Command
Eine durchsuchbare Liste von Aktionen, inline oder als ⌘K-Palette, mit Seiten, Tastenkürzeln und hervorgehobenen Treffern.
pnpm dlx shadcn@latest add https://hextaui.com/r/command.jsonFügt die Komponente, die HextaUI-Theme-Tokens und alle HextaUI-Komponenten hinzu, von denen sie abhängt.
Füge die Theme-Tokens zu deinem globalen CSS hinzu, falls du das noch nicht getan hast.
Installiere die Abhängigkeiten.
pnpm add @base-ui/react @tabler/icons-react class-variance-authority cmdk cnKopiere den folgenden Code und füge ihn in dein Projekt ein.
components/ui/command.tsx components/ui/button.tsx lib/motion.ts Passe die Importpfade an dein Projekt-Setup an.
Hotkeys verwenden mod für ⌘ auf Apple-Geräten und Strg überall sonst. Labels werden automatisch pro Plattform formatiert.
Einfach
Tippen filtert und sortiert Einträge laufend. Gruppen ohne Treffer verschwinden, und die Listenhöhe animiert sich an das, was übrig bleibt.
Dialog
Setze ein <Command /> in <CommandDialog /> und schalte es mit useCommandHotkey um. Drücke ⌘K oder Strg+K. Eintrags-Kürzel laufen, solange es geöffnet ist, Treffer werden hervorgehoben, und preserveSearch behält Suchbegriff und Auswahl für das nächste Öffnen.
Seiten
Ein Eintrag mit page öffnet das passende <CommandPage />. Der Seitentitel erscheint als Chip im Input, die Liste gleitet seitlich herein, und Backspace bei leerer Suche oder Escape geht zurück.
Scrollbar
Lange Listen scrollen in einer begrenzten Höhe. Der ausgewählte Eintrag bleibt beim Bewegen per Tastatur immer im Sichtbereich.
Asynchrone Ergebnisse
Setze shouldFilter={false} und rendere die Ergebnisse, die du lädst. <CommandLoading /> wartet 150 ms, bevor es erscheint, und bleibt dann mindestens 300 ms, sodass schnelle Antworten nie einen Spinner aufblitzen lassen. Probiere beide Latenzen aus.
Langer Inhalt
Überschriften werden umgebrochen, lange Namen werden je nach Wunsch gekürzt oder umgebrochen, und Kürzel werden nie hinausgedrängt.
Rechts nach links
Icons, Kürzel, der Seiten-Chip und das Gleiten der Seite folgen alle der Leserichtung.
| Taste | Aktion |
|---|---|
| ↓ | Wählt den nächsten Eintrag aus. |
| ↑ | Wählt den vorherigen Eintrag aus. |
| Alt↓ | Springt zum ersten Eintrag der nächsten Gruppe. |
| Alt↑ | Springt zum ersten Eintrag der vorherigen Gruppe. |
| Home | Wählt den ersten Eintrag aus. |
| End | Wählt den letzten Eintrag aus. |
| CtrlN | Wählt den nächsten Eintrag aus. Strg+J funktioniert ebenfalls. Mit vimBindings abschaltbar. |
| CtrlP | Wählt den vorherigen Eintrag aus. Strg+K funktioniert ebenfalls. Mit vimBindings abschaltbar. |
| Enter | Führt den ausgewählten Eintrag aus. Bei einem Link-Eintrag öffnet ⌘ Enter oder Strg+Enter ihn in einem neuen Tab. |
| Esc | Leert zuerst die Suche, geht dann eine Seite zurück und schließt schließlich den Dialog. |
| Backspace | Geht eine Seite zurück, wenn die Suche leer ist. |
| ⌘P | Jedes Eintrags-Kürzel führt seinen Eintrag aus, solange der Fokus im Command-Menü liegt. |
- Das Input ist eine Combobox, die auf den ausgewählten Eintrag zeigt, sodass Screenreader jeden Eintrag beim Bewegen ansagen.
- Eine Live-Region mit polite-Priorität sagt kurz nach dem Aufhören des Tippens die Anzahl der Ergebnisse an und den Seitentitel, wenn du eine Seite öffnest oder verlässt. Ändere den Wortlaut mit
formatResultsundrootTitle. <CommandDialog />hat einen verborgenen Titel und eine verborgene Beschreibung, fängt den Fokus ein, solange es geöffnet ist, und gibt ihn beim Schließen an den Trigger zurück.- Eintrags-Kürzel werden mit
aria-keyshortcutsbereitgestellt. - Bei reduzierter Bewegung laufen Einträge ohne Bestätigungsblinken, und Seiten blenden über, statt zu gleiten.
Basiert auf cmdk, mit <CommandDialog /> auf dem Base UI Dialog. Teile akzeptieren die Props des cmdk-Teils, den sie umschließen.
| Prop | Typ | Standard |
|---|---|---|
labelZugänglicher Name des Menüs. | string | "Command menu" |
highlightHebt die passenden Buchstaben in jedem Eintrag hervor und dimmt den Rest. | boolean | false |
shouldFilterAuf false setzen, um die Einträge selbst zu filtern und zu sortieren, zum Beispiel wenn die Ergebnisse von einem Server kommen. | boolean | true |
filterGibt einen Wert von 0 (verborgen) bis 1 (bester Treffer) zurück. | (value: string, search: string, keywords?: string[]) => number | – |
valueDer Wert des ausgewählten Eintrags. | string | – |
defaultValue | string | – |
onValueChange | (value: string) => void | – |
loopAn den Enden der Liste umbrechen. | boolean | false |
vimBindingsNavigation mit Strg+N, J, P und K. | boolean | true |
disablePointerSelection | boolean | false |
formatResultsText, der Screenreadern nach dem Tippen angesagt wird. | (count: number) => string | "3 results" |
rootTitleWird angesagt, wenn du die letzte Seite verlässt und zur Wurzel zurückkehrst. | string | "All commands" |
| Attribut | Beschreibung |
|---|---|
data-slot="command" | Das Root in CSS ansprechen. |
data-highlighting | Vorhanden, solange highlight aktiv und die Suche nicht leer ist. |
--command-radius | Äußerer Radius. Einträge leiten daraus einen konzentrischen Radius ab. |
--command-inset | Padding zwischen dem Listenrand und ihren Einträgen. |
| Prop | Typ | Standard |
|---|---|---|
open | boolean | – |
defaultOpen | boolean | false |
onOpenChange | (open: boolean, details) => void | – |
preserveSearchHält den Dialog gemountet, sodass Suchbegriff, Seite und Auswahl das Schließen überstehen. Der Suchbegriff ist beim erneuten Öffnen markiert. | boolean | false |
titleVisuell verborgener Dialogtitel. | string | "Command menu" |
descriptionVisuell verborgene Dialogbeschreibung. | string | "Search for a command to run." |
showCloseButton | boolean | false |
classNameWird auf das Dialog-Popup angewendet. | string | – |
| Attribut | Beschreibung |
|---|---|
data-slot="command-dialog" | Das Dialog-Popup. |
data-slot="command-dialog-overlay" | Der Hintergrund. |
data-open | Vorhanden am Popup, solange es geöffnet ist. |
| Prop | Typ | Standard |
|---|---|---|
valueGesteuerter Suchtext. | string | – |
onValueChange | (search: string) => void | – |
placeholder | string | – |
clearLabelZugänglicher Name des Löschen-Buttons. | string | "Clear search" |
backLabelZugänglicher Name des Seiten-Chips. | (title: string) => string | (title) => `Back from ${title}` |
| Attribut | Beschreibung |
|---|---|
data-slot="command-input" | Das Input. |
data-slot="command-input-wrapper" | Die Zeile mit Icon, Input und Löschen-Button. |
data-slot="command-clear" | Der Löschen-Button, sichtbar sobald du tippst. |
data-slot="command-page-chip" | Der Zurück-Chip, der auf einer Seite angezeigt wird. |
| Prop | Typ | Standard |
|---|---|---|
labelZugänglicher Name der Liste. | string | – |
| Attribut | Beschreibung |
|---|---|
data-slot="command-list" | Die Liste. |
data-settled | Vorhanden, sobald sich die Liste gemessen hat. Der Höhenübergang läuft nur, solange es gesetzt ist. |
--cmdk-list-height | Höhe der sichtbaren Einträge, zum Animieren der Liste verwendet. |
| Prop | Typ | Standard |
|---|---|---|
childrenVerwende die Funktionsform, um die Suchanfrage wiederzugeben. | ReactNode | (search: string) => ReactNode | – |
| Attribut | Beschreibung |
|---|---|
data-slot="command-empty" | Verborgen, solange ein CommandLoading in der Liste ist. |
| Prop | Typ | Standard |
|---|---|---|
loading | boolean | true |
delayMillisekunden, die gewartet wird, bevor der Spinner erscheint. | number | 150 |
minDurationMindestdauer in Millisekunden, die der Spinner nach dem Erscheinen bleibt. | number | 300 |
labelZugängliches Label. Standardmäßig String-Kinder. | string | – |
progress | number | – |
| Attribut | Beschreibung |
|---|---|
data-slot="command-loading" | Die Ladezeile. |
data-pending | Vorhanden während der Verzögerung, solange die Zeile angesagt, aber noch nicht sichtbar ist. |
| Prop | Typ | Standard |
|---|---|---|
heading | ReactNode | – |
valueErforderlich, wenn es keine Überschrift gibt. | string | – |
forceMountHält die Gruppe beim Filtern sichtbar. | boolean | false |
| Attribut | Beschreibung |
|---|---|
data-slot="command-group" | Die Gruppe. |
[cmdk-group-heading] | Das Überschriftenelement. |
| Prop | Typ | Standard |
|---|---|---|
onSelectLäuft bei Klick, Enter oder dem Kürzel des Eintrags, nach dem Bestätigungsblinken. | (value: string) => void | – |
valueWird zum Filtern verwendet. Standardmäßig der Text des Eintrags, ohne das Kürzel. | string | – |
keywordsZusätzliche Wörter, die zu diesem Eintrag passen. | string[] | – |
disabled | boolean | false |
shortcutEin Hotkey wie "mod+shift+c". Wird am Eintrag angezeigt und führt ihn aus, solange der Fokus im Menü liegt. | string | – |
pageÖffnet die CommandPage mit dieser ID, statt auszuführen. | string | – |
pageTitleTitel, der im Seiten-Chip angezeigt wird. Standardmäßig der Wert. | string | – |
hrefRendert den Eintrag als Link. Enter folgt ihm, ⌘ oder Strg+Enter öffnet einen neuen Tab. | string | – |
renderEin Link-Element, das stattdessen gerendert wird, etwa Next.js <Link />. | ReactElement | – |
confirmLässt den Eintrag kurz blinken, bevor er ausgeführt wird, damit die Auswahl wahrgenommen wird. | boolean | true |
forceMountHält den Eintrag beim Filtern sichtbar. | boolean | false |
| Attribut | Beschreibung |
|---|---|
data-slot="command-item" | Der Eintrag. |
data-selected="true" | Vorhanden am ausgewählten Eintrag. |
data-disabled="true" | Vorhanden an deaktivierten Einträgen. |
data-value | Der Wert, der zum Filtern verwendet wird. |
data-confirming | Vorhanden während des Bestätigungsblinkens. |
data-page | Vorhanden an Einträgen, die eine Seite öffnen. |
| Prop | Typ | Standard |
|---|---|---|
idEntspricht der page-Prop des Eintrags, der sie öffnet. Ihre Gruppen und Einträge werden nur gerendert, solange sie die aktuelle Seite ist. | string | – |
| Prop | Typ | Standard |
|---|---|---|
hotkeyFormatiert einen Hotkey wie "mod+k" für die aktuelle Plattform. Kinder überschreiben es. | string | – |
| Attribut | Beschreibung |
|---|---|
data-slot="command-shortcut" | Das Kürzel-Label. |
| Prop | Typ | Standard |
|---|---|---|
alwaysRenderHält ihn bei der Suche sichtbar. | boolean | false |
| Attribut | Beschreibung |
|---|---|
data-slot="command-separator" | Das Trennzeichen. |
| Prop | Typ | Standard |
|---|---|---|
childrenStandardmäßig Tastenhinweise, die sich auf einer Seite aktualisieren. Auf Touchscreens ausgeblendet. | ReactNode | – |
| Attribut | Beschreibung |
|---|---|
data-slot="command-footer" | Der Footer. |
| Prop | Typ | Standard |
|---|---|---|
hotkeyEs wird auf dem gesamten Dokument gelauscht. Hotkeys ohne Modifier werden ignoriert, während du in ein Feld tippst. | string | – |
callback | (event: KeyboardEvent) => void | – |
options.enabled | boolean | true |
Gibt zurück, ob ein Ladeindikator sichtbar sein soll, mit derselben Verzögerung und Mindestdauer wie <CommandLoading />. Verwende es, um veraltete Ergebnisse auszublenden, während eine Anfrage läuft.
| Prop | Typ | Standard |
|---|---|---|
loading | boolean | – |
options.delay | number | 150 |
options.minDuration | number | 300 |
useCommandPages()gibt{ pages, page, push, pop, reset }zurück, um Seiten aus deinem eigenen Code zu steuern.useCommandState(selector)liest den cmdk-State, etwa die Suche oder die Anzahl gefilterter Einträge.useHotkeyLabel(hotkey)formatiert einen Hotkey für die aktuelle Plattform, etwa ⌘K oder Strg+K.
- ButtonButtons in allen Varianten und Größen, mit eingebautem Lade-, Erfolgs- und Fehlerablauf, der den Spinner bei schnellen Anfragen überspringt.
- HotkeyTastenkürzel parsen, beschriften, ansagen und abgleichen, mit ⌘ auf Apple-Plattformen und Strg überall sonst.
- MotionDie Easing-Kurven, Dauern und der Reduced-Motion-Check, mit denen jede Komponente animiert, plus Hooks für Größen-Morphs und gleitende Hervorhebungen.
- SpinnerEin Ladeindikator mit Ticks im Apple-Stil oder einem atmenden Ring, der vor dem Anzeigen warten und lange genug sichtbar bleiben kann, um nicht zu flackern.
- Alert dialogEin Bestätigungsdialog für destruktive oder wichtige Aktionen, der auf asynchrone Arbeit wartet und auf Smartphones zum Bottom Sheet wird.
- Context menuEin Menü mit Aktionen per Rechtsklick oder langem Drücken, mit Untermenüs, Checkbox- und Radio-Einträgen sowie Halte-Feedback auf Touch-Geräten.
In Blocks verwendet
Blocks, die auf Command aufbauen.