Overlays
Command
A searchable list of actions and destinations, used inline or as a cmd+K palette, with groups, shortcuts and a hint footer.
npx prodular-ui add commandPalette
Input, grouped results with shortcuts, and a footer with keyboard hints.
No resultsTry a customer name, an issue id like REL-482 or a setting.
Create issueC
Invite teammate
New document⌘⇧N
InboxG I
CustomersG C
Workspace settingsG S
NavigateOpenEscClose
import { ArrowDownIcon, ArrowUpIcon, CornerDownLeftIcon, FileTextIcon, InboxIcon, PlusIcon, SettingsIcon, UserPlusIcon, UsersIcon,} from "lucide-react"
import { Command, CommandEmpty, CommandFooter, CommandGroup, CommandInput, CommandItem, CommandList, CommandSeparator, CommandShortcut,} from "@/components/ui/command"import { Kbd } from "@/components/ui/kbd"
export default function CommandPalette() { return ( <Command className="w-full max-w-xl border shadow-lg"> <CommandInput placeholder="Search or run a command" /> <CommandList> <CommandEmpty> <span className="font-medium text-foreground">No results</span> <span>Try a customer name, an issue id like REL-482 or a setting.</span> </CommandEmpty> <CommandGroup heading="Actions"> <CommandItem> <PlusIcon /> Create issue <CommandShortcut>C</CommandShortcut> </CommandItem> <CommandItem> <UserPlusIcon /> Invite teammate </CommandItem> <CommandItem> <FileTextIcon /> New document <CommandShortcut>⌘⇧N</CommandShortcut> </CommandItem> </CommandGroup> <CommandSeparator /> <CommandGroup heading="Go to"> <CommandItem> <InboxIcon /> Inbox <CommandShortcut>G I</CommandShortcut> </CommandItem> <CommandItem> <UsersIcon /> Customers <CommandShortcut>G C</CommandShortcut> </CommandItem> <CommandItem> <SettingsIcon /> Workspace settings <CommandShortcut>G S</CommandShortcut> </CommandItem> </CommandGroup> </CommandList> <CommandFooter> <span className="flex items-center gap-1.5"> <Kbd> <ArrowUpIcon /> </Kbd> <Kbd> <ArrowDownIcon /> </Kbd> Navigate </span> <span className="flex items-center gap-1.5"> <Kbd> <CornerDownLeftIcon /> </Kbd> Open </span> <span className="ml-auto flex items-center gap-1.5"> <Kbd>Esc</Kbd> Close </span> </CommandFooter> </Command> )}Command dialog
Press the button or cmd+K. The dialog sits high on the screen, so results grow downward.
"use client"
import * as React from "react"import { ArrowRightIcon, CircleDotIcon, SearchIcon, UserIcon } from "lucide-react"
import { Button } from "@/components/ui/button"import { Command, CommandDialog, CommandEmpty, CommandFooter, CommandGroup, CommandInput, CommandItem, CommandList, CommandShortcut,} from "@/components/ui/command"import { Kbd, KbdGroup } from "@/components/ui/kbd"
const issues = [ { id: "REL-482", title: "Webhook retries stop after a deploy" }, { id: "REL-479", title: "Export to CSV drops custom fields" }, { id: "REL-470", title: "SLA timer ignores business hours" },]
const people = ["Priya Raman", "Tom Becker", "Ana Sousa"]
export default function CommandDialogDemo() { const [open, setOpen] = React.useState(false)
React.useEffect(() => { const onKeyDown = (e: KeyboardEvent) => { if (e.key === "k" && (e.metaKey || e.ctrlKey)) { e.preventDefault() setOpen((o) => !o) } } document.addEventListener("keydown", onKeyDown) return () => document.removeEventListener("keydown", onKeyDown) }, [])
return ( <> <Button variant="outline" className="w-64 justify-start text-muted-foreground" onClick={() => setOpen(true)}> <SearchIcon data-icon="inline-start" /> Search Relay <KbdGroup className="ml-auto"> <Kbd>⌘</Kbd> <Kbd>K</Kbd> </KbdGroup> </Button> <CommandDialog open={open} onOpenChange={setOpen}> <Command> <CommandInput placeholder="Search issues, people and pages" /> <CommandList> <CommandEmpty>No issues or people match that search.</CommandEmpty> <CommandGroup heading="Issues"> {issues.map((i) => ( <CommandItem key={i.id} value={`${i.id} ${i.title}`} onSelect={() => setOpen(false)}> <CircleDotIcon /> <span className="truncate">{i.title}</span> <CommandShortcut className="font-mono">{i.id}</CommandShortcut> </CommandItem> ))} </CommandGroup> <CommandGroup heading="People"> {people.map((p) => ( <CommandItem key={p} onSelect={() => setOpen(false)}> <UserIcon /> {p} </CommandItem> ))} </CommandGroup> <CommandGroup heading="Pages"> <CommandItem onSelect={() => setOpen(false)}> <ArrowRightIcon /> Billing settings </CommandItem> </CommandGroup> </CommandList> <CommandFooter> <span className="flex items-center gap-1.5"> <Kbd>↵</Kbd> Open </span> <span className="flex items-center gap-1.5"> <KbdGroup> <Kbd>⌘</Kbd> <Kbd>↵</Kbd> </KbdGroup> Open in new tab </span> <span className="ml-auto">Searching Halcyon</span> </CommandFooter> </Command> </CommandDialog> </> )}Anatomy
<CommandDialog open={open} onOpenChange={setOpen}> <Command> <CommandInput placeholder="Search or run a command" /> <CommandList> <CommandEmpty>No results.</CommandEmpty> <CommandGroup heading="Actions"> <CommandItem> <PlusIcon /> Create issue <CommandShortcut>C</CommandShortcut> </CommandItem> </CommandGroup> </CommandList> <CommandFooter>{/* keyboard hints */}</CommandFooter> </Command></CommandDialog>Guidance
Use it when
- Use as a global cmd+K palette for navigation and actions in apps with many pages.
- Use inline inside a Popover for searchable pickers with more than about ten options.
Avoid
- Short lists. Use Dropdown menu or Select.
- Free text search over content that needs filters and pagination. Build a search page.
Rules for AI agents
Published in llms-full.txt and the registry, so coding agents follow them when they build with this component.
- Inside CommandDialog, render a Command with CommandInput, CommandList and optionally CommandFooter.
- Always include CommandEmpty with a sentence that suggests what to search for.
- Group results with CommandGroup heading in sentence case: Actions, Go to, Recent.
- Set value on CommandItem when the visible label is not what people type, for example an issue id plus its title.
- Close the dialog in onSelect after running the action.
- Register the cmd+K and ctrl+K listener once at the app level, not per page.
API
CommandDialog
| Prop | Type | Default | Description |
|---|---|---|---|
| open / onOpenChange | boolean / (open: boolean) => void | Controlled state of the palette. | |
| title / description | string | "Command palette" | Screen reader title and description. |
CommandItem
| Prop | Type | Default | Description |
|---|---|---|---|
| value | string | Text used for filtering. Defaults to the item's text. | |
| onSelect | (value: string) => void | Runs on click or Enter. |
Command
| Prop | Type | Default | Description |
|---|---|---|---|
| shouldFilter | boolean | true | Set to false when you filter on the server. |