Fast, composable command menu with ranked fuzzy search, keyboard-first navigation, and smart result sorting.
Command
A command palette or search-driven menu that filters, ranks, and reorders items as the user types. It supports grouped items, keyboard shortcuts, vim-style bindings, pointer-free keyboard navigation, flexible ranking via keywords, and keeps the original authored DOM order when no search is active.
import { Command } from "@areia/slots" ;
document. querySelector ( "#root" ) ! .innerHTML = `
<div data-slot="command" data-label="Command Menu" class="win95-panel w-80 p-2">
<div data-slot="command-input-wrapper" class="mb-2">
<input
data-slot="command-input"
id="command-input"
placeholder="Search..."
class="win95-input w-full"
/>
</div>
<div data-slot="command-list" class="win95-inset p-3">
<div data-slot="command-empty" hidden class="px-3 py-1 text-neutral-600">
No results found.
</div>
<div data-slot="command-group">
<div data-slot="command-group-heading" class="win95-label">
Actions
</div>
<div
data-slot="command-item"
data-value="copy"
data-keywords="duplicate"
class="win95-menu-item"
>
Copy
<span
data-slot="command-shortcut"
class="float-right ml-8 text-neutral-700"
>
⌘C
</span>
</div>
<div
data-slot="command-item"
data-value="paste"
data-keywords="insert"
class="win95-menu-item"
>
Paste
<span
data-slot="command-shortcut"
class="float-right ml-8 text-neutral-700"
>
⌘V
</span>
</div>
</div>
<div data-slot="command-separator" class="win95-separator"></div>
<div data-slot="command-group">
<div data-slot="command-group-heading" class="win95-label">
Navigation
</div>
<div data-slot="command-item" data-value="home" class="win95-menu-item">
Home
<span
data-slot="command-shortcut"
class="float-right ml-8 text-neutral-700"
>
⌘H
</span>
</div>
<div
data-slot="command-item"
data-value="settings"
class="win95-menu-item"
>
Settings
<span
data-slot="command-shortcut"
class="float-right ml-8 text-neutral-700"
>
⌘,
</span>
</div>
</div>
<div data-slot="command-item" data-disabled class="win95-menu-item">
Disabled item
</div>
</div>
</div>
` ;
const root = document. querySelector ( '[data-slot="command"]' ) ! ;
const controller = Command. createCommand (root, {
label: "Command Menu" ,
loop: true ,
vimBindings: true ,
});
Import
import { Command } from "@areia/slots" ;
Usage
import { Command } from "@areia/slots" ;
// Auto-bind a single root
const root = document. querySelector ( '[data-slot="command"]' );
const controller = Command. createCommand (root, {
label: "Command Menu" ,
onValueChange : ( value ) => console. log ( "active item:" , value),
onSelect : ( value ) => console. log ( "selected:" , value),
});
// Auto-bind all unbound roots in scope
const controllers = Command. create ();
Expected Markup
The command expects a search input and a list of items. Items can be organized into groups with headings. Use data-value for deterministic item identification, data-keywords to boost ranking, data-disabled to disable items, and data-force-mount to keep filtered-out items in the DOM.
< label for = "command-input" >Actions</ label >
< div data-slot = "command" data-label = "Command Menu" >
< div data-slot = "command-input-wrapper" >
< input
data-slot = "command-input"
id = "command-input"
placeholder = "Search..."
/>
</ div >
< div data-slot = "command-list" >
< div data-slot = "command-empty" hidden >
No results found.
</ div >
< div data-slot = "command-group" >
< div data-slot = "command-group-heading" >Actions</ div >
< div
data-slot = "command-item"
data-value = "copy"
data-keywords = "duplicate"
>
Copy
< span data-slot = "command-shortcut" >⌘C</ span >
</ div >
< div
data-slot = "command-item"
data-value = "paste"
data-keywords = "insert"
>
Paste
< span data-slot = "command-shortcut" >⌘V</ span >
</ div >
</ div >
< div data-slot = "command-separator" ></ div >
< div data-slot = "command-group" >
< div data-slot = "command-group-heading" >Navigation</ div >
< div data-slot = "command-item" data-value = "home" >
Home
< span data-slot = "command-shortcut" >⌘H</ span >
</ div >
< div data-slot = "command-item" data-value = "settings" >
Settings
< span data-slot = "command-shortcut" >⌘,</ span >
</ div >
</ div >
< div data-slot = "command-item" data-disabled >
Disabled item
</ div >
</ div >
</ div >
Data Slots
Item Data Attributes
Generated Attributes
Events
Outbound
Inbound
API Reference
Options
Controller
Controller
The controller is returned by Command.createCommand() and provides imperative control over the command menu’s state.
const controller = Command. createCommand (root, {
label: "Command Menu" ,
});
// Set search query programmatically
controller. setSearch ( "copy" );
// Select an item programmatically
controller. select ( "paste" );
// Clear selection
controller. select ( null );
// Read current state
console. log (controller.value); // "paste" | null
console. log (controller.search); // "copy"
// Clean up
controller. destroy ();