command-palette
Universal Cmd+K command palette with search, keyboard navigation, and grouped actions.
Description
The <command-palette> component provides a universal Cmd+K search and action launcher. It opens as a modal dialog with a search input that filters through grouped commands. Different from <site-search> (which is Pagefind site search) — this is for user-defined commands and actions.
Basic Usage
<command-palette hotkey="meta+k"> <command-group label="Navigation"> <command-item value="home" data-hotkey="meta+h"> Go Home </command-item> <command-item value="settings"> Settings </command-item> </command-group> <command-group label="Actions"> <command-item value="theme">Toggle Dark Mode</command-item> <command-item value="copy">Copy Current URL</command-item> </command-group></command-palette>
Attributes
| Attribute | On | Description |
|---|---|---|
hotkey |
command-palette |
Global keyboard shortcut (default: meta+k) |
placeholder |
command-palette |
Search input placeholder text |
discover |
command-palette |
Auto-populate from [data-command] elements on the page |
label |
command-group |
Group header text |
value |
command-item |
Value passed in command-palette:select event |
data-hotkey |
command-item |
Display keyboard shortcut badge on item |
With Icons
Use slot="icon" on icon elements inside <command-item>:
<command-palette hotkey="meta+k"> <command-group label="Navigation"> <command-item value="home"> <icon-wc name="home" slot="icon"></icon-wc> Go Home </command-item> <command-item value="settings"> <icon-wc name="cog" slot="icon"></icon-wc> Settings </command-item> </command-group></command-palette>
Trigger Button
You can add a visual trigger button that opens the palette:
<!-- Trigger button --><button onclick="document.querySelector('command-palette').open()"> Search commands... <kbd>⌘K</kbd></button>
Auto-Discovery (discover)
Add discover to <command-palette> to auto-populate the palette with [data-command] elements from the page. Any button, link, or element with data-command becomes searchable. If it also has data-shortcut, the shortcut is displayed and bound as a real keyboard shortcut. Selecting a discovered command in the palette clicks the original element.
<!-- Command palette with auto-discovery --><command-palette hotkey="meta+k" discover> <command-group label="Navigation"> <command-item value="home">Go Home</command-item> </command-group> <!-- [data-command] elements auto-populate as additional groups --></command-palette> <!-- Anywhere on the page: these appear in the palette --><button data-command="Toggle Dark Mode" data-shortcut="meta+shift+t"> Dark Mode</button><a href="/docs" data-command="Documentation" data-command-group="Navigation"> Docs</a>
data-command Attributes
| Attribute | Description |
|---|---|
data-command |
Label in the palette (required to opt in) |
data-command-group |
Group name (default: "Page Actions") |
data-command-icon |
Icon name for <icon-wc> in palette |
data-shortcut |
Keyboard shortcut — displayed AND bound globally |
<!-- data-command attributes --><button data-command="Save Draft" data-shortcut="meta+s" data-command-icon="save"> Save</button> <!-- Attribute reference --><!-- data-command = Label in the palette (required) --><!-- data-command-group = Group name (default: "Page Actions") --><!-- data-command-icon = Icon name for icon-wc (optional) --><!-- data-shortcut = Keyboard shortcut (displayed + bound) -->
Elements with commandfor (HTML Invoker API) are also auto-discovered. The label comes from textContent; override with data-command if needed.
Aggressive Auto-Discovery (discover="auto")
Set discover="auto" to also scan for nav links and page headings without any explicit data-command attributes:
| Source | Palette label | Group |
|---|---|---|
nav a[href] links |
Link text | "Navigation" |
Headings with id (h2[id], h3[id]) |
"Jump to: { heading text }" | "On This Page" |
[data-command] elements |
data-command value |
data-command-group or "Page Actions" |
<!-- Aggressive auto-discovery: also scans nav links + headings --><command-palette hotkey="meta+k" discover="auto"> <command-group label="Quick Actions"> <command-item value="theme">Toggle Dark Mode</command-item> </command-group></command-palette> <!-- These are found automatically (no data-command needed): --><!-- nav links → "Navigation" group --><!-- h2[id], h3[id] → "On This Page" group -->
Auto-discovered items are capped at 50 and styled with muted text. Elements inside footer, aside, dialog, [hidden], or [aria-hidden="true"] are excluded. Clicking a heading command scrolls to it smoothly.
Keyboard Navigation
| Key | Action |
|---|---|
| Cmd+K / Ctrl+K | Open/close palette |
| Arrow Down | Move to next item |
| Arrow Up | Move to previous item |
| Enter | Select active item |
| Escape | Close palette |
JavaScript API
Methods
| Method | Description |
|---|---|
open() |
Open the command palette |
close() |
Close the command palette |
Events
| Event | Description |
|---|---|
command-palette:select |
Fired when an item is selected (detail.value) |
command-palette:open |
Fired when palette opens |
command-palette:close |
Fired when palette closes |
const palette = document.querySelector('command-palette'); // Open programmaticallypalette.open(); // Listen for selectionpalette.addEventListener('command-palette:select', (e) => { console.log('Selected:', e.detail.value); switch (e.detail.value) { case 'theme': document.documentElement.toggleAttribute('data-dark'); break; case 'home': window.location.href = '/'; break; }});
Accessibility
- Opens as native
<dialog>with focus trapping - Search input focused on open
- Full keyboard navigation (Arrow keys, Enter, Escape)
- Items have
role="option"within arole="listbox" - Active item scrolls into view
- Platform-aware keyboard shortcut display (⌘ on Mac, Ctrl on others)