SvCommand

A Cmd+K command palette: a fuzzy-searchable list of actions in a centered, focus-trapped dialog, with an optional global hotkey.

SvCommand is the keyboard-driven launcher that power users expect. It filters a flat list of commands with a fuzzy matcher, groups them under headers, shows per-command shortcut hints, and runs the chosen action. It is built on the shared a11y primitives (portal, focus trap, scroll lock, dismissable layer) and emits WAI-ARIA combobox markup with aria-activedescendant. By default it binds Cmd/Ctrl+K to toggle itself, so you can mount it once at the app root.

Basic usage

<script lang="ts">
  import { SvCommand, type CommandItem } from '@svgrid/grid'
  const commands: CommandItem[] = [
    { id: 'new', label: 'New record', group: 'Actions', shortcut: '⌘N', onRun: create },
    { id: 'export', label: 'Export CSV', group: 'Actions', onRun: exportCsv },
  ]
</script>

<SvCommand {commands} onRun={(c) => track(c.id)} />  <!-- Cmd/Ctrl+K opens it -->

Props

Prop Type Default Description
open boolean false Whether the palette is shown (bindable).
onClose () => void - Fires when the palette closes.
commands ReadonlyArray<CommandItem> - The actions to search and run.
onRun (cmd: CommandItem) => void - Fires when a command is chosen (before its own onRun).
placeholder string Type a command or search… Search-input placeholder.
emptyText string No results Shown when nothing matches.
hotkey mod+k | mod+p | false mod+k Global toggle hotkey; false disables it.

CommandItem (exported): { id, label, hint?, group?, icon?, shortcut?, keywords?, disabled?, onRun? }. group becomes a section header, hint is a right-aligned description, shortcut shows a key hint, keywords adds extra searchable terms, and each item's own onRun fires when it is chosen.

Patterns

Grouping and shortcuts

Give commands a group and a shortcut; groups render as headers when the query is empty, and shortcuts show on the right:

const commands = [
  { id: 'save', label: 'Save', group: 'File', shortcut: '⌘S', onRun: save },
  { id: 'open', label: 'Open…', group: 'File', shortcut: '⌘O', onRun: open },
]

Controlled open state

Bind open to drive the palette from a toolbar button as well as the hotkey:

<SvButton onclick={() => (paletteOpen = true)}>Commands</SvButton>
<SvCommand bind:open={paletteOpen} {commands} />

Extra search terms

Add keywords so a command surfaces under words that are not in its label:

{ id: 'theme', label: 'Toggle dark mode', keywords: 'appearance color scheme', onRun: toggle }

A palette wired to real actions

Mount SvCommand once at the app root and Cmd/Ctrl+K opens it anywhere. Mix navigation and actions, group them, add keywords for terms not in the label, and gate admin-only entries with disabled:

<script lang="ts">
  import { SvCommand, type CommandItem } from '@svgrid/grid'
  import { goto } from '$app/navigation'

  let theme = $state<'light' | 'dark'>('light')

  const commands: CommandItem[] = [
    { id: 'go-dashboard', label: 'Go to Dashboard', group: 'Navigate', icon: '📊', onRun: () => goto('/') },
    { id: 'go-orders', label: 'Go to Orders', group: 'Navigate', keywords: 'sales invoices', onRun: () => goto('/orders') },
    { id: 'new', label: 'New order', group: 'Actions', shortcut: '⌘N', onRun: createOrder },
    { id: 'theme', label: 'Toggle dark mode', group: 'Actions', keywords: 'appearance color scheme',
      onRun: () => (theme = theme === 'dark' ? 'light' : 'dark') },
    { id: 'billing', label: 'Open billing', group: 'Actions', hint: 'Admins only', disabled: !isAdmin,
      onRun: () => goto('/billing') },
  ]
</script>

<SvCommand {commands} onRun={(c) => analytics.track('command', c.id)} />

Tip: the top-level onRun prop fires first, then the chosen command's own onRun - so use the prop for cross-cutting concerns (analytics, closing a menu) and each item's onRun for its actual action. disabled commands are filtered out of the results entirely, so they never surface in search.

Accessibility

See also