Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
9983364
feat(ui): add command palette for quick navigation and actions
serhalp Mar 20, 2026
1036612
Merge remote-tracking branch 'origin/main' into serhalp/cmdk-palette
ghostdevv Mar 23, 2026
c9b5586
fix: address valid CodeRabbit feedback
serhalp Mar 24, 2026
651ba8a
refactor: avoid route type error
serhalp Mar 24, 2026
9c155a3
refactor: actually actually fix that route type
serhalp Mar 24, 2026
b515456
[autofix.ci] apply automated fixes
autofix-ci[bot] Mar 24, 2026
bfc524b
Merge remote-tracking branch 'origin/main' into serhalp/cmdk-palette
ghostdevv Mar 25, 2026
c9ad183
Merge branch 'main' into serhalp/cmdk-palette
serhalp Mar 27, 2026
e5a5ffd
fix: use trimmed query consistently
serhalp Mar 27, 2026
4354dcf
test(a11y): explicitly test for announcer existence
serhalp Mar 27, 2026
642d277
fix(a11y): remove unnecessary aria-labelledby
serhalp Mar 27, 2026
9271263
fix: don't change active command on hover
serhalp Mar 27, 2026
ae8e1b1
refactor: use pure CSS for active palette command styling
serhalp Mar 28, 2026
b4a6398
fix: add back the body.appendChild(a) in download util
serhalp Mar 28, 2026
19f242f
test: fix cmd palette a11y test
serhalp Mar 28, 2026
f10f375
Merge remote-tracking branch 'origin/main' into serhalp/cmdk-palette
serhalp Mar 29, 2026
7efb8c4
refactor: extract and use util to parse package name
serhalp Mar 29, 2026
5bb5e1c
fix: announce package tarball download from command palette
serhalp Mar 29, 2026
a7c1e09
refactor: avoid .then().finally()
serhalp Mar 29, 2026
218de39
fix(a11y): announce more command palette actions
serhalp Mar 29, 2026
3e2e8a5
fix: actually persist selected locale via cmd palette
serhalp Mar 29, 2026
3959303
fix: refactor away i18n key interpolation
serhalp Mar 29, 2026
13e6fab
fix: make "Search" nav item and "Search for query" separate
serhalp Mar 29, 2026
471200c
test: update test fetch mocks for new calls
serhalp Mar 29, 2026
e797864
fix: add missing id to keyboard shortcuts modal
serhalp Mar 29, 2026
e867eb1
fix: only show copy-markdown command when appropriate
serhalp Mar 29, 2026
2c67363
fix: align cmd palette items vertically
serhalp Mar 30, 2026
f70c603
fix: remove imports from onPrehydrate
serhalp Mar 30, 2026
e86c3b2
fix: actually restore the default accent color
serhalp Mar 31, 2026
2072386
test: update default accent color in tests
serhalp Mar 31, 2026
7fb4201
[autofix.ci] apply automated fixes
autofix-ci[bot] Mar 31, 2026
112db46
fix: simplify palette package versions loading a bit
serhalp Apr 1, 2026
8e868d4
fix: work around double scrollbar Safari bug πŸ™ƒ
serhalp Apr 1, 2026
68956c0
Merge remote-tracking branch 'origin/main' into serhalp/cmdk-palette
serhalp Apr 1, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ This focus helps guide our project decisions as a community and what we choose t
- [Naming conventions](#naming-conventions)
- [Vue components](#vue-components)
- [Internal linking](#internal-linking)
- [Command palette](#command-palette)
- [Cursor and navigation](#cursor-and-navigation)
- [RTL Support](#rtl-support)
- [Localization (i18n)](#localization-i18n)
Expand Down Expand Up @@ -400,6 +401,14 @@ For package links, use the auto-imported `packageRoute()` utility from `app/util
> [!IMPORTANT]
> Never construct package URLs as strings. The route structure uses separate `org` and `name` params, and `packageRoute()` handles the splitting correctly.

### Command palette

The command palette is a first-class navigation surface. When you add a new user-facing capability to the app, you should also register a corresponding command palette entry for it whenever that action or destination makes sense outside its immediate UI.

- Add global entries in the command palette composables.
- Add page- or component-scoped entries from the page/component that owns the capability.
- Prefer palette entries for actions users may reasonably want to trigger from the keyboard or jump to directly.

#### Available route names

| Route name | URL pattern | Parameters |
Expand Down
2 changes: 2 additions & 0 deletions app/app.vue
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,8 @@ if (import.meta.client) {
<NuxtPage />
</div>

<CommandPalette />

<AppFooter />

<ScrollToTop />
Expand Down
11 changes: 11 additions & 0 deletions app/components/AppFooter.vue
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ const route = useRoute()
const isHome = computed(() => route.name === 'index')

const discord = useDiscordLink()
const { commandPaletteShortcutLabel } = usePlatformModifierKey()
const modalRef = useTemplateRef('modalRef')
const showModal = () => modalRef.value?.showModal?.()
const closeModal = () => modalRef.value?.close?.()
Expand Down Expand Up @@ -51,14 +52,24 @@ const closeModal = () => modalRef.value?.close?.()
</button>

<Modal
id="keyboard-shortcuts-modal"
ref="modalRef"
:modalTitle="$t('footer.keyboard_shortcuts')"
class="w-auto max-w-lg"
>
<p class="mb-4 text-sm leading-relaxed text-fg-muted">
{{
$t('shortcuts.command_palette_description', { ctrlKey: $t('shortcuts.ctrl_key') })
}}
</p>
<p class="mb-2 font-mono text-fg-subtle">
{{ $t('shortcuts.section.global') }}
</p>
<ul class="mb-6 flex flex-col gap-2">
<li class="flex gap-2 items-center">
<kbd class="kbd">{{ commandPaletteShortcutLabel }}</kbd>
<span>{{ $t('shortcuts.command_palette') }}</span>
</li>
<li class="flex gap-2 items-center">
<kbd class="kbd">/</kbd>
<span>{{ $t('shortcuts.focus_search') }}</span>
Expand Down
22 changes: 21 additions & 1 deletion app/components/AppHeader.vue
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ import { NPMX_DOCS_SITE } from '#shared/utils/constants'

const keyboardShortcuts = useKeyboardShortcuts()
const discord = useDiscordLink()
const { open: openCommandPalette } = useCommandPalette()
const { commandPaletteShortcutLabel } = usePlatformModifierKey()

withDefaults(
defineProps<{
Expand Down Expand Up @@ -267,6 +269,24 @@ onKeyStroke(
<!-- Spacer when logo is hidden on desktop -->
<span v-else class="hidden sm:block w-1" />

<ButtonBase
type="button"
variant="secondary"
class="hidden lg:inline-flex shrink-0 gap-2 px-2.5 me-3"
:aria-label="$t('shortcuts.command_palette')"
:title="$t('shortcuts.command_palette_description', { ctrlKey: $t('shortcuts.ctrl_key') })"
@click="openCommandPalette"
>
<span>{{ $t('command_palette.quick_actions') }}</span>
<span class="inline-flex items-center gap-1 text-xs text-fg-subtle">
<kbd
class="inline-flex items-center justify-center rounded border border-border bg-bg-muted px-1.5 py-0.5 font-mono text-[0.7rem] text-fg-muted"
>
{{ commandPaletteShortcutLabel }}
</kbd>
</span>
</ButtonBase>

<!-- Center: Search bar + nav items -->
<div
class="flex-1 flex items-center md:gap-6"
Expand Down Expand Up @@ -302,7 +322,7 @@ onKeyStroke(
</div>

<!-- End: Desktop nav items + Mobile menu button -->
<div class="hidden sm:flex flex-shrink-0">
<div class="hidden sm:flex flex-shrink-0 items-center gap-2">
<!-- Desktop: Explore link -->
<LinkBase
v-for="link in desktopLinks"
Expand Down
Loading
Loading