components / 29

marked command

search should feel immediate, not invisible. every focused command carries a bright hand-drawn trace and every shortcut stays readable.

shadcnnpx shadcn@latest add berkantay/cheez/marked-command
live

find the next action

type or use arrow keys
⌘ k search without leaving
ink
character
value
<MarkedCommand
  items={actions}
  value={selected}
  onValueChange={setSelected}
  itemToStringLabel={(action) => action.label}
  tone="purple"
  character="rushed"
>
  <MarkedCommandInput />
  <MarkedCommandContent>
    <MarkedCommandEmpty>no command found.</MarkedCommandEmpty>
    <MarkedCommandList>
      {(action) => <MarkedCommandItem value={action}>{action.label}</MarkedCommandItem>}
    </MarkedCommandList>
  </MarkedCommandContent>
</MarkedCommand>
palette

open above the work

focus returns to the trigger on close
the command menu can stay inline or arrive as a focused palette.

the dialog owns focus and escape behavior. the command still owns search, highlighting, and selection.

structure

groups keep the scan quick

visible labels, searchable children
01create2 actions
02navigate2 actions
03appearance2 actions
states

silence is still a state

empty, loading, disabled
empty
loading
disabled
reference

api

Base UI mechanics, Cheez feedback
partproptypedefaultpurpose
RootitemsAction[] | Group[]filterable command collection
RootvalueAction | nullcontrolled chosen command
RootonValueChangefunctionrun or store a command
RootlabelReactNode"command menu"accessible search label
RoottoneMarkedCommandTone"purple"field and result ink
RootcharacterCheezCharacter"rushed"drawing pressure
Inputplaceholderstring"type a command…"search prompt
InputclearLabelstring"clear command search"clear-button name
Contentloadingbooleanfalseannounced search state
ItemdescriptionReactNodesecondary result copy
ItemiconReactNodedecorative leading symbol
ItemshortcutReactNodevisible keyboard hint
Separatorcolorstring"#ff4f2e"hand-cut group divider

behavior notes

  • the search field keeps a real combobox role and accessible label
  • Arrow Down and Arrow Up move focus, Enter chooses, and Escape closes
  • the selected result is surfaced through onValueChange, never hidden in context
  • groups and empty states stay part of the Base UI collection model
  • dialog focus trapping and restoration come from Base UI
  • the shortcut is a visual hint; application-level keyboard bindings remain yours
  • no Framer Motion is shipped