Skip to content

Интеграции и тестирование

Множественные инстансы

Запускайте несколько независимых палитр в одном приложении — например, глобальную командную строку плюс поиск в сайдбаре — каждую со своей горячей клавишей, командами и состоянием. Используйте createCommandPalette() для каждого инстанса, кроме дефолтного (она возвращает новый объект плагина, чтобы дедупликация app.use во Vue его не пропустила).

ts
import { VCommandPalettePlugin, createCommandPalette } from '@macrulez/vue-command-palette'

app.use(VCommandPalettePlugin) // инстанс по умолчанию
app.use(createCommandPalette({ name: 'sidebar', hotkey: ['$mod', 'j'] }))
vue
<template>
  <!-- по умолчанию -->
  <CommandPalette />
  <!-- sidebar -->
  <CommandPalette name="sidebar" placeholder="Search the sidebar…" />
</template>

Обращайтесь к конкретному инстансу из composables через аргумент name:

ts
const sidebar = useCommandPalette('sidebar')
useRegisterCommands([/* … */], 'sidebar')
useRegisterGroup({/* … */}, 'sidebar')

Nuxt

Добавьте в nuxt.config.ts:

ts
export default defineNuxtConfig({
  modules: ['@macrulez/vue-command-palette/nuxt'],
})

Опции читаются из runtimeConfig.public.vCommandPalette. Настройте в nuxt.config.ts:

ts
export default defineNuxtConfig({
  modules: ['@macrulez/vue-command-palette/nuxt'],
  runtimeConfig: {
    public: {
      vCommandPalette: {
        hotkey: ['$mod', 'k'],
        persistRecent: true,
        maxRecent: 5,
      },
    },
  },
})

Модуль Nuxt устанавливает плагин автоматически. useCommandPalette, useRegisterGroup и useRegisterCommands доступны во всех компонентах без явных импортов (при использовании @nuxt/eslint с включёнными автоимпортами).

Утилиты для тестирования

ts
import { createPaletteContext, PaletteProvider } from '@macrulez/vue-command-palette/testing'

createPaletteContext

Создаёт полностью изолированный контекст палитры — без реального DOM, без плагина, без побочных эффектов localStorage:

ts
import { createPaletteContext } from '@macrulez/vue-command-palette/testing'
import { mount } from '@vue/test-utils'
import { describe, it, expect, vi } from 'vitest'
import MyComponent from './MyComponent.vue'

describe('MyComponent', () => {
  it('executes the command', async () => {
    const performFn = vi.fn()

    const { provide, isOpen, query, store } = createPaletteContext({
      commands: [{ id: 'test-cmd', label: 'Test Command', perform: performFn }],
    })

    const wrapper = mount(MyComponent, {
      global: { provide },
    })

    // Взаимодействие
    query.value = 'test'
    await wrapper.find('[data-testid="item"]').trigger('click')

    expect(performFn).toHaveBeenCalledOnce()
  })
})

PaletteProvider

Компонент-обёртка, предоставляющий контекст своим дочерним элементам слота — полезен для тестов дерева компонентов:

ts
import { PaletteProvider } from '@macrulez/vue-command-palette/testing'
import { mount } from '@vue/test-utils'

const wrapper = mount(PaletteProvider, {
  props: {
    commands: [{ id: 'cmd', label: 'My Command', perform: vi.fn() }],
    groups: [],
  },
  slots: {
    default: MyConsumerComponent,
  },
})

Опции createPaletteContext

ОпцияТипПо умолчаниюОписание
commandsCommand[][]Команды для предварительной регистрации (без группы)
groupsCommandGroup[][]Группы для предварительной регистрации
persistRecentbooleanfalseВключить персистентность в localStorage
maxRecentnumber5Лимит недавних команд
maxRecentPerGroupnumber0Лимит недавних на группу
localStorageKeystring'vcp:recent:test'Ключ, если persistRecent равен true
onOpen() => voidМок-колбэк для событий открытия
onClose() => voidМок-колбэк для событий закрытия
onError(err, cmd) => voidМок-обработчик ошибок

Возвращаемое значение

ts
const {
  ctx, // полный PaletteContext — передавайте в код на основе inject
  store, // CommandStore — регистрируйте/ищите команды напрямую
  isOpen, // Ref<boolean>
  query, // Ref<string>
  activeIndex, // Ref<number>
  provide, // объект для Vue Test Utils `global: { provide }`
} = createPaletteContext(options)