Tessina UI
Tessina UI
GitHubIntroduction
InstallationUsageTheming
Components
ButtonIconButtonLinkSpinnerBadgeAvatarStatusChipShortcutSkeletonSurfaceProgressMeterRating
LabelFieldFieldsetCheckboxRadioSwitchSliderSelectComboboxSearchTextareaNumberFieldDate PickerTime PickerOTP InputFile UploadCalendar
AlertBannerToastTooltip
TabsAccordionCollapsibleBreadcrumbPaginationStepperSegmentedControlButtonGroupToggleButtonToggleGroupToolbarNavigation MenuMenubarBottom NavSidebar
Split ButtonFABDropdown MenuContextMenuCommandPopoverHoverCard
ContainerStackFlexGridAspectRatioSpacerCardCarouselDividerScroll Area
Table
ChatBubblePromptInputCodeBlock
ModalAlertDialogDrawerAction SheetTop Header MobileTop Header DesktopEmptyStateForm
Contributing
ComponentsAction Blocks

Command

Command palette / ⌘K menu — filterable, keyboard-driven action launcher with inline and modal modes, grouped items, descriptions, breadcrumbs, shortcuts, and footer key hints.

Playground

Installation

pnpm add @tessinaui/ui

Usage

import {
  Command,
  useCommandShortcut,
} from "@tessinaui/ui";

Inline command palette

Embed the palette directly in the page. The list is always visible — typing into the input filters items live.

<Command.Root size="md" rounded="xl">
  <Command.Input placeholder="Type a command or search…" shortcut="⌘K" />
  <Command.List>
    <Command.Empty>No results found.</Command.Empty>
    <Command.Group heading="Suggestions">
      <Command.Item value="dashboard" leadingIcon={<LayoutDashboard />}>
        <Command.ItemTitle>Dashboard</Command.ItemTitle>
        <Command.Shortcut>⌘D</Command.Shortcut>
      </Command.Item>
      <Command.Item value="settings" leadingIcon={<Settings />}>
        <Command.ItemTitle>Settings</Command.ItemTitle>
      </Command.Item>
    </Command.Group>
  </Command.List>
</Command.Root>

Modal command palette

Wrap the same content in Command.Dialog to make a ⌘K overlay. Pair with useCommandShortcut("k", …) for a global keyboard trigger.

function App() {
  const [open, setOpen] = useState(false);
  useCommandShortcut("k", () => setOpen((o) => !o));

  return (
    <Command.Dialog open={open} onOpenChange={setOpen}>
      <Command.Input placeholder="Search…" />
      <Command.List>
        <Command.Empty>No results found.</Command.Empty>
        <Command.Group heading="Actions">
          <Command.Item value="new-file" onSelect={() => createFile()}>
            <Command.ItemTitle>New file</Command.ItemTitle>
            <Command.Shortcut>⌘N</Command.Shortcut>
          </Command.Item>
        </Command.Group>
      </Command.List>
      <Command.Footer>
        <Command.FooterHint shortcut="enter">To select</Command.FooterHint>
        <Command.FooterHint shortcut="arrows">To navigate</Command.FooterHint>
        <Command.FooterHint shortcut="escape" appearance="ghost">To close</Command.FooterHint>
      </Command.Footer>
    </Command.Dialog>
  );
}

Items with rich content

Items can hold a title, optional description, breadcrumb path, and a trailing shortcut.

<Command.Item value="settings-team" leadingIcon={<Users />}>
  <Command.ItemTitle>Team settings</Command.ItemTitle>
  <Command.ItemDescription>Invite or remove members</Command.ItemDescription>
  <Command.Shortcut>⌘T</Command.Shortcut>
</Command.Item>

<Command.Item value="docs-deep-link">
  <Command.Crumbs crumbs={["Components", "Form", "Field"]} />
</Command.Item>

Examples

API Reference

Command.Root / Command.Dialog props

Both accept the same visual props. Command.Root renders inline; Command.Dialog renders inside a Base UI Dialog with backdrop and focus trap.

PropTypeDefaultDescription
size"xs" | "sm" | "md" | "lg" | "xl""md"Input height, padding, and typography scale
rounded"none" | "sm" | "md" | "lg" | "xl" | "full""full" (Dialog) / "xl" (Root)Container border radius (full = 36px)
width"narrow" | "default" | "wide""default"Max-width — used when modal
intent"none" | "error" | "warning" | "success" | "info""none"Semantic accent on the container border
dir"ltr" | "rtl""ltr"Text direction. Flips chevrons and shortcut alignment
value / defaultValueValue—Controlled / uncontrolled selected item value (from Base UI Combobox)
onValueChange(value) => void—Fires when the selection changes
inputValue / defaultInputValuestring—Controlled / uncontrolled text input value
onInputValueChange(value) => void—Fires as the user types
disabledbooleanfalseDisables all interaction

Command.Dialog additional props

PropTypeDefaultDescription
openboolean—Controlled open state
defaultOpenboolean—Uncontrolled initial open state
onOpenChange(open: boolean, event: Event) => void—Fires when the dialog opens or closes
dismissiblebooleantrueWhether Escape / backdrop click closes the dialog
modalbooleantrueWhether focus is trapped and page scroll is locked
labelstring"Command palette"a11y label for the Dialog popup

Command.Input props

PropTypeDefaultDescription
placeholderstring"Type a command or search…"Placeholder text
leadingIconReactNodesearch iconOverride the leading icon. Pass null to hide
shortcutReactNode—Trailing kbd hint shown to the right of the input
trailingReactNode—Additional trailing content (e.g. mic button)
showClearbooleantrueShow the × clear button when the input has a value

Command.Item props

PropTypeDefaultDescription
valuestring—Value used for filtering and selection
leadingIconReactNode—Leading slot — typically a Lucide icon
leadingAvatarReactNode—Leading slot — avatar visual (mutually exclusive with leadingIcon)
trailingIconReactNode—Trailing slot — icon or status indicator
hideLeadingbooleanfalseHide the leading slot entirely
onSelect(value) => void—Fires when the item is selected (click or Enter)
disabledbooleanfalseDisables the item

Command.Group props

PropTypeDefaultDescription
headingReactNode—Group heading rendered above the items
headingTrailingReactNode—Optional slot rendered at the end of the heading row (e.g. "See all" link)

Command.Crumbs props

PropTypeDefaultDescription
crumbsReactNode[]—Path segments. Last segment styled as the destination
separatorReactNodechevron rightCustom separator between segments

Command.Empty props

PropTypeDefaultDescription
iconReactNode—Optional decorative icon shown above the empty text

Command.Loading props

PropTypeDefaultDescription
labelReactNode"Loading…"Loading message rendered beside the spinner

Command.FooterHint props

PropTypeDefaultDescription
shortcutReactNode | "enter" | "arrow-up" | "arrow-down" | "arrows" | "escape" | "tab" | "shift"—Glyph or preset for the kbd chip
labelPosition"before" | "after""after"Whether the label sits before or after the chip
appearance"filled" | "ghost""filled"Filled (default) or outlined chip

Rich content layouts

For Mobbin / Linear / Raycast-style palettes, compose additional parts on top of the core API:

  • Command.Chips + Command.ChipItem — horizontal scrollable pill row (recent searches, filters)
  • Command.Body + Command.Sidebar + Command.SidebarItem — two-column layout with an inner view-switching nav rail
  • Command.Section — heading wrapper for arbitrary content; auto-hides when its filterable children are all filtered out
  • Command.Grid + Command.Card — thumbnail card grid (filter-aware via value)
  • Command.IconRow + Command.AppIcon — horizontal app logo strip (decorative, non-filterable)
<Command.Dialog>
  <Command.Input
    placeholder="iOS Apps, Screens, UI Elements, Flows or Keywords…"
    trailing={
      <SegmentedControl size="xs" value={platform} onValueChange={setPlatform}>
        <SegmentedControlItem value="ios"><Smartphone /></SegmentedControlItem>
        <SegmentedControlItem value="desktop"><Monitor /></SegmentedControlItem>
      </SegmentedControl>
    }
  />
  <Command.Chips>
    <Command.ChipItem leadingIcon={<Search />} value="transactions">transactions</Command.ChipItem>
    <Command.ChipItem leadingIcon={<DocFile />} value="note-detail">Note Detail</Command.ChipItem>
  </Command.Chips>
  <Command.Body>
    <Command.Sidebar value={view} onValueChange={setView}>
      <Command.SidebarItem value="trending" leadingIcon={<TrendingUp />}>Trending</Command.SidebarItem>
      <Command.SidebarItem value="screens"  leadingIcon={<Smartphone />}>Screens</Command.SidebarItem>
    </Command.Sidebar>
    <Command.List>
      <Command.IconRow>
        <Command.AppIcon src="/duolingo.png" label="Duolingo" />
        <Command.AppIcon src="/wise.png" label="Wise" />
      </Command.IconRow>
      <Command.Section heading="Screens">
        <Command.Grid columns={3}>
          <Command.Card value="signup" title="Signup" image="/signup.png" />
          <Command.Card value="login"  title="Login"  image="/login.png" />
        </Command.Grid>
      </Command.Section>
    </Command.List>
  </Command.Body>
</Command.Dialog>

Command.Chips / Command.ChipItem props

PropTypeDefaultDescription
label (Chips)ReactNode—Optional label rendered before the pills
value (ChipItem)string—Filter value. Chip hides when the input query doesn't match
leadingIconReactNode—Leading icon
leadingAvatarReactNode—Leading avatar (replaces icon)
onRemove() => void—Show a trailing × button; called when clicked

Command.Body / Command.Sidebar props

PropTypeDefaultDescription
minHeight (Body)string | number"320px"Min-height of the row layout
value (Sidebar)string—Controlled active item value
defaultValue (Sidebar)string—Uncontrolled initial active value
onValueChange (Sidebar)(value) => void—Fires when active item changes
value (SidebarItem)string—Item identifier, compared against the sidebar's value
leadingIcon / trailingIcon (SidebarItem)ReactNode—Icons

Command.Section props

PropTypeDefaultDescription
headingReactNode—Heading rendered above the content
headingTrailingReactNode—Slot rendered at the end of the heading row

Auto-hides when filtering removes every Command.Item, Command.ChipItem, or Command.Card descendant.

Command.Grid / Command.Card props

PropTypeDefaultDescription
columns (Grid)1 | 2 | 3 | 4 | 5 | 63Number of columns
gap (Grid)string"gap-2"Tailwind gap class
value (Card)string—Filter value. Card hides on no match
title / descriptionReactNode—Text under the media frame
image (Card)string—Image src (rendered as <img>)
media (Card)ReactNode—Custom content inside the aspect frame (overrides image)
aspect (Card)"square" | "video" | "3/4" | "4/3" | "1/1""3/4"Aspect ratio of the media frame
onSelect (Card)(value) => void—Called when the card is activated

Command.IconRow / Command.AppIcon props

PropTypeDefaultDescription
gap (IconRow)string"gap-3"Tailwind gap class
src (AppIcon)string—Image src for the logo
label (AppIcon)string—Accessible label / tooltip
children (AppIcon)ReactNode—Custom content (overrides src)

useCommandShortcut(key, onTrigger, options?)

Hook for binding a global keyboard trigger.

ArgumentTypeDescription
keystringCase-insensitive key name (e.g. "k")
onTrigger() => voidCallback fired when the chord is pressed
options.modifier"auto" | "ctrl" | "meta" | "alt" | "shift" | "none""auto" (default) detects platform: ⌘ on macOS, Ctrl elsewhere
options.enabledbooleanSet false to suspend listening

Accessibility

  • The dialog uses @base-ui/react/dialog — focus is trapped inside, and Escape closes (when dismissible is true).
  • The list uses @base-ui/react/combobox in inline mode — arrow keys move the highlight, Enter selects the highlighted item, typing filters the list.
  • Group headings use <Combobox.GroupLabel> so screen readers announce the section context.
  • Empty / loading states are aria-live announcements via Base UI primitives.

ContextMenu

A right-click / long-press menu anchored at the cursor. Built on Base UI's context-menu primitive — supports items, groups, labels, separators, sub-menus, checkbox-items, and radio-items. Compound API mirrors DropdownMenu so you can swap one for the other when the trigger gesture changes from click to right-click.

Popover

A floating panel that appears next to its trigger and holds interactive content. Click-activated, with full keyboard support, positioning, an optional arrow, and compound parts for header, body, and footer.

On this page

PlaygroundInstallationUsageInline command paletteModal command paletteItems with rich contentExamplesAPI ReferenceCommand.Root / Command.Dialog propsCommand.Dialog additional propsCommand.Input propsCommand.Item propsCommand.Group propsCommand.Crumbs propsCommand.Empty propsCommand.Loading propsCommand.FooterHint propsRich content layoutsCommand.Chips / Command.ChipItem propsCommand.Body / Command.Sidebar propsCommand.Section propsCommand.Grid / Command.Card propsCommand.IconRow / Command.AppIcon propsuseCommandShortcut(key, onTrigger, options?)Accessibility