- Accordion
- Alert
- Alert Dialog
- Autocomplete
- Auth Surface
- Avatar
- Badge
- Browse Catalog Dialog
- Button
- Card
- Checkbox
- Checkbox Group
- Collapsible
- Combobox
- Command
- Connector Setup Dialog
- Cookie Banner
- Dialog
- Directory Card
- Directory Detail
- Directory Skeleton
- DrawerНовое
- Token Parts Input
- Empty
- Field
- Fieldset
- File Preview Modal
- File Preview Skeleton
- Form
- Frame
- Group
- Icon
- Input
- Input Group
- Kbd
- Label
- Legal Shell
- Menu
- Mermaid Diagram
- Mind Map Diagram
- Not Found Screen
- Onboarding Frame
- Popover
- PDF Thumbnail
- Personalization Landing
- Preview Card
- Pricing Page
- Progress
- Radio Group
- Ring Spinner
- Scroll Area
- Select
- Separator
- Settings Page
- Settings Skills
- Settings Connectors
- Settings Capabilities
- Settings Usage
- Settings Account
- Settings Billing
- Sheet
- Sidebar
- Skeleton
- Skill Create Dialog
- Slider
- Spinner
- Stat
- Switch
- Table
- Tabs
- Textarea
- Toast
- Toggle
- Tooltip
- Компоненты AI
- Chat Conversation
- Chat Message
- Chat Response
- Chat Suggestion
- Chat Prompt Input
- Slash Highlighted Textarea
- Chat Search Dialog
- Chat Skill Doc
- Chat Connector Detail
- Chat Attachments
- Chat File Card
- Chat Token Chip
- Chat Code Block
- Chat Image
- Chat Inline Citation
- Chat Sources
- Chat Web Search
- Chat Research
- Chat Source
- Chat Actions
- Chat Context
- Chat Loader
- Chat Compaction
- Chat Timeline
- Chat Snippet
- Chat Terminal
- Chat Stack Trace
- Chat Test Results
- Chat File Tree
- Chat Environment Variables
- Chat Audio Player
- Chat Transcription
- Chat Speech Input
- Chat Mic Selector
- Chat Voice Selector
- Chat Agent
- Chat Persona
- Chat Connection
- Chat Connector Suggestion
- Chat Queue
- Chat Checkpoint
- Chat Confirmation
- Chat Artifact
- Chat JSX Preview
- Chat Schema Display
- Chat Package Info
- Chat Commit
- Chat Plan
- Chat Open In Chat
- Chat Sandbox
- Chat Model Selector
- Chat Canvas
- Chat Node
- Chat Edge
Command
Компонент командной палитры на основе Dialog и Autocomplete для поиска и выполнения команд.
"use client";
import {
IconArrowDown,
IconArrowUp,
IconCornerDownLeft,
} from "@tabler/icons-react";
import { Fragment, useEffect, useState } from "react";
import { Button } from "@/components/ui/button";
import {
Command,
CommandCollection,
CommandDialog,
CommandDialogPopup,
CommandDialogTrigger,
CommandEmpty,
CommandFooter,
CommandGroup,
CommandGroupLabel,
CommandInput,
CommandItem,
CommandList,
CommandPanel,
CommandSeparator,
CommandShortcut,
} from "@/components/ui/command";
import { Kbd, KbdGroup } from "@/components/ui/kbd";
export interface Item {
value: string;
label: string;
shortcut?: string;
}
export interface Group {
value: string;
items: Item[];
}
export const suggestions: Item[] = [
{ label: "Linear", shortcut: "⌘L", value: "linear" },
{ label: "Figma", shortcut: "⌘F", value: "figma" },
{ label: "Slack", shortcut: "⌘S", value: "slack" },
{ label: "YouTube", shortcut: "⌘Y", value: "youtube" },
{ label: "Raycast", shortcut: "⌘R", value: "raycast" },
];
export const commands: Item[] = [
{
label: "История буфера обмена",
shortcut: "⌘⇧C",
value: "clipboard-history",
},
{ label: "Импорт расширения", shortcut: "⌘I", value: "import-extension" },
{ label: "Создать сниппет", shortcut: "⌘N", value: "create-snippet" },
{ label: "Системные настройки", shortcut: "⌘,", value: "system-preferences" },
{ label: "Управление окнами", shortcut: "⌘⇧W", value: "window-management" },
];
export const groupedItems: Group[] = [
{ items: suggestions, value: "Suggestions" },
{ items: commands, value: "Commands" },
];
const groupLabels: Record<string, string> = {
Commands: "Команды",
Suggestions: "Рекомендации",
};
export default function Particle() {
const [open, setOpen] = useState(false);
function handleItemClick(_item: Item) {
setOpen(false);
}
useEffect(() => {
const down = (e: KeyboardEvent) => {
if (e.key === "j" && (e.metaKey || e.ctrlKey)) {
e.preventDefault();
setOpen((open) => !open);
}
};
document.addEventListener("keydown", down);
return () => document.removeEventListener("keydown", down);
}, []);
return (
<CommandDialog onOpenChange={setOpen} open={open}>
<CommandDialogTrigger render={<Button variant="outline" />}>
Открыть палитру команд
<KbdGroup>
<Kbd>⌘</Kbd>
<Kbd>J</Kbd>
</KbdGroup>
</CommandDialogTrigger>
<CommandDialogPopup>
<Command items={groupedItems}>
<CommandInput placeholder="Поиск приложений и команд..." />
<CommandPanel>
<CommandEmpty>Ничего не найдено.</CommandEmpty>
<CommandList>
{(group: Group, _index: number) => (
<Fragment key={group.value}>
<CommandGroup items={group.items}>
<CommandGroupLabel>
{groupLabels[group.value]}
</CommandGroupLabel>
<CommandCollection>
{(item: Item) => (
<CommandItem
key={item.value}
onClick={() => handleItemClick(item)}
value={item.value}
>
<span className="flex-1">{item.label}</span>
{item.shortcut && (
<CommandShortcut>{item.shortcut}</CommandShortcut>
)}
</CommandItem>
)}
</CommandCollection>
</CommandGroup>
<CommandSeparator />
</Fragment>
)}
</CommandList>
</CommandPanel>
<CommandFooter>
<div className="flex items-center gap-4">
<div className="flex items-center gap-2">
<KbdGroup>
<Kbd>
<IconArrowUp stroke={1.5} />
</Kbd>
<Kbd>
<IconArrowDown stroke={1.5} />
</Kbd>
</KbdGroup>
<span>Навигация</span>
</div>
<div className="flex items-center gap-2">
<Kbd>
<IconCornerDownLeft stroke={1.5} />
</Kbd>
<span>Открыть</span>
</div>
</div>
<div className="flex items-center gap-2">
<Kbd>Esc</Kbd>
<span>Закрыть</span>
</div>
</CommandFooter>
</Command>
</CommandDialogPopup>
</CommandDialog>
);
}
Установка
pnpm dlx shadcn@latest add @oracul/command
Использование
import {
Command,
CommandCollection,
CommandDialog,
CommandDialogPopup,
CommandDialogTrigger,
CommandEmpty,
CommandFooter,
CommandGroup,
CommandGroupLabel,
CommandInput,
CommandItem,
CommandList,
CommandPanel,
CommandSeparator,
CommandShortcut,
} from "@/components/ui/command"
import { Button } from "@/components/ui/button"const items = [
{ value: "linear", label: "Linear" },
{ value: "figma", label: "Figma" },
{ value: "slack", label: "Slack" },
]
<CommandDialog>
<CommandDialogTrigger render={<Button variant="outline" />}>
Open Command Palette
</CommandDialogTrigger>
<CommandDialogPopup>
<Command items={items}>
<CommandInput placeholder="Search..." />
<CommandEmpty>No results found.</CommandEmpty>
<CommandList>
{(item) => (
<CommandItem key={item.value} value={item.value}>
{item.label}
</CommandItem>
)}
</CommandList>
</Command>
</CommandDialogPopup>
</CommandDialog>API
Command
Корневой компонент, оборачивающий функциональность autocomplete. Это псевдоним для Autocomplete.Root с разумными значениями по умолчанию для поведения командной палитры: autoHighlight="always", keepHighlight={true} и open={true}.
| Свойство | Тип | По умолчанию | Описание |
|---|---|---|---|
items | readonly unknown[] | - | Массив элементов для отображения в command |
open | boolean | true | Управляет тем, открыт ли command |
autoHighlight | boolean | "always" | "always" | Управляет автоматической подсветкой элементов |
keepHighlight | boolean | true | Сохранять ли состояние подсветки |
...props | React.ComponentProps<typeof Command> | - | Поддерживаются все свойства Base UI Autocomplete |
CommandDialog
Компонент-обёртка, предоставляющий функциональность корня диалога. Это псевдоним для Dialog.Root из Base UI.
| Свойство | Тип | Описание |
|---|---|---|
open | boolean | Управляет тем, открыт ли диалог |
onOpenChange | function | Колбэк, вызываемый при изменении состояния открытия |
...props | Свойства Base UI Dialog | Поддерживаются все стандартные атрибуты диалога |
CommandDialogTrigger
Кнопка-триггер, открывающая диалог command. По умолчанию рендерится как кнопка.
| Свойство | Тип | Описание |
|---|---|---|
render | React.ReactElement | Элемент для рендеринга в качестве триггера |
className | string | Дополнительные CSS-классы для применения к компоненту |
...props | Свойства Base UI Dialog Trigger | Поддерживаются все стандартные атрибуты триггера диалога |
CommandDialogPopup
Всплывающий контейнер содержимого, отображающий командную палитру внутри диалога.
| Свойство | Тип | Описание |
|---|---|---|
className | string | Дополнительные CSS-классы для применения к компоненту |
portalProps | Dialog.Portal.Props | Свойства, передаваемые внутреннему порталу (keepMounted, container и т. д.); см. API портала Base UI Dialog |
...props | Свойства Base UI Dialog Popup | Поддерживаются все стандартные атрибуты всплывающего окна диалога |
CommandInput
Поле поискового ввода со встроенной иконкой поиска. Автоматически включает иконку поиска через startAddon и по умолчанию имеет размер lg.
| Свойство | Тип | Описание |
|---|---|---|
placeholder | string | Текст-заполнитель для поля ввода |
className | string | Дополнительные CSS-классы для применения к компоненту |
...props | Свойства Base UI Autocomplete Input | Поддерживаются все стандартные атрибуты поля ввода autocomplete |
CommandList
Прокручиваемый контейнер для элементов command. Оборачивает AutocompleteList, добавляя функциональность прокрутки.
| Свойство | Тип | Описание |
|---|---|---|
className | string | Дополнительные CSS-классы для применения к компоненту |
...props | Свойства Base UI Autocomplete List | Поддерживаются все стандартные атрибуты списка autocomplete |
CommandPanel
Компонент-контейнер, обеспечивающий стилизацию содержимого command вне диалогов. Полезен при создании автономных командных интерфейсов с рамкой и приподнятым внешним видом.
| Свойство | Тип | Описание |
|---|---|---|
className | string | Дополнительные CSS-классы для применения к компоненту |
...props | React.ComponentProps<'div'> | Поддерживаются все стандартные атрибуты div |
CommandEmpty
Отображает сообщение, когда результаты не найдены.
| Свойство | Тип | Описание |
|---|---|---|
className | string | Дополнительные CSS-классы для применения к компоненту |
...props | Свойства Base UI Autocomplete Empty | Поддерживаются все стандартные атрибуты пустого состояния autocomplete |
CommandGroup
Группирует связанные элементы command. Оборачивает AutocompleteGroup.
| Свойство | Тип | Описание |
|---|---|---|
items | readonly unknown[] | Массив элементов в этой группе |
className | string | Дополнительные CSS-классы для применения к компоненту |
...props | Свойства Base UI Autocomplete Group | Поддерживаются все стандартные атрибуты группы autocomplete |
CommandGroupLabel
Отображает подпись для группы command.
| Свойство | Тип | Описание |
|---|---|---|
className | string | Дополнительные CSS-классы для применения к компоненту |
...props | Свойства Base UI Autocomplete Group Label | Поддерживаются все стандартные атрибуты подписи группы autocomplete |
CommandItem
Отдельный выбираемый элемент command. Расширяет AutocompleteItem.
| Свойство | Тип | Описание |
|---|---|---|
value | unknown | Значение элемента |
className | string | Дополнительные CSS-классы для применения к компоненту |
...props | Свойства Base UI Autocomplete Item | Поддерживаются все стандартные атрибуты элемента autocomplete |
CommandSeparator
Визуальный разделитель между группами или элементами command. Включает вертикальный отступ по умолчанию через className my-2.
| Свойство | Тип | Описание |
|---|---|---|
className | string | Дополнительные CSS-классы для применения к компоненту (по умолчанию включает my-2) |
...props | Свойства Base UI Autocomplete Separator | Поддерживаются все стандартные атрибуты разделителя autocomplete |
CommandShortcut
Отображает сочетания клавиш в стилизованном элементе span.
| Свойство | Тип | Описание |
|---|---|---|
className | string | Дополнительные CSS-классы для применения к компоненту |
...props | React.ComponentProps<'span'> | Поддерживаются все стандартные атрибуты span |
CommandFooter
Секция нижнего колонтитула для отображения подсказок или дополнительных сочетаний клавиш. Рендерится как стилизованный div с отступами и рамкой.
| Свойство | Тип | Описание |
|---|---|---|
className | string | Дополнительные CSS-классы для применения к компоненту |
...props | React.ComponentProps<'div'> | Поддерживаются все стандартные атрибуты div |
CommandCollection
Используется внутри CommandGroup для обёртки элементов при работе со сгруппированными данными. Это псевдоним для AutocompleteCollection из компонента Autocomplete.
| Свойство | Тип | Описание |
|---|---|---|
...props | Свойства Base UI Autocomplete Collection | Поддерживаются все стандартные атрибуты коллекции autocomplete |
Примеры
С сочетанием клавиш
Вы можете добавить сочетание клавиш для открытия командной палитры:
React.useEffect(() => {
const down = (e: KeyboardEvent) => {
if (e.key === "k" && (e.metaKey || e.ctrlKey)) {
e.preventDefault()
setOpen((open) => !open)
}
}
document.addEventListener("keydown", down)
return () => document.removeEventListener("keydown", down)
}, [])Со сгруппированными элементами
const groupedItems = [
{
value: "Suggestions",
items: [
{ value: "linear", label: "Linear" },
{ value: "figma", label: "Figma" },
]
},
{
value: "Commands",
items: [
{ value: "clipboard", label: "Clipboard History" },
{ value: "settings", label: "System Preferences" },
]
},
]
<Command items={groupedItems}>
<CommandInput placeholder="Search..." />
<CommandEmpty>No results found.</CommandEmpty>
<CommandList>
{(group, index) => (
<React.Fragment key={group.value}>
<CommandGroup items={group.items}>
<CommandGroupLabel>{group.value}</CommandGroupLabel>
<CommandCollection>
{(item) => (
<CommandItem key={item.value} value={item.value}>
{item.label}
</CommandItem>
)}
</CommandCollection>
</CommandGroup>
{index < groupedItems.length - 1 && <CommandSeparator />}
</React.Fragment>
)}
</CommandList>
</Command>Автономный Command (без диалога)
Вы можете использовать компонент Command без обёртки-диалога:
<Command open items={items}>
<CommandInput placeholder="Type a command..." />
<CommandEmpty>No results found.</CommandEmpty>
<CommandList>
{(item) => (
<CommandItem key={item.value} value={item.value}>
{item.label}
</CommandItem>
)}
</CommandList>
</Command>На этой странице