---
title: "CommandPalette"
description: "An overlay for searching and running commands."
category: Advanced
status: beta
since: 0.3.4
tags: [command, palette, launcher, shortcut]
syncStatus: reviewed
verified: true
---

## Usage

### Launcher
::TuffDemoWrapper{demo="CommandPaletteCommandPaletteDemo" code-lang="vue"}
---
code: |
  <script setup lang="ts">
  import { ref } from 'vue'

  const open = ref(false)
  const commands = [
    {
      id: 'search-files',
      title: 'Search Files',
      description: 'Find local files across Documents, Downloads, and Desktop',
      keywords: ['file', 'finder', 'everything'],
      icon: 'i-carbon-search',
      shortcut: '⌘ K',
    },
    { id: 'locked-admin', title: 'Admin Script', icon: 'i-carbon-locked', disabled: true },
  ]
  </script>

  <template>
    <TxButton variant="primary" @click="open = true">Open command palette</TxButton>
    <TxCommandPalette
      v-model="open"
      :commands="commands"
      placeholder="Search commands, plugins, or settings..."
      empty-text="No matching commands"
      :max-height="280"
      @select="(item) => run(item.id)"
    />
  </template>
---
::

### Best Practices

- Keep `id` stable across releases, and use it — not the localized title — for analytics, persistence, and permission checks.
- Put synonyms, aliases, and plugin names in `keywords` instead of duplicating commands for search variants.
- Register global shortcuts in the app shell, then open the palette through `v-model`.
- Use `footer` for sources, result counts, or keyboard help; use `empty` to show the query and a recovery action.
- Cap `maxHeight` for long command sets so the palette stays inside the viewport.

## API Reference

### Props

| Name | Type | Default | Description |
|------|------|------|------|
| `modelValue` | `boolean` | - | Whether the palette is shown, bound with `v-model`. |
| `commands` | `CommandPaletteItem[]` | `[]` | The commands. |
| `placeholder` | `string` | `'Search commands'` | Search placeholder; also the input's `aria-label`. |
| `emptyText` | `string` | `'No commands found'` | Text shown when nothing matches. |
| `maxHeight` | `number` | `320` | Maximum list height in px. |
| `autoFocus` | `boolean` | `true` | Focuses the search input on open. |
| `closeOnSelect` | `boolean` | `true` | Closes after a selection; set `false` for batch actions. |
| `overlayClass` | `string \| string[] \| Record<string, boolean>` | - | Class for the overlay. |
| `panelClass` | `string \| string[] \| Record<string, boolean>` | - | Class for the panel. |
| `query` | `string` | - | Search text for `v-model:query`; omit to let the palette manage it. |
| `ariaLabel` | `string` | `'Command palette'` | Accessible name of the dialog and command list. |

### Events

| Event | Payload | Description |
|------|------|------|
| `update:modelValue` | `(value)` | Fires when the palette asks to open or close. |
| `select` | `(item)` | Fires with the original item when an enabled command is chosen. |
| `open` | - | Fires when the palette opens. |
| `close` | - | Fires when an open palette closes. |
| `update:query` | `(value)` | Fires on input; resets to an empty string on close. |

### Slots

| Slot | Props | Description |
|------|------|------|
| `empty` | `{ query, emptyText }` | Content shown when nothing matches. |
| `footer` | `{ query, visibleCount }` | Area below the list. |

### Types

#### CommandPaletteItem

| Field | Type | Description |
|------|------|------|
| `id` | `string` | Unique id. |
| `title` | `string` | Title; searched. |
| `description` | `string` | Line under the title; searched. |
| `keywords` | `string[]` | Extra search terms; not displayed. |
| `icon` | `TxIconSource \| string` | Icon source or icon class. |
| `shortcut` | `string` | Shortcut hint on the right; registers nothing. |
| `disabled` | `boolean` | Stays visible but can't be selected. |

## Overview

- Visibility comes only from `modelValue`. The palette emits `open` when shown and `close` when an open palette is dismissed.
- Filtering is a local, case-insensitive substring match over `title`, `description`, and `keywords`; there is no ranking, debouncing, or remote fetch.
- `ArrowDown` / `ArrowUp` cycle and skip disabled commands, `Enter` selects, `Escape` closes. The highlight starts on the first enabled command.
- Keyboard selection is ignored during IME composition, so Chinese, Japanese, and Korean input is not submitted early.
- The overlay is `role="dialog"` with `aria-modal="true"`; disabled commands carry `aria-disabled="true"` and never emit `select`.

## Technologies

- Source: `packages/tuffex/packages/components/src/command-palette/`.

<TuffDocSourceLink />
