Overlay

Command

A search-enabled command palette with grouped items, keyboard navigation, filtering, and custom rendering. Built on bits-ui Command.

Playground

Experiment with different props.

Basic Usage

Pass groups with items. Built-in search filters items as you type.

<script lang="ts">
  import { Command } from 'sv5ui';

  const groups = [
    {
      id: 'actions',
      label: 'Actions',
      items: [
        { value: 'new-file', label: 'New File', icon: 'lucide:file-plus' },
        { value: 'new-folder', label: 'New Folder', icon: 'lucide:folder-plus' },
        { value: 'search', label: 'Search', icon: 'lucide:search' }
      ]
    }
  ];
</script>

<Command {groups} placeholder="Type a command..." />

Grouped Items

Organize commands into labeled groups with automatic separators.

<Command groups={[
  {
    id: 'suggestions',
    label: 'Suggestions',
    items: [
      { value: 'calendar', label: 'Calendar', icon: 'lucide:calendar' },
      { value: 'search', label: 'Search Emoji', icon: 'lucide:smile' },
      { value: 'calculator', label: 'Calculator', icon: 'lucide:calculator' }
    ]
  },
  {
    id: 'settings',
    label: 'Settings',
    items: [
      { value: 'profile', label: 'Profile', icon: 'lucide:user' },
      { value: 'billing', label: 'Billing', icon: 'lucide:credit-card' },
      { value: 'preferences', label: 'Preferences', icon: 'lucide:settings' }
    ]
  }
]} />

With Description

Add secondary text to items.

<Command groups={[
  {
    id: 'pages',
    label: 'Pages',
    items: [
      { value: 'home', label: 'Home', description: 'Go to the home page', icon: 'lucide:home' },
      { value: 'docs', label: 'Documentation', description: 'Browse component docs', icon: 'lucide:book-open' },
      { value: 'blog', label: 'Blog', description: 'Read latest articles', icon: 'lucide:pen-line' }
    ]
  }
]} />

onSelect Callback

Execute actions when items are selected.

<script lang="ts">
  import { Command } from 'sv5ui';
  import { toast } from 'sv5ui';

  const groups = [{
    id: 'actions',
    items: [
      { value: 'copy', label: 'Copy', icon: 'lucide:copy', onSelect: () => toast('Copied!') },
      { value: 'paste', label: 'Paste', icon: 'lucide:clipboard', onSelect: () => toast('Pasted!') },
      { value: 'delete', label: 'Delete', icon: 'lucide:trash-2', onSelect: () => toast.error('Deleted!') }
    ]
  }];
</script>

<Command {groups} />

Search Keywords

Add keywords so items can be found by alternative search terms. Try typing "dark" or "console".

<!-- Keywords help users find items with alternative search terms -->
<Command groups={[{
  id: 'tools',
  items: [
    { value: 'theme', label: 'Toggle Theme', icon: 'lucide:sun', keywords: ['dark', 'light', 'mode'] },
    { value: 'zoom', label: 'Zoom In', icon: 'lucide:zoom-in', keywords: ['magnify', 'scale', 'bigger'] },
    { value: 'terminal', label: 'Open Terminal', icon: 'lucide:terminal', keywords: ['console', 'shell', 'cmd'] }
  ]
}]} />

Sizes

5 sizes.

sm

md

lg

<Command {groups} size="sm" />
<Command {groups} size="md" />
<Command {groups} size="lg" />

Disabled Items

<Command groups={[{
  id: 'items',
  items: [
    { value: 'active', label: 'Active Item', icon: 'lucide:check' },
    { value: 'disabled', label: 'Disabled Item', icon: 'lucide:ban', disabled: true },
    { value: 'another', label: 'Another Item', icon: 'lucide:plus' }
  ]
}]} />

Loading

<Command {groups} loading />

In a Modal (Cmd+K)

Classic command palette pattern. Press + K or click below.

<script lang="ts">
  import { Command, Modal, Button, Kbd } from 'sv5ui';
  import { useKbd } from 'sv5ui';

  let open = $state(false);

  useKbd({
    shortcuts: {
      'ctrl+k': () => open = !open
    }
  });
</script>

<Button variant="outline" color="surface" onclick={() => open = true}>
  Search...
  {#snippet trailingSlot()}
    <Kbd value="ctrl" size="sm" /> <Kbd value="K" size="sm" />
  {/snippet}
</Button>

<Modal bind:open ui={{ content: 'p-0 max-w-lg' }} close={false} title="">
  {#snippet content()}
    <Command {groups} size="sm" />
  {/snippet}
</Modal>

Custom Empty Text

<Command {groups} emptyText="No commands match your search." />

UI Slots

Use the ui prop to override classes on internal elements.

SlotDescription
rootMain container
inputWrapperSearch input wrapper
inputIconSearch icon
inputInput element
listItems list container
emptyEmpty state
loadingLoading state
groupGroup container
groupHeadingGroup heading text
separatorDivider between groups
itemIndividual item
itemIconItem leading icon
itemLabelItem label text
itemDescriptionItem description text
itemTrailingItem trailing section
footerFooter container

Snippets

SnippetDescription
itemCustom item rendering (receives item, index)
itemLeadingCustom leading section (icon area)
itemLabelCustom label section
itemTrailingCustom trailing section
emptyCustom empty state (receives search term)
footerFooter content

Props

PropTypeDefault
groupsCommandGroup[]-
searchstring''
valuestring-
placeholderstring'Type a command...'
size'xs'|'sm'|'md'|'lg'|'xl''md'
iconstring-
loadingbooleanfalse
emptyTextstring'No results found.'
loopboolean-
shouldFilterbooleantrue
onValueChange(value) => void-
refHTMLElement | nullnull
classstring-
uiRecord<Slot, Class>-

Item Props

PropTypeDefault
valuestring-
labelstring-
descriptionstring-
iconstring-
keywordsstring[]-
disabledbooleanfalse
onSelect() => void-
classstring-

Group Props

PropTypeDefault
idstring-
labelstring-
itemsCommandItem[]-