Loading...
Features
- Searchable Command Dialog: Command palette with fuzzy search and real-time filtering.
- Groupable Command List: Organize commands into logical groups with optional headings.
- Selectable Items: Items support click actions, selection states, and checkmark indicators.
- Keyboard Navigation: Full keyboard support with arrow keys, Enter, and Escape navigation.
- Custom Shortcuts: Optional shortcut labels shown beside each command item.
- Empty State Handling: Automatically displays a fallback when no items match the query.
- Loopable Navigation: Optional looping behavior for continuous up/down key cycling.
- Custom Filtering Logic: Swap out the built-in filter with your own function.
- Accessible & Composable: ARIA roles and headless architecture for complete flexibility.
- Responsive Design: Adapts gracefully to different screen sizes and containers.
- Dialog or Inline Support: Can be used as a floating dialog or embedded inline.
About
This component uses the @gentleduck/vim library under the hood.
Installation
npx @gentleduck/cli add command
npx @gentleduck/cli add command
Usage
import {
Command,
CommandDialog,
CommandEmpty,
CommandGroup,
CommandInput,
CommandItem,
CommandList,
CommandSeparator,
CommandShortcut,
TooltipProvider,
} from '@/components/ui'import {
Command,
CommandDialog,
CommandEmpty,
CommandGroup,
CommandInput,
CommandItem,
CommandList,
CommandSeparator,
CommandShortcut,
TooltipProvider,
} from '@/components/ui'<Command>
<CommandInput placeholder="Type a command or search..." />
<CommandList>
<CommandEmpty>No results found.</CommandEmpty>
<CommandGroup heading="Suggestions">
<CommandItem>Search GitHub</CommandItem>
<CommandItem>Search Twitter</CommandItem>
<CommandItem>Search Discord</CommandItem>
</CommandGroup>
<CommandSeparator />
<CommandGroup heading="Settings">
<CommandItem>General</CommandItem>
<CommandItem>Profile</CommandItem>
<CommandItem>Notifications</CommandItem>
</CommandGroup>
</CommandList>
</Command><Command>
<CommandInput placeholder="Type a command or search..." />
<CommandList>
<CommandEmpty>No results found.</CommandEmpty>
<CommandGroup heading="Suggestions">
<CommandItem>Search GitHub</CommandItem>
<CommandItem>Search Twitter</CommandItem>
<CommandItem>Search Discord</CommandItem>
</CommandGroup>
<CommandSeparator />
<CommandGroup heading="Settings">
<CommandItem>General</CommandItem>
<CommandItem>Profile</CommandItem>
<CommandItem>Notifications</CommandItem>
</CommandGroup>
</CommandList>
</Command>Examples
Dialog
Press ⌘J
To show the command menu in a dialog, use the <CommandDialog /> component, or use the <Button/> component with the command variant.
import { useKeyCommands } from '@gentleduck/vim/react'
export function CommandMenu() {
const [open, setOpen] = React.useState(false)
useKeyCommands({
'ctrl+j': {
name: '⌘j',
description: 'Open command menu',
execute: () => {
window.event?.preventDefault()
setOpen(true)
},
},
})
return (
<CommandDialog
open={open}
onOpenChange={setOpen}
>
<CommandInput placeholder="Type a command or search..." />
<CommandList>
<CommandEmpty>No results found.</CommandEmpty>
<CommandGroup heading="Suggestions">
<CommandItem>Settings</CommandItem>
<CommandItem>Messages</CommandItem>
<CommandItem>Search</CommandItem>
</CommandGroup>
</CommandList>
</CommandDialog>
)
}import { useKeyCommands } from '@gentleduck/vim/react'
export function CommandMenu() {
const [open, setOpen] = React.useState(false)
useKeyCommands({
'ctrl+j': {
name: '⌘j',
description: 'Open command menu',
execute: () => {
window.event?.preventDefault()
setOpen(true)
},
},
})
return (
<CommandDialog
open={open}
onOpenChange={setOpen}
>
<CommandInput placeholder="Type a command or search..." />
<CommandList>
<CommandEmpty>No results found.</CommandEmpty>
<CommandGroup heading="Suggestions">
<CommandItem>Settings</CommandItem>
<CommandItem>Messages</CommandItem>
<CommandItem>Search</CommandItem>
</CommandGroup>
</CommandList>
</CommandDialog>
)
}API Reference
Command Props
props(React.HTMLProps<HTMLDivElement>): All native div props are supported.
CommandInput Props
placeholder(string, optional): Placeholder text in the input. Default is'Search...'.autoFocus(boolean, optional): Automatically focus input on mount. Default istrue.onChange(React.ChangeEventHandler, optional): Triggered when the input value changes....props(React.HTMLProps<HTMLInputElement>): All native input props are supported.
CommandList Props
props(React.HTMLAttributes<HTMLUListElement>): All nativeulprops are supported.
CommandItem Props
value(string, optional): The internal value for selection.onSelect((value: string) => void, optional): Called when the item is selected.onClick(React.MouseEventHandler, optional): Native click event.onKeyDown(React.KeyboardEventHandler, optional): Native keydown event....props(React.HTMLProps<HTMLLIElement>): All nativeliprops are supported.
CommandGroup Props
heading(string, optional): Optional heading for the group.props(React.HTMLProps<HTMLDivElement>): All nativedivprops are supported.
CommandEmpty Props
props(React.HTMLAttributes<HTMLHeadingElement>): All nativeh6props are supported.
CommandShortcut Props
keys(string, optional): Keyboard shortcut string (e.g."ctrl+K").onKeysPressed(() => void, optional): Triggered when shortcut is pressed.variant('default' | 'secondary', optional): Visual style variant....props(React.HTMLProps<HTMLElement>): All nativekbdprops are supported.
CommandSeparator Props
props(React.HTMLProps<HTMLDivElement>): All nativedivprops are supported.
CommandDialog Props
props(DialogProps): All props supported by the underlying<Dialog />component.
Types
CommandContextType
| Property | Type | Description |
|---|---|---|
search | string | Current search query value. |
setSearch | React.Dispatch<React.SetStateAction<string>> | Setter for search query. |
CommandRefsContextType
| Property | Type | Description |
|---|---|---|
commandRef | React.RefObject<HTMLDivElement | null> | Root command container reference. |
listRef | React.RefObject<HTMLUListElement | null> | UL element holding items. |
emptyRef | React.RefObject<HTMLHeadingElement | null> | Empty state heading ref. |
inputRef | React.RefObject<HTMLInputElement | null> | Search input field reference. |
selectedItem | HTMLLIElement | null | Currently selected item. |
setSelectedItem | React.Dispatch<React.SetStateAction<HTMLLIElement | null>> | Setter for selected item. |
items | React.RefObject<HTMLLIElement[]> | All command items. |
filteredItems | React.RefObject<HTMLLIElement[]> | Filtered items after search. |
groups | React.RefObject<HTMLDivElement[]> | Groups of command items. |
CommandBadgeProps (CommandShortcut)
| Property | Type | Description |
|---|---|---|
keys | string (optional) | Keyboard shortcut string (e.g. 'ctrl+K'). |
onKeysPressed | () => void (optional) | Called when the shortcut is triggered. |
variant | 'default' | 'secondary' (optional) | Visual style. |
...props | React.HTMLProps<HTMLElement> | Native kbd element props. |