Skip to content
Sapphire UIv4.1.0

Command Palette

Find and run commands from a searchable keyboard dialog. Use it when an application has many actions that are difficult to reach through navigation alone.

Examples

Actions

JSX usage

Install this example’s dependencies, load the package stylesheet from Setup, and add Example CSS where shown. The snippet includes its local helpers.

bun add @kongmy-dev/sapphire-ui react react-dom radix-ui
"use client";
import { useState } from "react";
import { Button } from "@kongmy-dev/sapphire-ui/button";
import { CommandPalette } from "@kongmy-dev/sapphire-ui/command-palette";

function CommandActions() {
  const [open, setOpen] = useState(false);
  const [selected, setSelected] = useState('No action');
  return (
    <div className="sp-cluster">
      <Button onClick={() => setOpen(true)}>Search actions</Button>
      <CommandPalette
        placeholder="Find an action…"
        items={[
          {
            id: 'save',
            label: 'Save draft',
            onSelect: () => setSelected('Draft saved'),
          },
          {
            id: 'publish',
            label: 'Publish document',
            onSelect: () => setSelected('Document published'),
          },
        ]}
        open={open}
        onOpenChange={setOpen}
      />
      <output>{selected}</output>
    </div>
  );
}

export default CommandActions;
Example CSS

Load these demo styles alongside the package stylesheet for the same layout and surfaces.

.docs-palette-stage {
  position: relative;
  height: 80vh;
  overflow: hidden;
  contain: layout paint;
  background: var(--background);
  border: var(--border-width) solid var(--border);
  border-radius: var(--radius-md);
}

.docs-palette-stage :is(.sp-sheet, .sp-sheet-overlay) {
  animation-duration: 0s;
}
HTML markup

Initial rendered HTML only. React handlers and portalled content require the JSX example; static HTML does not reproduce those interactions.

Navigation

JSX usage

Install this example’s dependencies, load the package stylesheet from Setup, and add Example CSS where shown. The snippet includes its local helpers.

bun add @kongmy-dev/sapphire-ui react react-dom radix-ui
"use client";
import { useState } from "react";
import { Button } from "@kongmy-dev/sapphire-ui/button";
import { type CommandItem, CommandPalette } from "@kongmy-dev/sapphire-ui/command-palette";

function CommandNavigation() {
  const [open, setOpen] = useState(false);
  const [selected, setSelected] = useState('No command');
  const items = [
    {
      id: 'projects',
      label: 'Open projects',
      hint: '/projects',
      onSelect: (query: string) => setSelected(`Projects: ${query}`),
      icon: (
        <svg
          className="sp-icon"
          aria-hidden="true"
          viewBox="0 0 24 24"
          fill="none"
          stroke="currentColor"
          strokeWidth={2}
        >
          <path d="M3 7h18v14H3zM7 7V3h10v4" />
        </svg>
      ),
    },
    {
      id: 'settings',
      label: 'Open settings',
      hint: '/settings',
      onSelect: () => setSelected('Settings'),
    },
  ] satisfies CommandItem[];
  return (
    <div className="sp-cluster">
      <Button onClick={() => setOpen(true)}>Search navigation</Button>
      <CommandPalette items={items} open={open} onOpenChange={setOpen} />
      <output>{selected}</output>
    </div>
  );
}

export default CommandNavigation;
Example CSS

Load these demo styles alongside the package stylesheet for the same layout and surfaces.

.docs-palette-stage {
  position: relative;
  height: 80vh;
  overflow: hidden;
  contain: layout paint;
  background: var(--background);
  border: var(--border-width) solid var(--border);
  border-radius: var(--radius-md);
}

.docs-palette-stage :is(.sp-sheet, .sp-sheet-overlay) {
  animation-duration: 0s;
}
HTML markup

Initial rendered HTML only. React handlers and portalled content require the JSX example; static HTML does not reproduce those interactions.

Props

Generated from the current public TypeScript signatures, including composed behaviour props. “—” means no default is declared in the local signature; forwarded behaviour defaults are not inferred.

CommandPalette

CommandPalette component props
PropTypeRequiredLocal default
itemsreadonly CommandItem[]Yes—
openbooleanYes—
onOpenChange(open: boolean) => voidYes—
placeholderstring | undefinedNo—

CommandItem

Supporting type used by this API.

CommandItem component props
PropTypeRequiredLocal default
idstringYes—
labelstringYes—
hintstring | undefinedNo—
iconReactElement<unknown, string | import("react").JSXElementConstructor<any>> | null | undefinedNo—
onSelect(query: string) => voidYes—

Setup

bun add @kongmy-dev/sapphire-ui react react-dom radix-ui

For an app using package components throughout, load the full stylesheet once. Add this component import where you use it.

import "@kongmy-dev/sapphire-ui/sapphire.css";
import { CommandPalette } from "@kongmy-dev/sapphire-ui/command-palette";

Mixing package and vendored components? Follow application setup.

Search documentation