Gebaut auf Vercels UI SDK 0.1.0-beta.1. Die API kann sich ändern.
Token input
Ein Textfeld auf Vercels UI SDK, das getippten Text mit Tokens für Personen, Dateien und Befehle mischt, mit Vorschlägen für @ und /.
- Formularkomponenten
- 15 Teilen
- 10 Beispielen
@tabler/icons-react@ui-sdk/core@ui-sdk/react
pnpm dlx shadcn@latest add https://hextaui.com/r/ui-sdk-token-input.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 @ui-sdk/react@0.1.0-beta.1 @ui-sdk/core@0.1.0-beta.1 @tabler/icons-react cnKopiere den folgenden Code und füge ihn in dein Projekt ein.
components/ui/ui-sdk-token-input.tsx Passe die Importpfade an dein Projekt-Setup an.
UI SDK bringt etwas eigenes CSS in einem Cascade Layer namens ui-sdk mit. Deklariere diesen Layer ganz oben im globalen Stylesheet, über dem Tailwind-Import, damit deine Klassen gewinnen.
Ein Wert ist ein Array aus Text und Tokens. Jedes Token hat einen type, einen value für deine App und ein label, das Menschen lesen. Der Editor verwaltet Inhalt, Auswahl und Rückgängig selbst, also lass ihn rendern und übergib renderToken, um das Aussehen eines Tokens zu ändern. Ohne zeigt jedes Token sein Label und einen Entfernen-Button.
Ein TriggerMenu im Input schlägt Tokens vor, sobald jemand einen Auslöser wie @ oder / tippt. Lass es weg, wenn dein Code die Tokens liefert.
Tippe @ für Dateien oder am Anfang / für Skills. Eine Datei ist ausstehend, solange sie lädt, und beim Senden wird jeder Skill mit updateToken() als laufend, dann als fertig markiert. Enter sendet, Shift+Enter fügt eine Zeile ein.
tokenDeletion legt fest, was die Rücktaste an einem Token tut. whole entfernt es, select wählt es zuerst aus und revert macht es wieder zu Text.
Ein Controller aus createTokenInputController() fügt Tokens per Code ein, ändert und entfernt sie. Übergib ein Promise als resolve, damit ein Token bis zum Abschluss als ausstehend gilt.
Mit name sendet das Input seinen Text, jedes Token als [@label](type:value). required verhindert leeres Senden, und ein Reset kehrt zu defaultValue zurück.
Mit submitShortcut="mod+enter" fügt Enter eine Zeile ein und Command oder Strg+Enter sendet, was viele, die Japanisch und Chinesisch schreiben, bevorzugen.
Ein Codec wandelt Tokens in Text und zurück, hier als <@id>. Mit copy="label" kopiert man, was man liest, und beim Wiedereinfügen kommen die Tokens zurück.
Ein deaktiviertes Input lässt sich weder fokussieren noch ändern, blendet die Entfernen-Buttons aus und sendet nichts.
Mit readOnly bleibt der Text fokussierbar, auswählbar und wird gesendet, aber Tippen, Einfügen und Ablegen ändern ihn nicht.
Der Editor folgt der Richtung der Seite, und ein Token bleibt auch in Rechts-nach-links-Text ein Stück.
| Taste | Aktion |
|---|---|
| BackspaceDelete | Entfernt das Token vor oder nach dem Cursor, wie tokenDeletion es festlegt. |
| ←→ | Bewegt den Cursor mit einem Druck über ein Token. Er bleibt nie darin stehen. |
| ↑↓ | Bewegt sich durch die Vorschläge, solange das Menü offen ist. |
| Enter | Sendet. Bei offenem Menü wählt es den hervorgehobenen Vorschlag. |
| Shift + Enter | Beginnt eine neue Zeile. |
| ⌘ + EnterCtrl + Enter | Sendet, wenn submitShortcut mod+enter ist. Enter beginnt dann eine neue Zeile. |
| ⌘ + ZCtrl + Z | Macht den letzten Schritt rückgängig. Tippen wird gruppiert, Einfügen und Token-Änderungen sind eigene Schritte. |
| Esc | Schließt die Vorschläge. |
Der Editor ist ein mehrzeiliges Textfeld. Ein Trigger-Menü darin ergänzt aria-autocomplete und aria-haspopup, und der Fokus bleibt im Text, während die Pfeiltasten durch die Vorschläge gehen. Jedes Token wird mit Label und Art vorgelesen, etwa „routes.ts Datei“, und Einfügen oder Entfernen wird angesagt. Benenne den Editor mit aria-label oder einem umgebenden Label.
Entfernen-Buttons sind für Screenreader verborgen, da die Rücktaste ein Token per Tastatur entfernt. Ihre Trefferfläche wächst auf Touchscreens, ein ausstehendes Token pulsiert nur, wenn Bewegung erlaubt ist, und ein ausgewähltes Token bekommt im Modus „Erzwungene Farben“ einen Systemrahmen.
Jeder Teil umhüllt den gleichnamigen UI-SDK-Teil und nimmt alle seine Props an, auch render und einen className, der eine Funktion des Zustands sein kann.
| Prop | Typ | Standard |
|---|---|---|
value | TokenInputValue | – |
defaultValue | TokenInputValue | – |
onValueChangeLäuft bei Tippen, Einfügen, Menüs, Rückgängig und Controller-Aufrufen. details nennt den Grund und entfernte Tokens. | (value, details) => void | – |
onSubmitLäuft beim Senden-Kürzel, außer ein Menü ist offen oder eine Eingabemethode setzt gerade Text zusammen. | (value, details) => void | – |
submitShortcut | "enter" | "mod+enter" | "enter" |
tokenDeletion | "whole" | "select" | "revert" | "whole" |
renderTokenRendert ein Token. Standard ist ein TokenInputToken mit Label und Entfernen-Button. | (token: Token) => ReactNode | – |
copy | "codec" | "label" | "codec" |
codec | TokenCodec | – |
getTokenDescriptionWas ein Token Screenreadern zusätzlich zum Label sagt. | (token: Token) => string | – |
history | { limit, groupDelay } | – |
name | string | – |
form | string | – |
required | boolean | false |
disabled | boolean | false |
readOnly | boolean | false |
controllerAus createTokenInputController(). | TokenInputController | – |
| Prop | Typ | Standard |
|---|---|---|
placeholderWird über aria-placeholder gezeigt, solange das Input leer ist. | string | – |
render | ReactElement | (props, state) => ReactElement | – |
| Attribut | Beschreibung |
|---|---|
data-slot="token-input-editor" | Spricht den Editor in CSS an. |
data-empty | Vorhanden, solange das Input leer ist. |
data-disabled | Vorhanden, wenn deaktiviert. |
data-readonly | Vorhanden, wenn schreibgeschützt. |
| Attribut | Beschreibung |
|---|---|
data-slot="token-input-token" | Spricht ein Token in CSS an. |
data-token-type | Der Typ des Tokens, etwa file oder mention. |
data-selected | Vorhanden, solange das Token in der Auswahl liegt oder zum Entfernen ausgewählt ist. |
data-pending | Vorhanden, solange das Token lädt. |
data-unresolved | Vorhanden, solange das Token eine Entscheidung braucht, etwa eine mehrdeutige Erwähnung. |
Entfernt sein Token und lässt den Fokus im Editor. Ohne children zeigt es ein Tabler-X-Icon und blendet sich aus, solange das Input deaktiviert oder schreibgeschützt ist.
| Prop | Typ | Standard |
|---|---|---|
triggersDie Zeichen, die das Menü öffnen, der Token-Typ, den jedes einfügt, und seine Einträge. | TriggerDefinition[] | – |
onSelectLäuft, wenn ein Eintrag gewählt wird. Gib ein Promise zurück, um das Token als ausstehend einzufügen. | (value, details) => void | Promise | – |
autoHighlight | boolean | true |
loop | boolean | true |
| Prop | Typ | Standard |
|---|---|---|
align | "start" | "center" | "end" | "start" |
sideOffset | number | 6 |
collisionPadding | number | 8 |
| Attribut | Beschreibung |
|---|---|
data-slot="trigger-menu-content" | Spricht das Popup in CSS an. |
data-trigger | Der Auslöser des aktuellen Treffers, etwa @, damit jede Liste anders aussehen kann. |
data-starting-style | Vorhanden, solange das Popup einblendet. |
data-ending-style | Vorhanden, solange das Popup ausblendet. |
| Prop | Typ | Standard |
|---|---|---|
value | T | – |
labelDer eingefügte und verglichene Text, wenn der Inhalt kein reiner Text ist. | string | – |
disabled | boolean | false |
| Attribut | Beschreibung |
|---|---|
data-highlighted | Am hervorgehobenen Eintrag vorhanden. Der Fokus bleibt im Editor. |
data-disabled | Vorhanden, wenn der Eintrag nicht gewählt werden kann. |
- CalendarEin Datumsraster für Einzel-, Bereichs- und Mehrfachauswahl, mit gleitenden Monaten, Bereichsvorschau und Tagen in Touch-Größe.
- CheckboxEine Checkbox, deren Häkchen sich einzeichnet, mit unbestimmten übergeordneten Elementen, Gruppen und Labels, die ihren Hover teilen.
- ComboboxEin filterbares Select mit Chips, Gruppen und asynchronen Ergebnissen, in einem Popup, das sich beim Tippen anpasst.
- Date pickerEin Button, der einen Kalender in einem Popover öffnet, auf Smartphones als Bottom Sheet, für einzelne Daten und Zeiträume.
- FieldLabels, Beschreibungen und Fehler, mit ihrem Steuerelement verbunden, mit Validierungszuständen und Layouts für Formulare.
- InputEin Texteingabefeld mit drei Größen, ungültigen und schreibgeschützten Zuständen, nativem Validierungsstyling und einer 16-px-Schrift für Touch, damit Smartphones nie hineinzoomen.