Command Menu

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

If you hit any issues, make sure you check out the installation guide here.

Composed Components

When you plug this component from the CLI, it autoloads all the composed components. No need to toss 'em in one at a time.

The Command Menu's decked out with several components to make it bangin'.

Separator

Lays down the access creds for a separator. It’s the visual boss that splits up chunks of content, like menu items or page sections.

Keyboard

Keyboard and focus support ensures smooth navigation with keys, essential for users without a mouse and appreciated by power users for quick access.

Manual Installation

Sometimes, using the CLI is the way to go, so make sure you install the necessary dependencies for the components you want to use.

And next, you can copy the code below and paste it into your dopest component folder.

Anatomy

Import the components and use them as shown below, adapting the structure to fit each 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.

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:

<CommandItem onSelect={() => console.log('share getjustd.com/d/command')} />

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.

<CommandMenu
  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}
>
  <CommandInput placeholder="Search for apps and commands..." />
  <CommandEmpty className="grid place-content-center">
    <div className="text-center">
      <IconCube className="inline" />
      <p className="mt-2">No results found.</p>
    </div>
  </CommandEmpty>
  ...
</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 (...)