Command

A command menu component that can be used to search, filter, and select items.

	<script lang="ts">
  import { Command } from "bits-ui";
  import Sticker from "phosphor-svelte/lib/Sticker";
  import CodeBlock from "phosphor-svelte/lib/CodeBlock";
  import Palette from "phosphor-svelte/lib/Palette";
  import CalendarBlank from "phosphor-svelte/lib/CalendarBlank";
  import RadioButton from "phosphor-svelte/lib/RadioButton";
  import Textbox from "phosphor-svelte/lib/Textbox";
</script>
 
<Command.Root
  class="flex h-full w-full flex-col divide-y divide-border self-start overflow-hidden rounded-xl border border-muted bg-background"
>
  <Command.Input
    class="focus-override inline-flex h-input w-[296px] truncate rounded-xl bg-background px-4 text-sm transition-colors placeholder:text-foreground-alt/50 focus:outline-none focus:ring-0"
    placeholder="Search for something..."
  />
  <Command.List
    class="max-h-[280px] overflow-y-auto overflow-x-hidden px-2 pb-2"
  >
    <Command.Viewport>
      <Command.Empty
        class="flex w-full items-center justify-center pb-6 pt-8 text-sm text-muted-foreground"
      >
        No results found.
      </Command.Empty>
      <Command.Group>
        <Command.GroupHeading
          class="px-3 pb-2 pt-4 text-xs text-muted-foreground"
        >
          Suggestions
        </Command.GroupHeading>
        <Command.GroupItems>
          <Command.Item
            class="flex h-10 cursor-pointer select-none items-center gap-2 rounded-button px-3 py-2.5 text-sm capitalize outline-none data-[selected]:bg-muted"
            keywords={["getting started", "tutorial"]}
          >
            <Sticker class="size-4" />
            Introduction
          </Command.Item>
          <Command.Item
            class="flex h-10 cursor-pointer select-none items-center gap-2 rounded-button px-3 py-2.5 text-sm capitalize outline-none data-[selected]:bg-muted"
            keywords={["child", "custom element", "snippets"]}
          >
            <CodeBlock class="size-4 " />
            Delegation
          </Command.Item>
          <Command.Item
            class="flex h-10 cursor-pointer select-none items-center gap-2 rounded-button px-3 py-2.5 text-sm capitalize outline-none data-[selected]:bg-muted"
            keywords={["css", "theme", "colors", "fonts", "tailwind"]}
          >
            <Palette class="size-4" />
            Styling
          </Command.Item>
        </Command.GroupItems>
      </Command.Group>
      <Command.Separator />
      <Command.Group>
        <Command.GroupHeading
          class="px-3 pb-2 pt-4 text-xs text-muted-foreground"
        >
          Components
        </Command.GroupHeading>
        <Command.GroupItems>
          <Command.Item
            class="flex h-10 cursor-pointer select-none items-center gap-2 rounded-button px-3 py-2.5 text-sm capitalize outline-none data-[selected]:bg-muted"
            keywords={["dates", "times"]}
          >
            <CalendarBlank class="size-4" />
            Calendar
          </Command.Item>
          <Command.Item
            class="flex h-10 cursor-pointer select-none items-center gap-2 rounded-button px-3 py-2.5 text-sm capitalize outline-none data-[selected]:bg-muted"
            keywords={["buttons", "forms"]}
          >
            <RadioButton class="size-4" />
            Radio Group
          </Command.Item>
          <Command.Item
            class="flex h-10 cursor-pointer select-none items-center gap-2 rounded-button px-3 py-2.5 text-sm capitalize outline-none data-[selected]:bg-muted"
            keywords={["inputs", "text", "autocomplete"]}
          >
            <Textbox class="size-4" />
            Combobox
          </Command.Item>
        </Command.GroupItems>
      </Command.Group>
    </Command.Viewport>
  </Command.List>
</Command.Root>

Overview

The Command component, also known as a command menu, is designed to provide users with a quick and efficient way to search, filter, and select items within an application. It combines the functionality of a search input with a dynamic, filterable list of commands or options, making it ideal for applications that require fast navigation or action execution.

Key Features

  • Dynamic Filtering: As users type in the input field, the list of commands or items is instantly filtered and sorted based on an (overridable) scoring algorithm.
  • Keyboard Navigation: Full support for keyboard interactions, allowing users to quickly navigate and select items without using a mouse.
  • Grouped Commands: Ability to organize commands into logical groups, enhancing readability and organization.
  • Empty and Loading States: Built-in components to handle scenarios where no results are found or when results are being loaded.
  • Accessibility: Designed with ARIA attributes and keyboard interactions to ensure screen reader compatibility and accessibility standards.

Architecture

The Command component is composed of several subcomponents, each with a specific role:

  • Root: The main container that manages the overall state and context of the command menu.
  • Input: The text input field where users can type to search or filter commands.
  • List: The container for the list of commands or items.
  • Viewport: The visible area of the command list, which applies CSS variables to handle dynamic resizing/animations based on the height of the list.
  • Empty: A component to display when no results are found.
  • Loading: A component to display while results are being fetched or processed.
  • Group: A container for a group of items within the command menu.
  • GroupHeading: A header element to provide an accessible label for a group of items.
  • GroupItems: A container for the items within a group.
  • Item: Individual selectable command or item.
  • LinkItem: A variant of Command.Item specifically for link-based actions.
  • Separator: A visual separator to divide different sections of the command list.

Structure

Here's an overview of how the Command component is structured in code:

	<script lang="ts">
	import { Combobox } from "bits-ui";
</script>
 
<Command.Root>
	<Combobox.Input />
	<Command.List>
		<Command.Viewport>
			<Command.Empty />
			<Command.Loading />
			<Command.Group>
				<Command.GroupHeading />
				<Command.GroupItems>
					<Command.Item />
					<Command.LinkItem />
				</Command.GroupItems>
			</Command.Group>
			<Command.Separator />
			<Command.Item />
			<Command.LinkItem />
		</Command.Viewport>
	</Command.List>
</Command.Root>

Managing Value State

Bits UI offers several approaches to manage and synchronize the Command's value state, catering to different levels of control and integration needs.

1. Two-Way Binding

For seamless state synchronization, use Svelte's bind:value directive. This method automatically keeps your local state in sync with the component's internal state.

	<script lang="ts">
	import { Command } from "bits-ui";
	let myValue = $state("");
</script>
 
<button onclick={() => (myValue = "A")}> Select A </button>
 
<Command.Root bind:value={myValue}>
	<!-- ... -->
</Command.Root>

Key Benefits

  • Simplifies state management
  • Automatically updates myValue when the internal state changes (e.g., via clicking on an item)
  • Allows external control (e.g., selecting an item via a separate button)

2. Change Handler

For more granular control or to perform additional logic on state changes, use the onValueChange prop. This approach is useful when you need to execute custom logic alongside state updates.

	<script lang="ts">
	import { Command } from "bits-ui";
	let myValue = $state("");
</script>
 
<Command.Root
	value={myValue}
	onValueChange={(value) => {
		myValue = value;
		// additional logic here.
	}}
>
	<!-- ... -->
</Command.Root>

Use Cases

  • Implementing custom behaviors on value change
  • Integrating with external state management solutions
  • Triggering side effects (e.g., logging, data fetching)

3. Fully Controlled

For complete control over the component's value state, use the controlledValue prop. This approach requires you to manually manage the value state, giving you full control over when and how the component responds to value change events.

To implement controlled state:

  1. Set the controlledValue prop to true on the Command.Root component.
  2. Provide a value prop to Command.Root, which should be a variable holding the current state.
  3. Implement an onValueChange handler to update the state when the internal state changes.
	<script lang="ts">
	import { Command } from "bits-ui";
	let myValue = $state("");
</script>
 
<Command.Root controlledValue value={myValue} onValueChange={(v) => (myValue = v)}>
	<!-- ... -->
</Command.Root>

When to Use

  • Implementing complex value change logic
  • Coordinating multiple UI elements
  • Debugging state-related issues

In a Modal

You can combine the Command component with the Dialog component to display the command menu within a modal.


	<script lang="ts">
  import { Command, Dialog } from "bits-ui";
  import Sticker from "phosphor-svelte/lib/Sticker";
  import CodeBlock from "phosphor-svelte/lib/CodeBlock";
  import Palette from "phosphor-svelte/lib/Palette";
  import CalendarBlank from "phosphor-svelte/lib/CalendarBlank";
  import RadioButton from "phosphor-svelte/lib/RadioButton";
  import Textbox from "phosphor-svelte/lib/Textbox";
 
  let dialogOpen = $state(false);
 
  function handleKeydown(e: KeyboardEvent) {
    if (e.key === "j" && (e.metaKey || e.ctrlKey)) {
      e.preventDefault();
      dialogOpen = true;
    }
  }
</script>
 
<svelte:document onkeydown={handleKeydown} />
 
<Dialog.Root bind:open={dialogOpen}>
  <Dialog.Trigger
    class="inline-flex h-12 select-none
	items-center justify-center whitespace-nowrap rounded-input bg-dark px-[21px]
	text-[15px] font-semibold text-background shadow-mini transition-colors hover:bg-dark/95 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-foreground focus-visible:ring-offset-2 focus-visible:ring-offset-background active:scale-98"
  >
    Open Command Menu ⌘J
  </Dialog.Trigger>
  <Dialog.Portal>
    <Dialog.Overlay
      class="fixed inset-0 z-50 bg-black/80 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0"
    />
    <Dialog.Content
      class="fixed left-[50%] top-[50%] z-50 w-full max-w-[94%] translate-x-[-50%] translate-y-[-50%] rounded-card-lg  bg-background shadow-popover outline-none data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[state=closed]:slide-out-to-left-1/2 data-[state=closed]:slide-out-to-top-[48%] data-[state=open]:slide-in-from-left-1/2 data-[state=open]:slide-in-from-top-[48%] sm:max-w-[490px] md:w-full"
    >
      <Dialog.Title class="sr-only">Command Menu</Dialog.Title>
      <Dialog.Description class="sr-only">
        This is the command menu. Use the arrow keys to navigate and press ⌘K to
        open the search bar.
      </Dialog.Description>
      <Command.Root
        class="flex h-full w-full flex-col divide-y divide-border self-start overflow-hidden rounded-xl border border-muted bg-background"
      >
        <Command.Input
          class="focus-override inline-flex h-input w-[296px] truncate rounded-xl bg-background px-4 text-sm transition-colors placeholder:text-foreground-alt/50 focus:outline-none focus:ring-0"
          placeholder="Search for something..."
        />
        <Command.List
          class="max-h-[280px] overflow-y-auto overflow-x-hidden px-2 pb-2"
        >
          <Command.Viewport>
            <Command.Empty
              class="flex w-full items-center justify-center pb-6 pt-8 text-sm text-muted-foreground"
            >
              No results found.
            </Command.Empty>
            <Command.Group>
              <Command.GroupHeading
                class="px-3 pb-2 pt-4 text-xs text-muted-foreground"
              >
                Suggestions
              </Command.GroupHeading>
              <Command.GroupItems>
                <Command.Item
                  class="flex h-10 cursor-pointer select-none items-center gap-2 rounded-button px-3 py-2.5 text-sm capitalize outline-none data-[selected]:bg-muted"
                  keywords={["getting started", "tutorial"]}
                >
                  <Sticker class="size-4" />
                  Introduction
                </Command.Item>
                <Command.Item
                  class="flex h-10 cursor-pointer select-none items-center gap-2 rounded-button px-3 py-2.5 text-sm capitalize outline-none data-[selected]:bg-muted"
                  keywords={["child", "custom element", "snippets"]}
                >
                  <CodeBlock class="size-4 " />
                  Delegation
                </Command.Item>
                <Command.Item
                  class="flex h-10 cursor-pointer select-none items-center gap-2 rounded-button px-3 py-2.5 text-sm capitalize outline-none data-[selected]:bg-muted"
                  keywords={["css", "theme", "colors", "fonts", "tailwind"]}
                >
                  <Palette class="size-4" />
                  Styling
                </Command.Item>
              </Command.GroupItems>
            </Command.Group>
            <Command.Separator />
            <Command.Group>
              <Command.GroupHeading
                class="px-3 pb-2 pt-4 text-xs text-muted-foreground"
              >
                Components
              </Command.GroupHeading>
              <Command.GroupItems>
                <Command.Item
                  class="flex h-10 cursor-pointer select-none items-center gap-2 rounded-button px-3 py-2.5 text-sm capitalize outline-none data-[selected]:bg-muted"
                  keywords={["dates", "times"]}
                >
                  <CalendarBlank class="size-4" />
                  Calendar
                </Command.Item>
                <Command.Item
                  class="flex h-10 cursor-pointer select-none items-center gap-2 rounded-button px-3 py-2.5 text-sm capitalize outline-none data-[selected]:bg-muted"
                  keywords={["buttons", "forms"]}
                >
                  <RadioButton class="size-4" />
                  Radio Group
                </Command.Item>
                <Command.Item
                  class="flex h-10 cursor-pointer select-none items-center gap-2 rounded-button px-3 py-2.5 text-sm capitalize outline-none data-[selected]:bg-muted"
                  keywords={["inputs", "text", "autocomplete"]}
                >
                  <Textbox class="size-4" />
                  Combobox
                </Command.Item>
              </Command.GroupItems>
            </Command.Group>
          </Command.Viewport>
        </Command.List>
      </Command.Root>
    </Dialog.Content>
  </Dialog.Portal>
</Dialog.Root>

Filtering

Custom Filter

By default, the Command component uses a scoring algorithm to determine how the items should be sorted/filtered. You can provide a custom filter function to override this behavior.

The function should return a number between 0 and 1, with 1 being a perfect match, and 0 being no match, resulting in the item being hidden entirely.

The following example shows how you might implement a strict substring match filter:

	<script lang="ts">
	import { Command } from "bits-ui";
 
	function customFilter(value: string, search: string, keywords?: string[]): number {
		return value.includes(search) ? 1 : 0;
	}
</script>
 
<Command.Root filter={customFilter}>
	<!-- ... -->
</Command.Root>

Disable Filtering

You can disable filtering by setting the shouldFilter prop to false.

	<Command.Root shouldFilter={false}>
	<!-- ... -->
</Command.Root>

This is useful when you have a lot of custom logic, need to fetch items asynchronously, or just want to handle filtering yourself. You'll be responsible for iterating over the items and determining which ones should be shown.

Item Selection

You can use the onSelect prop to handle the selection of items.

	<Command.Item onSelect={() => console.log("selected something!")} />

If you want one of the items to get all the benefits of a link (prefetching, etc.), you should use the Command.LinkItem component instead of the Command.Item component. The only difference is that the Command.LinkItem component will render an a element instead of a div element.

	<Command.LinkItem href="/some/path">
	<!-- ... -->
</Command.LinkItem>

API Reference

Command.Root

The main container that manages the overall state and context of the component.

Property Type Description
value $bindable
string

The value of the command.

Default: undefined
onValueChange
function

A callback that is fired when the command value changes.

Default: undefined
controlledValue
boolean

Whether or not the value is controlled or not. If true, the component will not update the value state internally, instead it will call onValueChange when it would have otherwise, and it is up to you to update the value prop that is passed to the component.

Default: false
label
string

An accessible label for the command menu. This is not visible and is only used for screen readers.

Default: undefined
filter
function

A custom filter function used to filter items. This function should return a number between 0 and 1, with 1 being a perfect match, and 0 being no match, resulting in the item being hidden entirely. The items are sorted/filtered based on this score.

Default: undefined
shouldFilter
boolean

Whether or not the command menu should filter items. This is useful when you want to apply custom filtering logic outside of the Command component.

Default: true
loop
boolean

Whether or not the command menu should loop through items when navigating with the keyboard.

Default: false
disablePointerSelection
boolean

Set this to true to prevent items from being selected when the users pointer moves over them.

Default: false
vimBindings
boolean

Whether VIM bindings should be enabled or not, which allow the user to navigate using ctrl+n/j/p/k

Default: true
ref $bindable
HTMLDivElement

The underlying DOM element being rendered. You can bind to this to get a reference to the element.

Default: undefined
children
Snippet

The children content to render.

Default: undefined
child
Snippet

Use render delegation to render your own element. See delegation docs for more information.

Default: undefined
Data Attribute Value Description
data-command-root
''

Present on the root element.

Command.Input

The text input field where users can type to search or filter commands.

Property Type Description
value $bindable
string

The value of the search query. This is used to filter items and to search for items.

Default: undefined
ref $bindable
HTMLInputElement

The underlying DOM element being rendered. You can bind to this to get a reference to the element.

Default: undefined
children
Snippet

The children content to render.

Default: undefined
child
Snippet

Use render delegation to render your own element. See delegation docs for more information.

Default: undefined
Data Attribute Value Description
data-command-input
''

Present on the input element.

Command.List

The container for the viewport, items, and other elements of the command menu.

Property Type Description
ref $bindable
HTMLDivElement

The underlying DOM element being rendered. You can bind to this to get a reference to the element.

Default: undefined
children
Snippet

The children content to render.

Default: undefined
child
Snippet

Use render delegation to render your own element. See delegation docs for more information.

Default: undefined
Data Attribute Value Description
data-command-list
''

Present on the list element.

CSS Variable Description
--bits-command-list-height

The height of the command list element, which is computed by the Command.Viewport component.

Command.Viewport

The visible area of the command list, which applies CSS variables to handle dynamic resizing/animations based on the height of the list.

Property Type Description
ref $bindable
HTMLDivElement

The underlying DOM element being rendered. You can bind to this to get a reference to the element.

Default: undefined
children
Snippet

The children content to render.

Default: undefined
child
Snippet

Use render delegation to render your own element. See delegation docs for more information.

Default: undefined
Data Attribute Value Description
data-command-viewport
''

Present on the viewport element.

Command.Group

A container for a group of items within the command menu.

Property Type Description
value
string

If a Command.GroupHeading is used within this group, the contents of the heading will be used as the value. If the content is dynamic or you wish to have a more specific value, you can provide a unique value for the group here.

Default: undefined
forceMount
boolean

Whether or not the group should always be mounted to the DOM, regardless of the internal filtering logic

Default: false
ref $bindable
HTMLDivElement

The underlying DOM element being rendered. You can bind to this to get a reference to the element.

Default: undefined
children
Snippet

The children content to render.

Default: undefined
child
Snippet

Use render delegation to render your own element. See delegation docs for more information.

Default: undefined
Data Attribute Value Description
data-command-group
''

Present on the group element.

Command.GroupHeading

A heading element to provide an accessible label for a group of items.

Property Type Description
ref $bindable
HTMLDivElement

The underlying DOM element being rendered. You can bind to this to get a reference to the element.

Default: undefined
children
Snippet

The children content to render.

Default: undefined
child
Snippet

Use render delegation to render your own element. See delegation docs for more information.

Default: undefined
Data Attribute Value Description
data-command-group-heading
''

Present on the group heading element.

Command.GroupItems

The container for the items within a group.

Property Type Description
ref $bindable
HTMLDivElement

The underlying DOM element being rendered. You can bind to this to get a reference to the element.

Default: undefined
children
Snippet

The children content to render.

Default: undefined
child
Snippet

Use render delegation to render your own element. See delegation docs for more information.

Default: undefined
Data Attribute Value Description
data-command-group-items
''

Present on the group items element.

Command.Item

Represents a single item within the command menu. If you wish to render an anchor element to link to a page, use the Command.LinkItem component.

Property Type Description
value required
string

The value of the item.

Default: undefined
keywords
string[]

An array of additional keywords or aliases that will be used to filter the item.

Default: undefined
forceMount
boolean

Whether or not the item should always be mounted to the DOM, regardless of the internal filtering logic

Default: false
onSelect
function

A callback that is fired when the item is selected.

Default: undefined
disabled
boolean

Whether or not the combobox item is disabled. This will prevent interaction/selection.

Default: false
ref $bindable
HTMLDivElement

The underlying DOM element being rendered. You can bind to this to get a reference to the element.

Default: undefined
children
Snippet

The children content to render.

Default: undefined
child
Snippet

Use render delegation to render your own element. See delegation docs for more information.

Default: undefined
Data Attribute Value Description
data-disabled
''

Present when the item is disabled.

data-selected
''

Present when the item is selected.

data-command-item
''

Present on the item element.

Command.LinkItem

Similar to the Command.Item component, but renders an anchor element to take advantage of preloading before navigation.

Property Type Description
value required
string

The value of the item.

Default: undefined
keywords
string[]

An array of additional keywords or aliases that will be used to filter the item.

Default: undefined
forceMount
boolean

Whether or not the item should always be mounted to the DOM, regardless of the internal filtering logic

Default: false
onSelect
function

A callback that is fired when the item is selected.

Default: undefined
disabled
boolean

Whether or not the combobox item is disabled. This will prevent interaction/selection.

Default: false
ref $bindable
HTMLDivElement

The underlying DOM element being rendered. You can bind to this to get a reference to the element.

Default: undefined
children
Snippet

The children content to render.

Default: undefined
child
Snippet

Use render delegation to render your own element. See delegation docs for more information.

Default: undefined
Data Attribute Value Description
data-disabled
''

Present when the item is disabled.

data-selected
''

Present when the item is selected.

data-command-item
''

Present on the item element.

Command.Empty

A component to display when no results are found.

Property Type Description
forceMount
boolean

Whether or not to forcefully mount the empty state, regardless of the internal filtering logic. Useful when you want to handle filtering yourself.

Default: false
ref $bindable
HTMLDivElement

The underlying DOM element being rendered. You can bind to this to get a reference to the element.

Default: undefined
children
Snippet

The children content to render.

Default: undefined
child
Snippet

Use render delegation to render your own element. See delegation docs for more information.

Default: undefined
Data Attribute Value Description
data-command-empty
''

Present on the empty element.

Command.Loading

A component to display while results are being fetched or processed.

Property Type Description
progress
number

The progress of the loading state.

Default: 0
ref $bindable
HTMLDivElement

The underlying DOM element being rendered. You can bind to this to get a reference to the element.

Default: undefined
children
Snippet

The children content to render.

Default: undefined
child
Snippet

Use render delegation to render your own element. See delegation docs for more information.

Default: undefined
Data Attribute Value Description
data-command-loading
''

Present on the loading element.

Command.Separator

A visual separator to divide different sections of the command list. Visible when the search query is empty or the forceMount prop is true.

Property Type Description
forceMount
boolean

Whether or not the separator should always be mounted to the DOM, regardless of the internal filtering logic

Default: false
ref $bindable
HTMLDivElement

The underlying DOM element being rendered. You can bind to this to get a reference to the element.

Default: undefined
children
Snippet

The children content to render.

Default: undefined
child
Snippet

Use render delegation to render your own element. See delegation docs for more information.

Default: undefined
Data Attribute Value Description
data-command-separator
''

Present on the separator element.