Command
Overview
Fast, composable, command menu for Vue. SCommand is a searchable command palette built on the Aria listbox primitives with Fuse fuzzy matching. It delegates filtering, grouped item aggregation, and default item composition to the Aria CommandCompact; the UI wrapper only injects styles.
Use a command for a ⌘K-style palette, searchable menus, or inline typeahead. For a plain action menu use dropdown-menu; for a compact single-select list use select.
Usage
SCommandnow delegates filtering, grouped item aggregation, and default item composition to AriaCommandCompact. For unstyled, data-driven usage, importCommandCompactfrom@vean/aria/command.
Features
- 🔎 Fuzzy search — Fuse-powered matching over
label/groupLabel/descriptionwith configurablefuseOptions(threshold,resultLimit, match-all-on-empty) - 🧩 Aria/styled split —
CommandCompactowns filtering, grouping and item composition;SCommandonly injects styles - 📊 Grouped data —
itemswith nested groupitems(label/value/icon/description/disabled/separator) and flat items - 🔍 Item descriptions —
descriptionrenders as a secondary line under the label and is searchable by the built-in filter - 🚀 External filtering —
external-filterbypasses the built-in fuzzy filter so items can be filtered and ranked by an external engine (e.g. full-text content search) - ⌨️ Keyboard nav — full listbox roving focus (arrow keys), selection and
highlight/selectevents - 🏷️ Icons + shortcuts —
iconper item andshortcutrendered as aKbd - 🧹 Clearable —
clearableshows a trailing clear control;placeholder/emptyLabellocalize the empty state - 🔒 Disabled —
disableddisables the input and blocks selection - ♿ Accessible —
role="listbox"/option,aria-labeld list, labelled input,axe-coreclean
Component family
SCommand(styled) — the entry wrapper;commandVariantsrecipe with dynamic slot forwardingCommandCompact(Aria) — the aggregated composite; owns search, grouping, filtering and default item compositionListboxRoot/ListboxFilter/ListboxContent/ListboxGroup/ListboxGroupLabel/ListboxItem(Aria) — the underlying listbox primitivesKbd(Aria) — renders itemshortcuts
Demos
Basic
Dialog
API
Aria Layer
8Command<T>
Props
| Prop | Type | Default | Description |
|---|---|---|---|
class | ClassValue | — | Root class. |
size | ThemeSize | — | Visual size of the component. |
ui | Partial<CommandUi> | — | Per-slot class overrides for the component. |
items | CommandOptionData<T>[] | — | Items rendered by the component. |
placeholder | string | — | Placeholder. |
searchTerm | string | — | Search term. |
externalFilter | boolean | — | Whether the items are already filtered and ranked by an external engine
(e.g. full-text content search). When true, the built-in fuzzy filter is
skipped and all `items` render as-is; `searchTerm` still syncs via
`update:searchTerm` so the caller can drive its own search. |
clearable | boolean | — | Whether clearable. |
fuseOptions | UseFuseOptions<T> | — | Fuse options. |
listProps | ListboxContentProps | — | Properties forwarded to the list element. |
itemProps | ListboxItemProps | — | Properties forwarded to the item element. |
itemLabelProps | CommandItemLabelProps | — | Properties forwarded to the item label element. |
itemContentProps | CommandItemContentProps | — | Properties forwarded to the item content element (wraps label + description). |
itemDescriptionProps | CommandDescriptionProps | — | Properties forwarded to the item description element. |
groupProps | ListboxGroupProps | — | Properties forwarded to the group element. |
groupLabelProps | ListboxGroupLabelProps | — | Properties forwarded to the group label element. |
shortcutProps | CommandShortcutProps | — | Properties forwarded to the shortcut element. |
separatorProps | CommandSeparatorProps | — | Properties forwarded to the separator element. |
inputProps | ListboxFilterProps | — | Properties forwarded to the input element. |
emptyProps | CommandEmptyProps | — | Properties forwarded to the empty element. |
emptyLabel | string | — | Empty label. |
modelValue | string | — | The controlled value of the selected item(s).
Use this when you need to control the state of the items. Can be bound with `v-model` |
defaultValue | string | — | The default value of the selected item(s).
Use this when you need to set the initial state of the items. |
multiple | false | — | Determines whether a "single" or "multiple" items can be selected at a time.
This prop will overwrite the inferred type from `modelValue` and `defaultValue`. |
selectionBehavior | SelectionBehavior | 'toggle' | How multiple selection should behave in the collection. |
disabled | boolean | — | When `true`, prevents the user from interacting with listbox |
dir | Direction | — | The reading direction of the listbox when applicable. <br> If omitted, inherits globally from `ConfigProvider` or
assumes LTR (left-to-right) reading mode. |
orientation | DataOrientation | — | The orientation of the listbox. <br>Mainly so arrow navigation is done accordingly (left & right vs. up & down) |
name | string | — | The name of the field. Submitted with its owning form as part of a name/value pair. |
highlightOnHover | boolean | — | When `true`, hover over item will trigger highlight |
required | boolean | — | When `true`, indicates that the user must set the value before the owning form can be submitted. |
Emits
| Emit Name | Parameters | Description |
|---|---|---|
update:modelValue | string | — |
highlight | CollectionItemData<ListboxCollectionItemData> | undefined | Event handler when highlighted element changes. |
entryFocus | CustomEvent<any> | Event handler called when container is being focused. Can be prevented. |
leave | Event | Event handler called when the mouse leave the container |
select | SelectEvent<string> | Event handler called when the selecting item. <br> It can be prevented by calling `event.preventDefault`. |
update:searchTerm | string | Emitted when the search term value changes. |
Slots
| Slot Name | Parameters | Description |
|---|---|---|
input-leading | CommandCompactInputSlotProps | Custom content for the input leading slot. |
input-trailing | CommandCompactInputSlotProps | Custom content for the input trailing slot. |
empty | — | Custom content for the empty slot. |
item-leading | CommandCompactItemSlotProps<T> | Custom content for the item leading slot. |
item-trailing | CommandCompactItemSlotProps<T> | Custom content for the item trailing slot. |
item-label | CommandCompactItemSlotProps<T> | Custom content for the item label slot. |
item-description | CommandCompactItemSlotProps<T> | Custom content for the item description slot. |
bottom | — | Custom content for the bottom slot. |
CommandCompact<T>
Props
| Prop | Type | Default | Description |
|---|---|---|---|
items | CommandOptionData<T>[] | — | Items rendered by the component. |
placeholder | string | — | Placeholder. |
searchTerm | string | — | Search term. |
externalFilter | boolean | — | Whether the items are already filtered and ranked by an external engine
(e.g. full-text content search). When true, the built-in fuzzy filter is
skipped and all `items` render as-is; `searchTerm` still syncs via
`update:searchTerm` so the caller can drive its own search. |
clearable | boolean | — | Whether clearable. |
fuseOptions | UseFuseOptions<T> | — | Fuse options. |
listProps | ListboxContentProps | — | Properties forwarded to the list element. |
itemProps | ListboxItemProps | — | Properties forwarded to the item element. |
itemLabelProps | CommandItemLabelProps | — | Properties forwarded to the item label element. |
itemContentProps | CommandItemContentProps | — | Properties forwarded to the item content element (wraps label + description). |
itemDescriptionProps | CommandDescriptionProps | — | Properties forwarded to the item description element. |
groupProps | ListboxGroupProps | — | Properties forwarded to the group element. |
groupLabelProps | ListboxGroupLabelProps | — | Properties forwarded to the group label element. |
shortcutProps | CommandShortcutProps | — | Properties forwarded to the shortcut element. |
separatorProps | CommandSeparatorProps | — | Properties forwarded to the separator element. |
inputProps | ListboxFilterProps | — | Properties forwarded to the input element. |
emptyProps | CommandEmptyProps | — | Properties forwarded to the empty element. |
emptyLabel | string | — | Empty label. |
modelValue | string | — | The controlled value of the selected item(s).
Use this when you need to control the state of the items. Can be bound with `v-model` |
defaultValue | string | — | The default value of the selected item(s).
Use this when you need to set the initial state of the items. |
multiple | false | — | Determines whether a "single" or "multiple" items can be selected at a time.
This prop will overwrite the inferred type from `modelValue` and `defaultValue`. |
selectionBehavior | SelectionBehavior | 'toggle' | How multiple selection should behave in the collection. |
disabled | boolean | — | When `true`, prevents the user from interacting with listbox |
dir | Direction | — | The reading direction of the listbox when applicable. <br> If omitted, inherits globally from `ConfigProvider` or
assumes LTR (left-to-right) reading mode. |
orientation | DataOrientation | — | The orientation of the listbox. <br>Mainly so arrow navigation is done accordingly (left & right vs. up & down) |
name | string | — | The name of the field. Submitted with its owning form as part of a name/value pair. |
highlightOnHover | boolean | — | When `true`, hover over item will trigger highlight |
required | boolean | — | When `true`, indicates that the user must set the value before the owning form can be submitted. |
Emits
| Emit Name | Parameters | Description |
|---|---|---|
update:modelValue | string | — |
highlight | CollectionItemData<ListboxCollectionItemData> | undefined | Event handler when highlighted element changes. |
entryFocus | CustomEvent<any> | Event handler called when container is being focused. Can be prevented. |
leave | Event | Event handler called when the mouse leave the container |
select | SelectEvent<string> | Event handler called when the selecting item. <br> It can be prevented by calling `event.preventDefault`. |
update:searchTerm | string | Emitted when the search term value changes. |
Slots
| Slot Name | Parameters | Description |
|---|---|---|
input-leading | CommandCompactInputSlotProps | Custom content for the input leading slot. |
input-trailing | CommandCompactInputSlotProps | Custom content for the input trailing slot. |
empty | — | Custom content for the empty slot. |
item-leading | CommandCompactItemSlotProps<T> | Custom content for the item leading slot. |
item-trailing | CommandCompactItemSlotProps<T> | Custom content for the item trailing slot. |
item-label | CommandCompactItemSlotProps<T> | Custom content for the item label slot. |
item-description | CommandCompactItemSlotProps<T> | Custom content for the item description slot. |
bottom | — | Custom content for the bottom slot. |
CommandDescription
CommandEmpty
CommandItemContent
CommandItemLabel
CommandSeparator
Props
| Prop | Type | Default | Description |
|---|---|---|---|
orientation | DataOrientation | — | Orientation of the component.
Either `vertical` or `horizontal`. Defaults to `horizontal`. |
decorative | boolean | — | Whether or not the component is purely decorative. <br>When `true`, accessibility-related attributes are updated so
that that the rendered element is removed from the accessibility tree. |
CommandShortcut
Props
| Prop | Type | Default | Description |
|---|---|---|---|
symbolize | boolean | true | Whether to convert the command value to symbol representation. |
Notes
Architecture and benchmark differences
CommandCompact owns the Fuse search, grouped-item aggregation and default item composition while the underlying listbox primitives stay style-free and only the UI wrapper injects the commandVariants classes. This mirrors the cmdk/shadcn-ui headless command split. Ant Design, Element Plus, Mantine and Naive UI ship a select/autocomplete rather than a dedicated command palette; VeanUI provides a true ⌘K-style command with Fuse fuzzy search, grouped data, icons/shortcuts, and full listbox keyboard behavior.
| Capability | VeanUI | shadcn/ui (cmdk) | Ant Design | Element Plus | Mantine | Naive UI |
|---|---|---|---|---|---|---|
| Aria/styled split | ✅ | ✅ | — | — | — | — |
| Fuzzy search (Fuse) | ✅ | ✅ | — | — | — | — |
| Grouped data | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
| Icons + shortcuts | ✅ | ✅ | — | — | ✅ | — |
| Keyboard nav | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
| Empty state | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
— = unsupported or a different interaction model.
Cautions
searchTermis controllable viav-model:searchTerm; filtering is performed by Fuse (defaultthreshold: 0.1,resultLimit: 12, match-all on empty).itemsaccepts grouped objects (itemsnested) and flat items;separator: truerenders a divider after a group/item.shortcutrenders as aKbd(e.g.['command', 'h']);iconrenders a leading icon.clearableshows a trailing clear control that resetssearchTerm; the empty state uses the localizedcommand.noResultsmessage.- The underlying listbox handles keyboard/roving focus; selection emits
selectandupdate:modelValue.
Roadmap
N/A — command is feature-complete for the current parity set.
FAQ
How do I build a command palette?
Pass items and a placeholder:
<SCommand
placeholder="Type a command..."
:items="[
{ label: 'Search Emoji', value: 'emoji', icon: 'lucide:smile' },
{ label: 'Help', value: 'help', icon: 'lucide:help-circle', shortcut: ['command', 'h'] }
]"
@select="onSelect"
/>How do I group items?
Nest items under a group object with a separator:
<SCommand
:items="[
{
label: 'Suggestions',
value: 'suggestions',
separator: true,
items: [{ label: 'Calendar', value: 'calendar' }]
}
]"
/>How do I control the search term?
Bind searchTerm with v-model:searchTerm and tune fuse-options:
<SCommand v-model:searchTerm="query" :items="items" :fuse-options="{ threshold: 0.3 }" />How do I show an empty state?
Set empty-label (falls back to the localized command.noResults):
<SCommand :items="items" empty-label="No results found" />How do I handle selection?
Listen to select and update:modelValue:
<SCommand :items="items" @select="value => run(value)" />How do I show an item description?
Add a description to the item — it renders as a secondary line under the label and is included in the built-in fuzzy filter:
<SCommand :items="[{ label: 'Calendar', value: 'calendar', description: 'Schedule management view' }]" />How do I use an external search engine instead of the built-in filter?
Set external-filter: the built-in fuzzy filter is skipped and items render as-is (preserving your ranking). searchTerm still syncs via v-model:searchTerm / update:searchTerm so you can drive your own search — for example a full-text content search:
<SCommand v-model:searchTerm="query" external-filter :items="results" @select="open" />