Command

A command is like a button with a twist, it opens a menu of options. It's a cooler version of a combobox, ideal for command palettes, menus, and more.

Basic

This command menu is straightforward and always under your control, allowing you to open and close it as needed.

Installation

In the terminal, run the following command to begin:
npx hq-kit add command

Blurred

The isBlurred prop can be used to blur the background of the CommandMenu component. To do that, simply add the prop to the CommandMenu component:

Separator

Add a separator between items for clear distinction.

Section

While you can operate the command menu solo, utilizing sections can organize commands more effectively.

Keyboard

Integrate keyboard interaction with the command menu. Note that keyboard functionality may be limited on smaller screens.

Trigger by Keyboard

Activate the command menu via keyboard commands, ideal for initiating command palettes.

⌘ /

Danger

Highlight a command item as dangerous by changing its color to red, indicating a warning.

Blur

If you want to blur the background, you can use isBlurred prop.

Controlled

Manage the command palette dynamically using the value and onValueChange props, making it responsive to changes in a parent component.

Additionally, control the execution of an action upon selecting an item:

<Command.Item onSelect={() => console.log('share this component')} />

Disabled

Disable items in the command menu to make them non-interactive, appearing grayed out.

Hide Indicator

Eliminate the search indicator and close button for a cleaner interface by using hideSearchIndicator and hideCloseButton. View this setup in the Command Description section.

<Command
  hideCloseButton
  hideSearchIndicator
  isOpen={isOpen}
  onOpenChange={setIsOpen}
/>

Description

Enhance command items with descriptions using the CommandDescription component. Be aware that keyboard accessibility might be limited on smaller screens.

Fallback Empty Message

The default setup displays a "No results found." message when no items match. If you prefer a different message, modify it by setting the messageOnEmpty prop.

<Command messageOnEmpty='There are no results'/>

Alternatively, if you want to create a custom empty message, disable the default by setting messageOnEmpty to false and implement your own design like so:

<Command
  messageOnEmpty={false}
  hideCloseButton
  hideSearchIndicator
  isOpen={isOpen}
  onOpenChange={setIsOpen}
>
  <Command.Input placeholder="Search for apps and commands..." />
  <Command.Empty className="grid place-content-center">
    <div className="text-center">
      <IconPackage className="inline" />
      <p className="mt-2">No results found.</p>
    </div>
  </Command.Empty>
  ...
</Command>

And again, you can see how this works in the Command Description section. Try typing something that doesn't match any option to see how the custom empty message appears.

Indeed, when using this command palette within client-side frameworks like Next.js or Inertia.js, it’s practical to automatically close the palette upon navigating via a link. Here’s how you can manage that:

Inertia.js

In Inertia.js, utilize the router.on('navigate') event to automatically close the command palette when navigation occurs. Here’s an example: This setup ensures that the command palette closes seamlessly when the user navigates to a new page, maintaining a clean and distraction-free user interface.

export function CommandPalette({ open, setOpen }: Props) {
  React.useEffect(() => {
    const down = (e: KeyboardEvent) => {
      if (e.key === 'k' && (e.metaKey || e.ctrlKey)) {
        e.preventDefault()
        setOpen((open: boolean) => !open)
      }
    }
 
    document.addEventListener('keydown', down)
 
    return () => document.removeEventListener('keydown', down)
 
    router.on('navigate', () => setOpen(false))
  }, [pathname, setOpen])
  return (...)

Next.js

When using Next.js, you can use the usePathname hook to close the command palette when you navigate to a new page.

export function CommandPalette({ open, setOpen }: Props) {
  const pathname = usePathname()
  React.useEffect(() => {
    const down = (e: KeyboardEvent) => {
      if (e.key === 'k' && (e.metaKey || e.ctrlKey)) {
        e.preventDefault()
        setOpen((open: boolean) => !open)
      }
    }
 
    document.addEventListener('keydown', down)
 
    return () => document.removeEventListener('keydown', down)
  }, [pathname, setOpen])
  return (...)