New

Command Palette

A full-screen search overlay surfacing all navigation destinations. Triggered by ⌘K and dismissed by Escape or backdrop click.

Preview

Or press ⌘K anywhere

Keyboard shortcuts

KeyAction
⌘K / Ctrl+KOpen the palette (wire in consumer — not built in)
↑ / ↓Navigate through results
↵ EnterNavigate to the highlighted result
EscapeClose the palette
Click backdropClose the palette

Data source

Results are drawn from allSearchableItems exported by @/lib/navigation. This is a flat array derived from the full navigation tree with added section and group metadata.

To surface additional content (pages, actions, recent items), extend allSearchableItems or pass a custom items list to the component.

Motion

ElementEnterExit
Backdropopacity 0 → 1 (200ms ease)opacity 1 → 0 (150ms ease)
Panelopacity+scale(0.97)+y(−8px) → visible, spring(500,40)opacity+scale → hidden (150ms ease)

Implementation

CommandPaletteUsage.tsx
tsx
"use client";

import { useState, useEffect } from "react";
import { CommandPalette } from "@/site/search/CommandPalette";

export function AppShell({ children }: { children: React.ReactNode }) {
  const [open, setOpen] = useState(false);

  // ⌘K / Ctrl+K global shortcut
  useEffect(() => {
    const handler = (e: KeyboardEvent) => {
      if ((e.metaKey || e.ctrlKey) && e.key === "k") {
        e.preventDefault();
        setOpen((v) => !v);
      }
    };
    document.addEventListener("keydown", handler);
    return () => document.removeEventListener("keydown", handler);
  }, []);

  return (
    <>
      {children}
      <CommandPalette open={open} onClose={() => setOpen(false)} />
    </>
  );
}

Props

PropTypeDefaultDescription
open*booleanControls whether the palette is visible. Mount/unmount is handled internally via AnimatePresence.
onClose*() => voidCalled when the user presses Escape, clicks the backdrop, or activates a result.

ARIA roles

ElementRoleKey attributes
Containerdialogaria-modal='true', aria-label
Search inputcomboboxaria-expanded, aria-controls, aria-activedescendant
Results listlistboxaria-label
Result itemoptionaria-selected

Keyboard

KeyAction
⌘K / Ctrl+KOpen the command palette
Arrow Down / UpMove focus between results
EnterExecute the focused result
EscapeClose the command palette
TabCycle forward through results (same as Arrow Down)

Accessibility

  • Panel uses role="dialog" and aria-modal="true" to trap assistive technology focus.
  • Input auto-focuses on open so users can type immediately without tabbing.
  • Results list uses role="listbox"; highlighted item uses aria-selected.
  • Backdrop click and Escape both close the dialog consistently.
  • Keyboard navigation (↑↓ Enter Escape) is handled via document-level keydown listeners that are cleaned up on unmount.
  • ⌘K binding is implemented in the consumer, not in the component — giving teams flexibility to use a different shortcut.