feat(nav): command palette (Cmd+K) — global navigation + search (#88)#100
Merged
Conversation
Adds a global command palette that replaces the planned 6-section top nav from #20. Pressing Cmd+K / Ctrl+K opens a centered modal that lists the 5 app routes, fuzzy-filters them as the user types, and merges in FTS5 content results from /api/search after a 300ms idle. The minimal top nav now exposes a search-input-styled trigger (desktop) and a magnifying-glass icon (mobile) that both open the palette. A sign-out utility item is also listed. Two-stage Esc (first Esc blurs the input, second Esc closes the dialog) follows the design spec's standard pattern. FTS5 snippets are rendered with React nodes (no dangerouslySetInnerHTML) so user-imported HTML in notes cannot inject markup. The 4 not-yet-built routes (chat, graph, tags, settings) get minimal "coming soon" placeholders so the navigation graph promised by the palette is intact.
…aph item The dialog's search input was rendering much narrower than the list rows below it. The shadcn CommandInput wrapper adds an extra `p-1` div and renders its own SearchIcon, which combined with the inline Esc kbd squeezed the placeholder until the label truncated. Switched to cmdk's Command.Input directly and dropped the redundant inline Esc (the footer already documents it). Also drops the literal "(placeholder)" suffix from the Graph item description — leftover stub language from when the route itself was a placeholder.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Implements #88.
What
Adds a global command palette that replaces the planned 6-section top nav from #20. Pressing
Cmd+K(macOS) orCtrl+K(Windows/Linux) opens a centered modal that:/api/search?q=…&limit=8once the query is ≥ 2 chars, rendering hits in a Content group with the FTS5<mark>snippetsThe minimal top nav now exposes a search-input-styled trigger on desktop and a magnifying-glass icon on mobile — both open the same palette. A single
CommandPaletteRoot(provider + dialog) is mounted in the root layout so the globalCmd+Klistener and the trigger share state.Behavior
↑/↓move selection,Enteractivates, two-stageEsc(first blurs the input, second closes the dialog) per the spec's "standard pattern".dangerouslySetInnerHTML), so user-imported<script>/&in notes is escaped, not executed.Routes
The 4 not-yet-built routes (
/chat,/graph,/tags,/settings) get minimal "coming soon" placeholders so all 5 routes promised by the palette's default view are reachable.Tests
55 new tests across the new files:
fuzzy-filter.test.ts(13) — subsequence matching, prefix preference, consecutive bonus, length tie-breaker, empty querycommand-items.test.ts(7) — the 5 routes, stable IDs,/searchexcluded, search haystack projectionsnippet.test.tsx(10) —<mark>rendering, XSS escape, unterminated-mark fallback, type-token mappinguse-command-palette.test.tsx(10) —Cmd+K/Ctrl+K, toggle, focus-doesn't-block-shortcut, modifier guards, listener cleanupcommand-palette.test.tsx(15) — trigger open, Cmd+K open, default view, fuzzy filter, FTS5 debounce + render, empty results, snippet XSS, navigation on Enter, sign-out form, two-stage Esc, abort on keep-typingChore
0.5.2 → 0.6.0(new user-facing feature: keyboard-driven global navigation + global content search).jsdom,@testing-library/react,@testing-library/jest-dom,@testing-library/user-event) needed for client-component tests.dialog+command(cmdk) + their transitive components viapnpm exec shadcn add dialog command.src/components/ui/**and the new root component.pnpm verifyis green: lint (incl.react-hooks/set-state-in-effect), typecheck, build, 595 tests, knip.