Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
49 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
e371b21
Merge remote-tracking branch 'origin/main' into serhalp/cmdk-palette
ghostdevv Apr 4, 2026
05db2f4
fix: fix indirect merge conflicts
serhalp Apr 5, 2026
7881d2f
fix: revert all changes to accent color modules
serhalp Apr 5, 2026
52679c0
fix: use ButtonBase in mobile menu cmd palette item
serhalp Apr 5, 2026
69ecd87
test: use Response.json() in mock
serhalp Apr 5, 2026
ab1e8ae
refactor: use conventional casing for consts
serhalp Apr 5, 2026
da410ad
perf: extract Apple platform regex
serhalp Apr 5, 2026
58dce1c
refactor: use URL.parse()
serhalp Apr 5, 2026
93b73fb
chore: update i18n schema.json
serhalp Apr 5, 2026
abe97d8
test: fix test assertions
serhalp Apr 5, 2026
1e7a71f
Merge remote-tracking branch 'origin/main' into serhalp/cmdk-palette
serhalp Apr 5, 2026
02d0672
refactor: resolve oxlint warnings
serhalp Apr 5, 2026
d4afc5c
fix(i18n): fix bad merge that duplicated a key
serhalp Apr 5, 2026
7fe8390
Merge branch 'main' into serhalp/cmdk-palette
serhalp Apr 6, 2026
ace5136
fix(a11y): wait to copy to clipboard before announcing it
serhalp Apr 6, 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 @@ -146,6 +146,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 @@ -4,6 +4,8 @@ import type { NavigationConfig, NavigationConfigWithGroups } from '~/types'
import { NPMX_DOCS_SITE } from '#shared/utils/constants'

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

withDefaults(
defineProps<{
Expand Down Expand Up @@ -253,6 +255,24 @@ useShortcuts({
<!-- 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 @@ -288,7 +308,7 @@ useShortcuts({
</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