Skip to content

Command Palette

v0.2.9UI-компонентыVueNuxt

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

Command Palette
Начать знакомство →
npm install @macrulez/vue-command-palette@latest
01 — Назначение

Когда это пригодится

Cmd+K давно стало ожидаемым паттерном в рабочих инструментах — vue-command-palette даёт готовую, полностью кастомизируемую реализацию вместо того, чтобы собирать поиск, клавиатурную навигацию и подсветку совпадений с нуля.

Действия разбросаны по всему интерфейсу

Настройки — в одном углу, экспорт — в другом, переключение темы — в третьем; палитра команд собирает всё это в одном месте, доступном с клавиатуры без похода по меню.

Команда требует уточнения перед запуском

«Назначить исполнителя» не может просто выполниться — сначала нужно найти человека; вложенная страница со своим асинхронным поиском решает это без отдельного модального окна.

Деструктивная команда затерялась среди обычных

«Удалить проект» не должна нажиматься так же легко, как «Открыть настройки» — встроенный шаг подтверждения страхует от случайного клика.

Одни и те же команды нужны каждый день

Вместо того чтобы каждый раз печатать заново, недавние и закреплённые команды поднимаются наверх при пустом запросе, а те, что вы используете чаще всего, со временем поднимаются в списке ещё выше.

02 — Фичи

Коротко о главном

Нечёткий поиск и навигация по командам

Нечёткий поиск и навигация по командам

Мгновенный поиск с ранжированием (точное совпадение, префикс, подстрока, нечёткое), подсветкой совпадений и нормализацией диакритики. Группировка команд с заголовками, вложенные подпалитры любой глубины и страницы с собственным асинхронным поиском.

Глобальные горячие клавиши и шорткаты

Глобальные горячие клавиши и шорткаты

Встроенный менеджер клавиатуры поддерживает модификаторы ($mod, shift, alt, ctrl, meta) и последовательности из двух клавиш. Привязывайте шорткаты к командам или используйте их отдельно. Команды с shortcut автоматически регистрируются как глобальные хоткеи.

Динамические команды и асинхронный поиск

Динамические команды и асинхронный поиск

Группы и страницы могут загружать команды по запросу через onSearch с дебаунсом 200 мс. Встроенная поддержка состояний загрузки, динамическое включение/отключение команд через enabled(), асинхронное выполнение с индикатором прогресса и обработка ошибок.

Персонализация: недавние, закреплённые, frecency

Персонализация: недавние, закреплённые, frecency

История выполненных команд сохраняется в localStorage и показывается при пустом запросе. Закрепляйте избранные команды, а frecency (частота + свежесть) поднимает часто используемые команды в результатах поиска. История запросов доступна через Alt+↑/↓.

Полная кастомизация, Vue/Nuxt и SSR

Полная кастомизация, Vue/Nuxt и SSR

Headless-слоты для полного контроля над UI, 20+ CSS-переменных для темизации, встроенная светлая/тёмная тема. Готовые хуки для Vue 3 и Nuxt-модуль. Все API безопасны для SSR, а утилиты тестирования упрощают юнит-тесты. Единственная зависимость — Vue 3.

Виртуальный список и множественные палитры

Виртуальный список и множественные палитры

Список результатов рендерится через виртуальный скроллинг — даже палитра с сотнями команд остаётся плавной. Создавайте несколько независимых экземпляров через createCommandPalette(), а для деструктивных команд используйте встроенный шаг подтверждения.

03 — Быстрый пример

Как это работает

Навигация двумя клавишами, как на GitHub

Две клавиши подряд без модификаторов — g, затем h — в окне 500 мс. registerShortcut сам разбирает такие последовательности.

shortcuts.ts
import { createKeyboardManager } from '@macrulez/vue-command-palette'

const km = createKeyboardManager()
km.start()

km.registerShortcut(['g', 'h'], () => router.push('/home'))
km.registerShortcut(['g', 'p'], () => router.push('/projects'))
km.registerShortcut(['g', 's'], () => router.push('/settings'))

// Two bare keys, no modifier, pressed within a 500ms window — the same
// "g then h" navigation pattern as GitHub's own keyboard shortcuts.

Вложенные палитры находятся поиском напрямую

subCommands открывает дочернюю палитру по выбору, а запрос "light" сразу находит команду внутри — с хлебной крошкой «Change Theme › Light», без захода в подменю.

nested-palette.ts
const changeTheme = {
  id: 'change-theme',
  label: 'Change Theme',
  icon: '🎨',
  subCommands: [
    { id: 'theme-light', label: 'Light', icon: '☀️', perform: () => (theme.value = 'light') },
    { id: 'theme-dark', label: 'Dark', icon: '🌙', perform: () => (theme.value = 'dark') },
    { id: 'theme-system', label: 'System', icon: '💻', perform: () => (theme.value = 'system') },
  ],
}

// With searchNested (on by default), typing "light" finds the command
// inside the sub-palette directly — shown with a breadcrumb, "Change
// Theme › Light" — no need to open "Change Theme" first.

Асинхронный поиск по внешним источникам

onSearch у группы дёргает любой API — документацию, базу, поиск — с дебаунсом 200 мс, а результаты сливаются с обычными и пересортировываются по релевантности.

async-search.ts
import { useRegisterGroup } from '@macrulez/vue-command-palette'

useRegisterGroup({
  id: 'docs-search',
  label: 'Documentation',
  commands: [],
  onSearch: async (query) => {
    const results = await searchDocs(query)
    return results.slice(0, 5).map((doc) => ({
      id: `doc-${doc.slug}`,
      label: doc.title,
      description: doc.excerpt,
      icon: '📄',
      perform: () => window.open(doc.url, '_blank'),
    }))
  },
})

// Debounced 200ms, merged with the synchronous results and re-sorted by
// score — already-shown results stay visible while the request is in flight.