Command
A command palette provides a searchable list of actions or items. Users type into a search input to filter and select commands via keyboard or mouse. This pattern is commonly used for quick-access command palettes (e.g., Ctrl+K interfaces), searchable menus, and action launchers.
The component renders a search region containing a text input and a listbox for results. The search value is bindable, allowing consumers to implement their own filtering logic and dynamically update the listbox content.
Example
Show demo markup
<div class="command" role="dialog" aria-label="Command palette"><input type="search" aria-label="Search commands" placeholder="Type a command..." /><ul role="listbox" aria-label="Commands"><li role="option" aria-selected="false">Open file</li><li role="option" aria-selected="false">Save</li></ul></div>
Usage example
<script lang="ts">
import Command from "./Command.svelte";
let q = $state("");
const commands = [
{ id: "new", name: "New file" },
{ id: "open", name: "Open file" },
{ id: "save", name: "Save" }
];
let filtered = $derived(
commands.filter((c) => c.name.toLowerCase().includes(q.toLowerCase()))
);
</script>
<Command label="Command palette" placeholder="Search commands..." bind:value={q}>
{#each filtered as c (c.id)}
<div role="option" tabindex="-1">{c.name}</div>
{/each}
</Command>
Show Svelte source
// In your Svelte component:
import Command from "lily-design-system-svelte-headless/components/Command/Command.svelte";
<Command>
<!-- content -->
</Command>
Usage
Application command palette triggered by Ctrl+K:
<Command label="Command palette" placeholder="Type a command..." value={query}>
<div role="option" tabindex="-1" onclick={() => navigate('/dashboard')}>Go to Dashboard</div>
<div role="option" tabindex="-1" onclick={() => navigate('/settings')}>Open Settings</div>
<div role="option" tabindex="-1" onclick={() => toggleTheme()}>Toggle Dark Mode</div>
</Command>
Admin panel action launcher with dynamic filtering:
<Command label="Actions" placeholder="Search actions..." value={actionQuery}>
{#each filteredActions as action}
<div role="option" tabindex="-1" onclick={() => action.execute()}>
{action.name} <kbd>{action.shortcut}</kbd>
</div>
{/each}
</Command>
Props
label: string (required) -- accessible name for both the search region and the input
placeholder: string (default: undefined) -- placeholder text for the search input
value: string (default: "", bindable) -- current search text, supports two-way binding via two-way value binding
children: slot (required) -- listbox content, typically option or command items
...restProps: any additional HTML attributes spread onto the outer <div>
Keyboard Interactions
- Tab: Moves focus into and out of the search input
- Additional keyboard navigation (arrow keys within the listbox) should be implemented by the consumer
ARIA
role="search" -- identifies the outer container as a search landmark region
aria-label={label} -- provides accessible name for the search region and input
role="listbox" -- identifies the results container as a listbox for selectable options
aria-label={label} -- provides accessible name for the listbox
When to Use
- Use Command for quick-access search interfaces such as Ctrl+K action launchers or searchable menus.
- Use Command when users need to search and execute actions from a large set without navigating through menus.
- Use Command for keyboard-driven navigation where users can jump to pages, run actions, or switch contexts.
- Use Command in developer tools, admin panels, or productivity applications where power users expect a command palette.
When Not to Use
- Do not use Command for site search or content search -- use SearchInput instead.
- Do not use Command for form input with a dropdown list of options -- use Combobox instead.
- Do not use Command for navigation menus that should always be visible -- use NavigationMenu instead.
Headless
This headless Command component provides a <div> with role="search" and aria-label, an <input type="search"> with autocomplete="off", and a <div> with role="listbox" for displaying results. The consumer provides all visual styling including modal/overlay presentation, result item layout, keyboard shortcut hints, grouping headers, and animations.
Styles
The consumer provides all CSS styling. The component renders with a .command class for targeting. No default styles are included — this is a fully headless component.
Testing
- Verify the component renders a
<div> element with class command
- Verify role="search"` -- identifies the outer container as a search landmark region
- Verify aria-label={label}` -- provides accessible name for the search region and input
- Verify role="listbox"` -- identifies the results container as a listbox for selectable options
- Verify aria-label={label}` -- provides accessible name for the listbox
- Verify keyboard interactions work correctly
- Verify pass-through attributes are applied
Advice
- Designers: Present the command palette in a modal overlay centered on screen. Group related commands and show keyboard shortcut hints alongside each action.
- Developers: Implement filtering logic by reacting to the bindable
value prop. Add arrow key navigation for the listbox items in your consumer code. Pair with a Dialog for modal presentation.
Implementation Notes
- Wraps content in a
<div> with role="search" and aria-label for semantic search region
- Contains an
<input type="search"> with autocomplete="off" to prevent browser autocomplete interference
- Contains a
<div> with role="listbox" for displaying filtered results
- Supports two-way binding on the
value prop component
- Children slot is rendered inside the listbox for consumer-controlled list items
- Spreads
restProps on the outer search container
Related components
combobox — a text input combined with a dropdown list for filtering options
menu — a list of actions or options triggered by a button
search-input — an input for entering a search query <input type="search">
References
- WAI-ARIA Listbox Pattern: https://www.w3.org/WAI/ARIA/apg/patterns/listbox/
- WAI-ARIA Combobox Pattern: https://www.w3.org/WAI/ARIA/apg/patterns/combobox/
Canonical contract
Generated from this component's canonical metadata — the machine-checked source the implementations are held to.
Metadata
- Component: command
- PascalCase: Command
- Description: a command palette for searching and executing actions
- Status: beta — implemented and unit-tested in all seven frameworks with an axe-clean demo page; not yet exercised in composed flows
- HTML tag: <div>
- CSS class: .command
- Interactive: yes
ARIA
role="search" -- identifies the outer container as a search landmark region aria-label={label} -- provides accessible name for the search region and input role="listbox" -- identifies the results container as a listbox for selectable options aria-label={label} -- provides accessible name for the listbox
Keyboard
- **Tab**: Moves focus into and out of the search input
- Additional keyboard navigation (arrow keys within the listbox) should be implemented by the consumer
Props
label: string (required) -- accessible name for both the search region and the input placeholder: string (default: undefined) -- placeholder text for the search input value: string (default: "", bindable) -- current search text, supports two-way binding via two-way value binding children: slot (required) -- listbox content, typically option or command items ...restProps: any additional HTML attributes spread onto the outer <div>