Command Palette
A ⌘K command palette with fuzzy search and keyboard navigation, reusing the modal behavior primitive — zero extra runtime.
Real use · ⌘K launcher (try the hotkey too)
Using Command Palette
Silica ships one design system through three paths. They share a class vocabulary but are not interchangeable — pick the one that matches what you are building.
Plain HTML — CSS classes
The Tailwind v4 plugin. Works in any framework or none — Rails, Django, PHP, Go, a static file. This path ships no JavaScript, so Command Palette is styled but inert: its behavior comes from modal. For that behavior with no framework, use the node-tree path below.
/* in your CSS */
@import "tailwindcss";
@plugin "@wizeworks/silicaui";Root class command-palette-backdrop, with 14 modifiers:
.command-palette-backdrop.command-palette-empty.command-palette-group.command-palette-group-label.command-palette-input.command-palette-item.command-palette-item-body.command-palette-item-desc.command-palette-item-icon.command-palette-item-label.command-palette-item-shortcut.command-palette-list.command-palette-popup.command-palette-search.command-palette-search-icon
React
Typed components over those same classes, with behavior and accessibility from Base UI.
npm i @wizeworks/silicaui-reactimport { CommandPalette } from "@wizeworks/silicaui-react";Props
| Prop | Type | Required | Description |
|---|---|---|---|
| items | CommandItem[] | yes | The commands to show and filter. |
| open | boolean | no | Controlled open state. |
| defaultOpen | boolean | no | Uncontrolled initial open state. |
| onOpenChange | (open: boolean) => void | no | — |
| placeholder | string | no | Search box placeholder. |
| emptyMessage | string | no | Shown when nothing matches. |
| hotkey | boolean | string | no | Global toggle hotkey. true (default) binds ⌘K / Ctrl+K; pass a single letter to rebind (still combined with ⌘/Ctrl); false disables it. |
| className | string | no | — |
Source of the demo above
The exact file that renders the examples above, so it can never drift from them. It imports a few of this site’s own layout helpers (../lib/…), so read it for the component calls rather than copying it whole.
Show source
import { useState } from "react";
import { CommandPalette, Button } from "@wizeworks/silicaui-react";
import type { CommandItem } from "@wizeworks/silicaui-react";
import { Section, Row } from "../lib/Section";
export function CommandPaletteDemo() {
const [open, setOpen] = useState(false);
const [lastCommand, setLastCommand] = useState<string | null>(null);
const items: CommandItem[] = [
{
id: "new-page",
label: "Create new page",
description: "Add a blank page to this site",
group: "Actions",
shortcut: "⌘N",
onSelect: () => setLastCommand("Create new page"),
},
{
id: "invite",
label: "Invite teammate",
group: "Actions",
keywords: ["member", "user", "collaborator"],
onSelect: () => setLastCommand("Invite teammate"),
},
{
id: "theme-light",
label: "Switch to light theme",
group: "Preferences",
onSelect: () => setLastCommand("Switch to light theme"),
},
{
id: "theme-dark",
label: "Switch to dark theme",
group: "Preferences",
onSelect: () => setLastCommand("Switch to dark theme"),
},
{
id: "billing",
label: "Open billing settings",
group: "Preferences",
disabled: true,
onSelect: () => setLastCommand("Open billing settings"),
},
];
return (
<Section title="Real use · ⌘K launcher (try the hotkey too)">
<Row>
<Button color="primary" onClick={() => setOpen(true)}>
Open command palette
</Button>
{lastCommand && (
<span className="text-sm opacity-70">Ran: {lastCommand}</span>
)}
</Row>
<CommandPalette items={items} open={open} onOpenChange={setOpen} />
</Section>
);
}Vanilla — node tree to HTML
CommandPalette — params.hotkey binds ⌘K/Ctrl+K globally (default true; props.hotkey === false disables it). Input/Item reuse the search/item parts modal.ts optionally wires filter+arrow-nav for. Build a node tree, project it with toHtml(), and let the zero-dependency runtime hydrate it. This is the path for generated or user-authored documents — a site builder, CMS output, a static export.
npm i @wizeworks/silicaui-html @wizeworks/silicaui-behaviorsimport { atom, toHtml } from "@wizeworks/silicaui-html";
const node = atom("CommandPalette", "command-palette-backdrop", { /* props */ }, [/* children */]);
const markup = toHtml(node);Styling on this path is the class string in the second argument — the same classes as the Plain HTML section above. There is no color prop here; write "command-palette-backdrop command-palette-backdrop-primary" rather than passing a colour as a prop.
- Takes children
- yes
- Hydrated by
modal
Load @wizeworks/silicaui-behaviors on the page or this markup renders correctly and does nothing.
The full API for Command Palette, on every path, is available through the Silica MCP server.