Skip to content

vue-command-palette

Command+K палитра для Vue 3. Нечёткий поиск с подсветкой совпадений, группировка команд, вложенные под-палитры, глобальные горячие клавиши, асинхронный поиск, диалоги подтверждения, история недавних команд и полная headless-кастомизация через слоты — и всего одна peer-зависимость (Vue 3).

Возможности

  • Нечёткий поиск — ранжирование: точное совпадение (100) › префикс (80) › подстрока (60) › нечёткое (1–40). Ищет по label, description, keywords и aliases; подсветка label сохраняется, даже если счёт выиграло другое поле. Нормализация диакритики, так что café совпадает с cafe. Подсветка совпадений через <mark>.
  • Подключаемый поиск — замените встроенный скорер на свой (например, Fuse.js) через опцию search.
  • Привязываемые горячие клавишиbindShortcuts: true превращает shortcut каждой команды в настоящую глобальную горячую клавишу.
  • Поиск по вложенным командам — под-команды напрямую всплывают в поиске с хлебными крошками (Change Theme › Light); шеврон отмечает пункты, открывающие под-палитру/страницу.
  • Страницы команд — команда может открыть page со своим плейсхолдером и асинхронным поиском (фильтры, удалённые пикеры, многошаговые сценарии).
  • Множественные инстансы — запустите несколько независимых именованных палитр в одном приложении через createCommandPalette().
  • Вид «все команды» — палитра при открытии показывает все зарегистрированные команды по группам; никакого пустого экрана.
  • Группировка команд — группы с заголовками, приоритетным порядком и визуальными разделителями секций.
  • Недавние команды — история последних N выполненных команд на основе localStorage, показывается сверху при пустом запросе.
  • Вложенные палитрыsubCommands открывает дочернюю палитру с хлебными крошками; Backspace / Esc возвращают назад.
  • Асинхронный поискonSearch: (query) => Promise<Command[]> на группу, с debounce 200 мс, объединяется с синхронными результатами.
  • Шаг подтвержденияconfirm: string показывает диалог да/нет перед выполнением команды.
  • Состояние загрузки — спиннер на пункте, пока выполняется асинхронный perform().
  • Guard enabled() — динамическая доступность команды, вычисляется на каждом цикле рендера.
  • Алиасы и ключевые слова — ищутся наравне с label; алиасы дают тот же счёт, что и совпадение по label.
  • Глобальный менеджер клавиатуры$mod (⌘ на macOS, Ctrl на Windows/Linux), комбинации модификаторов, последовательности голых клавиш (gh в пределах 500 мс).
  • Headless-слоты#trigger, #header, #input, #item, #group-header, #empty, #footer для полного контроля над UI.
  • 20+ CSS custom properties — полная кастомизация темы без изменения исходного кода. Автоматическая тёмная тема через prefers-color-scheme.
  • Кастомный скроллбар — тонкий 4-пиксельный скроллбар, стилизованный под тему палитры.
  • Виртуальный список — собственная реализация для наборов результатов > 50 элементов, без дополнительных зависимостей.
  • Модуль Nuxt — автоматически устанавливает плагин через nuxt.config.ts.
  • Утилиты для тестированияcreatePaletteContext + PaletteProvider для изолированных юнит-тестов.
  • SSR-безопасность — все обращения к браузерным API защищены проверкой typeof document !== 'undefined'.
  • Ноль runtime-зависимостей — только Vue 3 как peer-зависимость. ~11 КБ gzip.

Установка

bash
npm install @macrulez/vue-command-palette

Peer-зависимость:

bash
npm install vue@>=3.3

Быстрый старт

1. Установите плагин

ts
// main.ts
import { createApp } from 'vue'
import { VCommandPalettePlugin } from '@macrulez/vue-command-palette'
import '@macrulez/vue-command-palette/style.css'
import App from './App.vue'

const app = createApp(App)

app.use(VCommandPalettePlugin, {
  hotkey: ['$mod', 'k'], // Cmd+K на macOS, Ctrl+K на Windows/Linux
  colorTheme: 'system', // 'light' | 'dark' | 'system'
  persistRecent: true,
  maxRecent: 5,
})

app.mount('#app')

2. Разместите CommandPalette в любом месте дерева компонентов

vue
<script setup lang="ts">
import { CommandPalette, useRegisterGroup } from '@macrulez/vue-command-palette'

useRegisterGroup({
  id: 'navigation',
  label: 'Navigation',
  priority: 100,
  commands: [
    {
      id: 'go-home',
      label: 'Go to Home',
      icon: '🏠',
      perform: () => router.push('/'),
    },
    {
      id: 'go-settings',
      label: 'Settings',
      icon: '⚙️',
      shortcut: ['$mod', ','],
      perform: () => router.push('/settings'),
    },
  ],
})
</script>

<template>
  <RouterView />
  <CommandPalette placeholder="Search commands…" :max-results="12" />
</template>

Нажмите Cmd+K / Ctrl+K, чтобы открыть.