Command
A command palette (⌘K) for quick search and actions. Supports keyboard navigation, grouped items, nested pages, and both data-driven and compound component patterns.
Import
Section titled “Import”import { Command } from 'asterui'Examples
Section titled “Examples”Basic Usage
Data-driven command palette with grouped items.
import { Command, Button } from 'asterui'
import { useState } from 'react'
function App() {
const [open, setOpen] = useState(false);
const items = [
{ key: 'new-file', label: 'Create New File', group: 'Actions' },
{ key: 'new-folder', label: 'Create New Folder', group: 'Actions' },
{ key: 'search', label: 'Search Files', group: 'Actions' },
{ key: 'home', label: 'Go to Home', group: 'Navigation' },
{ key: 'settings', label: 'Open Settings', group: 'Navigation' },
{ key: 'profile', label: 'View Profile', group: 'Navigation' },
];
return (
<>
<Button color="primary" onClick={() => setOpen(true)}>
Open Command Palette
</Button>
<Command
open={open}
onOpenChange={setOpen}
items={items}
placeholder="Type a command or search..."
/>
</>
)
}
export default App Compound Components
Build command palettes using compound components for more control.
import { Command, Button } from 'asterui'
import { useState } from 'react'
function App() {
const [open, setOpen] = useState(false);
return (
<>
<Button color="primary" onClick={() => setOpen(true)}>
Open Command Palette
</Button>
<Command open={open} onOpenChange={setOpen}>
<Command.List>
<Command.Empty>No results found</Command.Empty>
<Command.Group heading="Actions">
<Command.Item onSelect={() => alert('Creating file...')}>
Create New File
</Command.Item>
<Command.Item onSelect={() => alert('Creating folder...')}>
Create New Folder
</Command.Item>
</Command.Group>
<Command.Separator />
<Command.Group heading="Navigation">
<Command.Item onSelect={() => alert('Going home...')}>
Go to Home
</Command.Item>
<Command.Item onSelect={() => alert('Opening settings...')}>
Open Settings
</Command.Item>
</Command.Group>
</Command.List>
</Command>
</>
)
}
export default App With Icons
Add icons to command items for visual context.
import { Command, Button } from 'asterui'
import { useState } from 'react'
function App() {
const [open, setOpen] = useState(false);
const items = [
{ key: 'new-file', label: 'Create New File', group: 'Actions', icon: <FileIcon /> },
{ key: 'new-folder', label: 'Create New Folder', group: 'Actions', icon: <FolderIcon /> },
{ key: 'search', label: 'Search Files', group: 'Actions', icon: <SearchIcon /> },
{ key: 'home', label: 'Go to Home', group: 'Navigation', icon: <HomeIcon /> },
{ key: 'settings', label: 'Open Settings', group: 'Navigation', icon: <SettingsIcon /> },
];
return (
<>
<Button color="primary" onClick={() => setOpen(true)}>
Open Command Palette
</Button>
<Command
open={open}
onOpenChange={setOpen}
items={items}
placeholder="Type a command or search..."
/>
</>
)
}
export default App Search Keywords
Add extra keywords to make items findable by alternative terms.
import { Command, Button } from 'asterui'
import { useState } from 'react'
function App() {
const [open, setOpen] = useState(false);
const items = [
{
key: 'new-file',
label: 'Create New File',
group: 'Actions',
keywords: ['add', 'create', 'new', 'file', 'document']
},
{
key: 'search',
label: 'Search Files',
group: 'Actions',
keywords: ['find', 'lookup', 'query']
},
{
key: 'settings',
label: 'Open Settings',
group: 'Navigation',
keywords: ['preferences', 'config', 'options']
},
{
key: 'profile',
label: 'View Profile',
group: 'Navigation',
keywords: ['user', 'account', 'me']
},
];
return (
<>
<Button color="primary" onClick={() => setOpen(true)}>
Open (try searching "preferences")
</Button>
<Command
open={open}
onOpenChange={setOpen}
items={items}
placeholder="Try 'preferences' or 'config'..."
/>
</>
)
}
export default App Nested Pages
Navigate to sub-pages with back navigation support. Press Backspace (when search is empty) or click the back arrow to return.
import { Command, Button } from 'asterui'
import { useState } from 'react'
function App() {
const [open, setOpen] = useState(false);
return (
<>
<Button color="primary" onClick={() => setOpen(true)}>
Open Command Palette
</Button>
<Command open={open} onOpenChange={setOpen}>
<Command.List>
<Command.Empty>No results found</Command.Empty>
{/* Root page content */}
<Command.Group heading="Quick Actions">
<Command.Item onSelect={() => alert('Creating file...')}>
Create New File
</Command.Item>
<Command.Item onSelect={() => alert('Searching...')}>
Search Files
</Command.Item>
</Command.Group>
<Command.Separator />
<Command.Group heading="Navigate">
<Command.Item value="settings-menu">
Settings →
</Command.Item>
<Command.Item value="theme-menu">
Theme →
</Command.Item>
</Command.Group>
{/* Settings page */}
<Command.Page id="settings">
<Command.Group heading="Settings">
<Command.Item onSelect={() => alert('Opening account settings...')}>
Account
</Command.Item>
<Command.Item onSelect={() => alert('Opening privacy settings...')}>
Privacy
</Command.Item>
<Command.Item onSelect={() => alert('Opening notification settings...')}>
Notifications
</Command.Item>
</Command.Group>
</Command.Page>
{/* Theme page */}
<Command.Page id="theme">
<Command.Group heading="Choose Theme">
<Command.Item onSelect={() => alert('Theme set to Light')}>
Light
</Command.Item>
<Command.Item onSelect={() => alert('Theme set to Dark')}>
Dark
</Command.Item>
<Command.Item onSelect={() => alert('Theme set to System')}>
System
</Command.Item>
</Command.Group>
</Command.Page>
</Command.List>
</Command>
</>
)
}
export default App Disabled Items
Disable specific items to prevent selection.
import { Command, Button } from 'asterui'
import { useState } from 'react'
function App() {
const [open, setOpen] = useState(false);
const items = [
{ key: 'new-file', label: 'Create New File', group: 'Actions' },
{ key: 'new-folder', label: 'Create New Folder', group: 'Actions', disabled: true },
{ key: 'search', label: 'Search Files', group: 'Actions' },
{ key: 'delete', label: 'Delete Files', group: 'Danger', disabled: true },
];
return (
<>
<Button color="primary" onClick={() => setOpen(true)}>
Open Command Palette
</Button>
<Command
open={open}
onOpenChange={setOpen}
items={items}
placeholder="Some items are disabled..."
/>
</>
)
}
export default App Custom Shortcut
Change the global keyboard shortcut from ⌘K to another key.
import { Command, Button, Space } from 'asterui'
import { useState } from 'react'
function App() {
const [open1, setOpen1] = useState(false);
const [open2, setOpen2] = useState(false);
const items = [
{ key: 'action1', label: 'Action 1' },
{ key: 'action2', label: 'Action 2' },
];
return (
<>
<Space direction="horizontal" size="sm">
<Button onClick={() => setOpen1(true)}>
Default (⌘K)
</Button>
<Button onClick={() => setOpen2(true)}>
Custom (⌘J)
</Button>
</Space>
<Command
open={open1}
onOpenChange={setOpen1}
items={items}
placeholder="Default shortcut ⌘K..."
/>
<Command
open={open2}
onOpenChange={setOpen2}
items={items}
shortcut={['j']}
placeholder="Custom shortcut ⌘J..."
/>
</>
)
}
export default App Custom Filter
Provide a custom filter function for advanced matching logic.
import { Command, Button } from 'asterui'
import { useState } from 'react'
function App() {
const [open, setOpen] = useState(false);
const items = [
{ key: 'apple', label: 'Apple', keywords: ['fruit', 'red'] },
{ key: 'banana', label: 'Banana', keywords: ['fruit', 'yellow'] },
{ key: 'carrot', label: 'Carrot', keywords: ['vegetable', 'orange'] },
{ key: 'date', label: 'Date', keywords: ['fruit', 'brown'] },
];
// Custom filter that only matches from the start of words
const customFilter = (value: string, search: string, keywords?: string[]) => {
const searchLower = search.toLowerCase();
if (value.toLowerCase().startsWith(searchLower)) return true;
return (keywords || []).some(k => k.toLowerCase().startsWith(searchLower));
};
return (
<>
<Button color="primary" onClick={() => setOpen(true)}>
Open (prefix matching only)
</Button>
<Command
open={open}
onOpenChange={setOpen}
items={items}
filter={customFilter}
placeholder="Type 'fr' for fruits..."
/>
</>
)
}
export default App Command
Section titled “Command”| Property | Description | Type | Default |
|---|---|---|---|
open | Controlled open state | boolean | - |
onOpenChange | Callback when open state changes | (open: boolean) => void | - |
defaultOpen | Default open state (uncontrolled) | boolean | false |
items | Data-driven item configuration | CommandItemConfig[] | - |
filter | Custom filter function | (value: string, search: string, keywords?: string[]) => boolean | - |
loop | Loop keyboard navigation at edges | boolean | true |
shortcut | Global keyboard shortcut key(s) | string[] | ['k'] |
placeholder | Search input placeholder | string | 'Type a command or search...' |
emptyMessage | Message when no results found | ReactNode | 'No results found.' |
data-testid | Test ID for testing | string | - |
CommandItemConfig
Section titled “CommandItemConfig”When using the data-driven items prop:
| Property | Description | Type | Default |
|---|---|---|---|
key | Unique key for the item | string | - |
label | Display label | ReactNode | - |
group | Group name for categorization | string | - |
keywords | Additional search keywords | string[] | - |
disabled | Disable the item | boolean | false |
onSelect | Callback when item is selected | () => void | - |
icon | Icon element to display | ReactNode | - |
data-testid | Test ID for testing | string | - |
Compound Components
Section titled “Compound Components”For more control, use compound components:
| Component | Description |
|---|---|
Command.List | Container for groups and items |
Command.Group | Groups items with optional heading |
Command.Item | Selectable command item |
Command.Empty | Shown when no results match |
Command.Page | Nested page for navigation |
Command.Separator | Visual separator between sections |
Accessibility
Section titled “Accessibility”- Uses native
<dialog>element for focus trapping and ESC handling - Search input has
role="combobox"with proper ARIA attributes - List uses
role="listbox"withrole="option"items - Keyboard navigation with Arrow keys, Enter to select, Escape to close
aria-activedescendanttracks the highlighted item- Groups use
role="group"witharia-label
Keyboard Shortcuts
Section titled “Keyboard Shortcuts”⌘K/Ctrl+K- Open command palette (customizable)↑↓- Navigate itemsEnter- Select highlighted itemEscape- Close palette (or go back on nested page)Backspace- Go back to previous page (when search is empty)