Marble UI
← Components

Command Palette

Preview: Default

⌘K command menu: a modal with a search field that filters a keyboard-navigable menu (React Aria Autocomplete + Menu, so arrow keys work while typing).

Import

import { CommandPalette, CommandGroup, CommandItem } from '@marbleui/ui'

Props

<CommandPalette>

PropTypeDefaultDescription
children *requiredReactNode—
isOpen *requiredboolean—
onOpenChange *required(open: boolean) => void—
footerReactNode—
placeholderstring'Type a command or search…'
shortcutstring'k'Global shortcut that opens the palette (mod = ⌘ on Mac, Ctrl elsewhere).

<CommandGroup>

PropTypeDefaultDescription
children *requiredReactNode—
title *requiredstring—

<CommandItem>

PropTypeDefaultDescription
descriptionstring—
iconReactNode—
shortcutstring—

Also accepts React Aria props (100).

Accessibility

Keyboard interaction, focus management and ARIA semantics come from the underlying primitives: React Aria Autocomplete · React Aria Dialog · React Aria Header · React Aria Input · React Aria Menu · React Aria MenuItem · React Aria MenuSection · React Aria Modal · React Aria ModalOverlay · React Aria SearchField. Follow the primitive's docs for the full keyboard map.

Usage notes

⌘K command menu: a modal search that filters a keyboard-navigable list of actions. Arrow keys work while typing.

const [open, setOpen] = useState(false)
<CommandPalette isOpen={open} onOpenChange={setOpen}>
  <CommandGroup title="Navigation">
    <CommandItem id="issues" onAction={() => go('/issues')}>Go to issues</CommandItem>
  </CommandGroup>
</CommandPalette>
  • shortcut sets the letter for the global ⌘/Ctrl shortcut (default k). You own isOpen, so you can also open it from a button.
  • Give items textValue when their children aren’t plain text, so filtering and typeahead work.
Example source · show
import { useState } from 'react'
import { Button } from '../button'
import { Kbd } from '../kbd'
import { CommandGroup, CommandItem, CommandPalette } from './command-palette'

const I = ({ d }: { d: string }) => (
  <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" aria-hidden><path d={d} /></svg>
)

function Demo() {
  const [open, setOpen] = useState(false)
  const [last, setLast] = useState<string | null>(null)
  return (
    <div className="flex flex-col items-center gap-3">
      <Button variant="outline" onPress={() => setOpen(true)}>
        Search commands <Kbd variant="soft" className="ml-2">⌘K</Kbd>
      </Button>
      {last && <span className="text-sm text-fg-muted">Ran: {last}</span>}
      <CommandPalette isOpen={open} onOpenChange={setOpen}>
        <CommandGroup title="Suggestions">
          <CommandItem id="new-issue" onAction={() => setLast('New issue')} icon={<I d="M12 5v14M5 12h14" />} shortcut="C">New issue</CommandItem>
          <CommandItem id="search-docs" onAction={() => setLast('Search docs')} icon={<I d="M4 19.5A2.5 2.5 0 0 1 6.5 17H20V2H6.5A2.5 2.5 0 0 0 4 4.5zM20 22H6.5a2.5 2.5 0 0 1 0-5" />} description="Guides and API reference">Search docs</CommandItem>
        </CommandGroup>
        <CommandGroup title="Navigation">
          <CommandItem id="inbox" onAction={() => setLast('Go to inbox')} icon={<I d="M22 12h-6l-2 3h-4l-2-3H2" />} shortcut="G I">Go to inbox</CommandItem>
          <CommandItem id="projects" onAction={() => setLast('Go to projects')} icon={<I d="M3 7h18M3 12h18M3 17h18" />} shortcut="G P">Go to projects</CommandItem>
          <CommandItem id="settings" onAction={() => setLast('Open settings')} icon={<I d="M12 15a3 3 0 1 0 0-6 3 3 0 0 0 0 6" />} shortcut="⌘,">Open settings</CommandItem>
        </CommandGroup>
        <CommandGroup title="Theme">
          <CommandItem id="light" onAction={() => setLast('Light theme')} icon={<I d="M12 17a5 5 0 1 0 0-10 5 5 0 0 0 0 10" />}>Switch to light</CommandItem>
          <CommandItem id="dark" onAction={() => setLast('Dark theme')} icon={<I d="M21 12.8A9 9 0 1 1 11.2 3a7 7 0 0 0 9.8 9.8" />}>Switch to dark</CommandItem>
        </CommandGroup>
      </CommandPalette>
    </div>
  )
}

export const styles = { Default: Demo }

Source: packages/ui/src/command-palette/command-palette.tsx

Catalog

Category
overlays
Priority
Pro
Primitive
composed
React Aria
Autocomplete + Menu + Modal