Pallas UI
DocsComponents
Core Concepts
    • Introduction
    • Getting Started
    • Theming
    • Color Tokens
    • Spacing & Sizing
    • Layout Guide
    • AspectRatio
    • Box
    • Flex
    • Grid
    • Shapes
Previews
    • Accordion
    • Alert
    • Avatar
    • Badge
    • Breadcrumb
    • Button
    • Carousel
    • Checkbox
    • Combobox
    • Command
    • Date Picker
    • Form
    • Input
    • Input OTP
    • Label
    • MenuBar
    • Modal
    • Popover
    • Progress
    • Radio Group
    • Segmented
    • Select
    • Separator
    • Sheet
    • Sidebar
    • Skeleton
    • Slider
    • Spinner
    • Steps
    • Switch
    • Tabs
    • Textarea
    • Toast
    • Tooltip
    • Typography
  1. Components
  2. Command

Command

Composable command menu.

No results found.
Suggestions
Calendar
Search Emoji
Calculator
Settings
Profile
Billing
Settings

Installation

Install the following dependencies

npm install cmdk @radix-ui/react-dialog

Copy and paste the following code into your project

'use client'
 
import { type Assign, type WithFixedClassName, createStyleContext } from '@pallas-ui/style-context'
import * as DialogPrimitive from '@radix-ui/react-dialog'
import { css, cx } from '@styled-system/css'
import { hstack } from '@styled-system/patterns'
import { type CommandVariantProps, command, dialog, icon } from '@styled-system/recipes'
import type { ComponentProps, JsxStyleProps } from '@styled-system/types'
import { Command as CommandPrimitive } from 'cmdk'
import { SearchIcon, XIcon } from 'lucide-react'
import * as React from 'react'
 
const { withProvider, withContext } = createStyleContext(command)
 
const CommandContext = React.createContext<{
  isModal?: boolean
} | null>(null)
 
const useCommandContext = () => {
  const context = React.useContext(CommandContext)
  if (!context) {
    throw new Error('useCommandContext must be used within Command.Root')
  }
  return context
}
 
export type RootProps = WithFixedClassName<ComponentProps<typeof CommandPrimitive>>
 
const CustomRoot = React.forwardRef<React.ComponentRef<typeof CommandPrimitive>, RootProps>(
  ({ className, ...props }, ref) => {
    const { root } = command()
    return (
      <CommandContext.Provider value={{ isModal: false }}>
        <CommandPrimitive ref={ref} className={cx(root, className)} {...props} />
      </CommandContext.Provider>
    )
  },
)
 
export const Root = withProvider<
  React.ComponentRef<typeof CommandPrimitive>,
  Assign<RootProps, JsxStyleProps>
>(CustomRoot, 'root')
 
const ModalRoot = withProvider<
  React.ComponentRef<typeof CommandPrimitive>,
  Assign<RootProps, CommandVariantProps & JsxStyleProps>
>(CommandPrimitive, 'root')
 
export type DialogProps = RootProps &
  ComponentProps<typeof DialogPrimitive.Root> & {
    title?: string
    description?: string
    className?: string
    showCloseButton?: boolean
  }
 
const dialogStyles = dialog()
 
const CommandDialog = React.forwardRef<
  React.ComponentRef<typeof DialogPrimitive.Content>,
  DialogProps
>(({ children, title, description, showCloseButton = true, ...props }, ref) => (
  <DialogPrimitive.Root className={dialogStyles.root} {...props}>
    <div data-slot="command-dialog-header" className={dialogStyles.header}>
      <DialogPrimitive.Title>{title}</DialogPrimitive.Title>
      <DialogPrimitive.Description>{description}</DialogPrimitive.Description>
    </div>
    <DialogPrimitive.Portal data-slot="dialog-portal">
      <DialogPrimitive.Overlay
        data-slot="command-dialog-overlay"
        className={dialogStyles.overlay}
      />
      <DialogPrimitive.Content
        data-slot="command-dialog-content"
        {...props}
        className={dialogStyles.content}
        ref={ref}
      >
        <CommandContext.Provider value={{ isModal: true }}>
          <ModalRoot type="floating" {...props}>
            {children}
            {showCloseButton && (
              <DialogPrimitive.Close
                data-slot="command-dialog-close"
                onKeyDown={({ code }) => {
                  if (code === 'Enter') props.onOpenChange?.(false)
                }}
              >
                <XIcon className={icon({ size: 'xl' })} />
                <span className={css({ srOnly: true })}>Close</span>
              </DialogPrimitive.Close>
            )}
          </ModalRoot>
        </CommandContext.Provider>
      </DialogPrimitive.Content>
    </DialogPrimitive.Portal>
  </DialogPrimitive.Root>
))
 
export const Dialog = withProvider<
  React.ComponentRef<typeof DialogPrimitive.Root>,
  Assign<DialogProps, JsxStyleProps>
>(CommandDialog, 'dialog')
 
const CommandInput = React.forwardRef<
  React.ComponentRef<typeof CommandPrimitive.Input>,
  ComponentProps<typeof CommandPrimitive.Input>
>(({ ...props }, ref) => {
  const { isModal } = useCommandContext()
  return (
    <div className={hstack()} data-slot="command-input-wrapper">
      <SearchIcon data-slot="command-input-icon" className={icon({ dimmed: true })} />
      <CommandPrimitive.Input {...props} ref={ref} autoFocus={isModal} />
    </div>
  )
})
 
CommandInput.displayName = CommandPrimitive.Input.displayName
 
export const Input = withContext<
  React.ComponentRef<typeof CommandPrimitive.Input>,
  Assign<ComponentProps<typeof CommandPrimitive.Input>, JsxStyleProps>
>(CommandInput, 'input')
 
export const List = withContext<
  React.ComponentRef<typeof CommandPrimitive.List>,
  Assign<ComponentProps<typeof CommandPrimitive.List>, JsxStyleProps>
>(CommandPrimitive.List, 'list')
 
export const Empty = withContext<
  React.ComponentRef<typeof CommandPrimitive.Empty>,
  Assign<ComponentProps<typeof CommandPrimitive.Empty>, JsxStyleProps>
>(CommandPrimitive.Empty, 'empty')
 
export const Group = withContext<
  React.ComponentRef<typeof CommandPrimitive.Group>,
  Assign<ComponentProps<typeof CommandPrimitive.Group>, JsxStyleProps>
>(CommandPrimitive.Group, 'group')
 
export const ItemIndicator = withContext<
  React.ComponentRef<'div'>,
  Assign<React.ComponentPropsWithoutRef<'div'>, JsxStyleProps>
>('div', 'itemIndicator')
 
const CustomItem = React.forwardRef<
  React.ComponentRef<typeof CommandPrimitive.Item>,
  ComponentProps<typeof CommandPrimitive.Item> & {
    icon?: React.ReactNode
  }
>(({ children, icon = false, ...props }, ref) => {
  return (
    <CommandPrimitive.Item ref={ref} {...props}>
      {icon && <ItemIndicator>{icon}</ItemIndicator>}
      {children}
    </CommandPrimitive.Item>
  )
})
 
CustomItem.displayName = CommandPrimitive.Item.displayName
 
export const Item = withContext<
  React.ComponentRef<typeof CommandPrimitive.Item>,
  Assign<
    ComponentProps<typeof CommandPrimitive.Item> & {
      icon?: React.ReactNode
    },
    JsxStyleProps
  >
>(CustomItem, 'item')
 
export const Separator = withContext<
  React.ComponentRef<typeof CommandPrimitive.Separator>,
  Assign<ComponentProps<typeof CommandPrimitive.Separator>, JsxStyleProps>
>(CommandPrimitive.Separator, 'separator')
 
const Command = {
  Root,
  Dialog,
  Input,
  List,
  Empty,
  Group,
  Item,
  Separator,
}
 
export default Command

Update the import paths to match your project setup

Usage

import {
  Command
} from '@/components/ui/command'
<Command.Root>
  <Command.Input placeholder="Type a command or search..." />
  <Command.List>
    <Command.Empty>No results found.</Command.Empty>
    <Command.Group heading="Suggestions">
      <Command.Item>
        <Calendar />
        <span>Calendar</span>
      </Command.Item>
      <Command.Item>
        <Smile />
        <span>Search Emoji</span>
      </Command.Item>
      <Command.Item disabled>
        <Calculator />
        <span>Calculator</span>
      </Command.Item>
    </Command.Group>
    <Command.Separator />
    <Command.Group heading="Settings">
      <Command.Item>
        <User />
        <span>Profile</span>
      </Command.Item>
      <Command.Item>
        <CreditCard />
        <span>Billing</span>
      </Command.Item>
      <Command.Item>
        <Settings />
        <span>Settings</span>
      </Command.Item>
    </Command.Group>
  </Command.List>
</Command.Root>

Examples

Default

No results found.
Suggestions
Calendar
Search Emoji
Calculator
Settings
Profile
Billing
Settings

Dialog

Press ⌘J

Built with ❤️ by the carbonteq team. The source code is available on GitHub.

© 2025 Pallas UI. All rights reserved.