Компоненты
CommandPalette
Палитра команд по ⌘K с локальными пунктами и серверным поиском.
Палитра команд по ⌘K: переход к разделам, поиск по данным и запуск действий одним полем ввода.
Попробовать
Стрелками список листается, Enter открывает, Escape закрывает. Наведение мышью двигает тот же курсор, что и клавиатура, — они не спорят за выбор.
Локальные пункты
Разделы приложения и команды не требуют запроса — они фильтруются на месте по заголовку и скрытым ключевым словам:
import { CommandPalette } from "@toimetdev/pathlogs-core";
<CommandPalette
items={[
{ id: "dashboard", group: "Навигация", title: "Проекты", hint: "g d",
onSelect: () => router.push("/dashboard") },
{ id: "new", group: "Действия", title: "Новая задача",
keywords: "создать добавить task",
onSelect: () => setNewTaskOpen(true) },
]}
labels={{ placeholder: "Поиск проектов, задач, разделов…", empty: "Ничего не найдено" }}
/>Горячая клавиша по умолчанию — mod+k. Палитра вешает её сама; передайте hotkey={null}, если управляете открытием снаружи.
Поиск на сервере
Всё, чего нет на клиенте, отдаёт функция search. Она вызывается с задержкой после ввода — пока пользователь печатает, промежуточные подстроки никому не нужны:
<CommandPalette
items={navItems}
search={async (query) => {
const { projects, tasks } = await searchAction(query);
return [
...projects.map((p) => ({
id: `p:${p.id}`, group: "Проекты", title: p.name, badge: p.key,
onSelect: () => router.push(`/projects/${p.id}`),
})),
...tasks.map((t) => ({
id: `t:${t.id}`, group: "Задачи", title: t.title,
badge: `${t.projectKey}-${t.number}`,
onSelect: () => router.push(`/tasks/${t.id}`),
})),
];
}}
/>Пропсы
| Проп | Тип | По умолчанию | Описание |
|---|---|---|---|
items | CommandItem[] | [] | Пункты, доступные без запроса. Фильтруются по title и keywords. |
search | (query: string) => Promise<CommandItem[]> | — | Источник результатов с сервера. |
debounce | number | 150 | Задержка перед запросом, мс. |
hotkey | string | null | "mod+k" | Клавиша открытия. null — только внешнее управление. |
open / onOpenChange | boolean / (open: boolean) => void | — | Внешнее управление. Без них палитра держит состояние сама. |
labels | { placeholder, empty, navigate, select } | — | Подписи. По умолчанию английские. |
itemsCommandItem[]по умолчанию: []
Пункты, доступные без запроса. Фильтруются по title и keywords.
search(query: string) => Promise<CommandItem[]>Источник результатов с сервера.
debouncenumberпо умолчанию: 150
Задержка перед запросом, мс.
hotkeystring | nullпо умолчанию: "mod+k"
Клавиша открытия. null — только внешнее управление.
open / onOpenChangeboolean / (open: boolean) => voidВнешнее управление. Без них палитра держит состояние сама.
labels{ placeholder, empty, navigate, select }Подписи. По умолчанию английские.
Пункт списка:
interface CommandItem {
id: string;
title: string;
group?: string; // заголовок раздела; пункты группируются в порядке следования
badge?: string; // короткая метка слева: ключ проекта, номер задачи
hint?: string; // подсказка справа: горячая клавиша пункта
icon?: ReactNode;
keywords?: string; // дополнительный текст для поиска, не показывается
onSelect: () => void;
}