Input group
Ein Input mit angehängten Icons, Text, Buttons oder Tastaturhinweis, die sich einen Rahmen und einen Fokusring teilen.
pnpm dlx shadcn@latest add https://hextaui.com/r/input-group.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 cnKopiere den folgenden Code und füge ihn in dein Projekt ein.
components/ui/input-group.tsx components/ui/input.tsx components/ui/button.tsx components/ui/number-flow.tsx lib/motion.ts Passe die Importpfade an dein Projekt-Setup an.
Setze <InputGroupInput /> oder <InputGroupTextarea /> an den Anfang und die Addons danach. Addons platzieren sich mit align selbst, sodass das Feld in der Tab-Reihenfolge und für Screenreader zuerst kommt.
Die Gruppe verfolgt ihr Feld, sodass die intelligenten Teile keine Verdrahtung brauchen. <InputGroupClear />, <InputGroupPasswordToggle /> und <InputGroupCount /> lesen Wert, type und maxLength aus dem Feld, egal ob es gesteuert ist oder nicht.
Icon
Icons sitzen auf beiden Seiten innerhalb des Rahmens. Ein Klick auf ein Icon fokussiert das Input, sodass sich die ganze Gruppe wie ein Feld anfühlt.
Leeren
<InputGroupClear /> blendet ein, sobald ein Wert vorhanden ist. Es leert über den Bearbeitungsverlauf des Browsers, sodass Cmd+Z den Text zurückbringt, und es löst dein onChange aus. Escape leert ebenfalls. Ein zweites Escape bleibt für den umgebenden Dialog oder das Popover.
Zeichenzähler
<InputGroupCount /> zählt gegen das maxLength des Felds. Nur die Ziffern, die sich ändern, rollen. Die Zahl wird nahe am Limit dunkler und beim Erreichen rot, und eine getippte Taste über das Limit hinaus lässt sie wackeln. Screenreader hören eine Meldung, wenn das Feld dem Limit nahekommt und wenn es erreicht wird, nie bei jeder Taste.
Text
Verwende <InputGroupText /> für Einheiten, Währungen und URL-Teile. Das Padding des Inputs schrumpft neben einem Addon, sodass der Text wie ein Wert wirkt.
Button
<InputGroupButton /> ist ein Ghost-Button, der so dimensioniert ist, dass er in das Feld passt. Seine Ecken sind konzentrisch zu denen der Gruppe, und er erhält seinen eigenen Fokusring.
Tastaturhinweis
Ein einfaches <kbd> in einem Addon wird als Tastenkappe gestylt. Es ist nur ein visueller Hinweis, binde das Kürzel also selbst.
Textarea
<InputGroupTextarea /> wächst mit seinem Inhalt bis 16 rem und scrollt dann. Die Höhe passt sich zwischen Zeilen sanft an, statt zu springen. Ein block-end-Addon wird zu einer Toolbar darunter, und Buttons an seinen Rändern erhalten denselben Einzug wie die Ecke, in der sie sitzen.
Kopfzeile
Ein block-start-Addon sitzt über dem Feld. Füge separator hinzu, um eine Haarlinie dazwischen zu zeichnen.
Passwort
<InputGroupPasswordToggle /> schaltet ein type="password"-Feld auf Text und zurück. Der Cursor und die Auswahl bleiben, wo sie waren, ein Mausklick hält den Fokus im Feld, und das Passwort wird beim Absenden des Formulars wieder verborgen. Steuere es mit revealed.
Größen
size an der Gruppe legt die Höhe fest und gibt sie an das Input weiter, passend zu den <Input />-Größen. Buttons behalten bei jeder Größe konzentrische Ecken.
Ungültig
Setze aria-invalid am Input, und die ganze Gruppe wird rot, einschließlich ihres Fokusrings. Verknüpfe die Meldung mit aria-describedby.
Deaktiviert
Ein deaktiviertes Input dimmt die ganze Gruppe und zeigt darüber einen not-allowed-Cursor. Deaktiviere auch Addon-Buttons, da sie sonst benutzbar bleiben.
Lädt
Inline-Addons gleiten auf ihre neue Breite, wenn sich ihr Inhalt ändert, sodass das Feld nie springt, wenn ein Spinner zu einer Trefferzahl wird. Der Spinner dreht sich nur, wenn Bewegung erlaubt ist, und role="status" sagt den Text an.
Dropdown
Rendere ein <InputGroupButton /> als Dropdown-Trigger, um das Input einzugrenzen.
Langer Inhalt
Lange Werte scrollen im Input, statt die Gruppe zu dehnen. Umschließe langen Addon-Text mit einem kürzenden Span mit maximaler Breite.
Rechts nach links
Addons, Padding und Eckenradien verwenden logische Seiten, sodass inline-start rechts landet.
| Taste | Aktion |
|---|---|
| Tab | Wechselt vom Feld zu jedem Addon-Button, in Quellreihenfolge. |
| ShiftTab | Geht rückwärts durch die Buttons und das Feld. |
| Escape | Mit einem InputGroupClear leert es das Feld. Ist es bereits leer, wird Escape durchgereicht. |
- Jedes Feld braucht einen Namen. Verwende ein sichtbares Label, ein Field oder
aria-label. Icons und Addon-Text sind nicht Teil des Namens des Felds. - Gib reinen Icon-Buttons ein
aria-label. - Wenn Addon-Text eine Bedeutung trägt, etwa eine Währung oder eine Domain, füge ihn dem Label hinzu oder verweise mit
aria-describedbydarauf. <InputGroupClear />wird in der Tab-Reihenfolge übersprungen, da Escape dasselbe tut. Der Passwort-Umschalter bleibt tabbar und behält denselben Namen, wobeiaria-pressedseinen Zustand meldet.- Wenn ein Absenden das Feld als ungültig vorfindet, wackelt die Gruppe einmal. Bei reduzierter Bewegung ist der rote Rahmen der einzige Hinweis.
- Auf Touchscreens ist der Feldtext mindestens 16 px groß, damit Smartphones beim Fokussieren nicht zoomen.
<InputGroupInput /> und <InputGroupTextarea /> akzeptieren die Props der Elemente, die sie rendern. Die übrigen Teile akzeptieren die Attribute ihres Elements.
| Prop | Typ | Standard |
|---|---|---|
sizeHöhe der Gruppe, die an das Input weitergegeben wird. | "sm" | "default" | "lg" | "default" |
| Attribut | Beschreibung |
|---|---|
data-slot="input-group" | Die Gruppe in CSS ansprechen. Rendert role="group". |
data-size | Die aktuelle Größe. |
data-filled | Vorhanden, solange das Feld einen Wert hat. |
data-shake | Vorhanden, während die Gruppe nach einem fehlgeschlagenen Absenden wackelt. |
data-disabled | Setze es selbst, um die Gruppe zu dimmen, wenn nur die Addons deaktiviert sind. |
--input-group-radius | Eckenradius der Gruppe. Buttons und Tastenkappen leiten ihren Radius davon ab. |
--input-group-height | Höhe der Gruppe für die aktuelle Größe. |
| Prop | Typ | Standard |
|---|---|---|
sizeWird von der Gruppe übernommen. | "sm" | "default" | "lg" | – |
aria-invalid | boolean | – |
disabled | boolean | false |
readOnly | boolean | false |
| Attribut | Beschreibung |
|---|---|
data-slot="input-group-control" | Markiert das Feld. Die Gruppe liest daraus Fokus-, Invalid-, Disabled- und Read-only-Zustände. |
data-invalid | Vorhanden, wenn ein umgebendes Field den Wert als ungültig markiert. |
data-disabled | Vorhanden, wenn das Feld deaktiviert ist. |
data-focused | Vorhanden, solange das Feld den Fokus hat. |
data-filled | Vorhanden, wenn das Feld einen Wert hat. |
data-dirty | Vorhanden, sobald sich der Wert vom Anfangswert unterscheidet. |
data-touched | Vorhanden, sobald das Feld fokussiert und wieder verlassen wurde. |
| Prop | Typ | Standard |
|---|---|---|
autoResizeWächst mit dem Inhalt bis 16 rem und gleitet dabei zwischen den Höhen. | boolean | true |
shakeLässt die Gruppe wackeln, wenn ein Absenden sie als ungültig vorfindet. | boolean | true |
rows | number | – |
aria-invalid | boolean | – |
disabled | boolean | false |
| Attribut | Beschreibung |
|---|---|
data-slot="input-group-control" | Markiert das Feld. Die Gruppe liest daraus Fokus-, Invalid-, Disabled- und Read-only-Zustände. |
data-invalid | Vorhanden, wenn ein umgebendes Field den Wert als ungültig markiert. |
data-disabled | Vorhanden, wenn das Feld deaktiviert ist. |
data-focused | Vorhanden, solange das Feld den Fokus hat. |
data-filled | Vorhanden, wenn das Feld einen Wert hat. |
data-dirty | Vorhanden, sobald sich der Wert vom Anfangswert unterscheidet. |
data-touched | Vorhanden, sobald das Feld fokussiert und wieder verlassen wurde. |
| Prop | Typ | Standard |
|---|---|---|
align | "inline-start" | "inline-end" | "block-start" | "block-end" | "inline-start" |
separatorZeichnet eine Haarlinie zwischen einem Block-Addon und dem Feld. | boolean | false |
| Attribut | Beschreibung |
|---|---|
data-slot="input-group-addon" | Addons in CSS ansprechen. |
data-align | Die aktuelle Ausrichtung. |
data-separator | Vorhanden, wenn separator gesetzt ist. |
--input-group-addon-inset | Abstand zwischen dem Rand der Gruppe und einem Button oder einer Tastenkappe darin. |
| Prop | Typ | Standard |
|---|---|---|
variant | "default" | "outline" | "secondary" | "ghost" | "destructive" | "link" | "ghost" |
size | "xs" | "sm" | "icon-xs" | "icon-sm" | "xs" |
type | string | "button" |
feedbackJede Button-Prop funktioniert, auch der Lade- und Erfolgsablauf. | boolean | false |
| Attribut | Beschreibung |
|---|---|
data-slot="input-group-button" | Addon-Buttons in CSS ansprechen. |
data-size | Die aktuelle Größe. |
| Prop | Typ | Standard |
|---|---|---|
onClearWird aufgerufen, nachdem das Feld geleert wurde. | () => void | – |
aria-label | string | "Clear" |
children | ReactNode | <IconX /> |
| Attribut | Beschreibung |
|---|---|
data-slot="input-group-clear" | Den Löschen-Button in CSS ansprechen. |
data-visible | Vorhanden, solange das Feld einen Wert hat und bearbeitbar ist. |
| Prop | Typ | Standard |
|---|---|---|
revealedGesteuerter State. Nicht setzen, damit es sich selbst verwaltet. | boolean | – |
onRevealedChange | (revealed: boolean) => void | – |
aria-label | string | "Show password" |
| Attribut | Beschreibung |
|---|---|
data-slot="input-group-password-toggle" | Den Umschalter in CSS ansprechen. |
data-revealed | Vorhanden, solange das Passwort angezeigt wird. |
| Prop | Typ | Standard |
|---|---|---|
thresholdVerbleibende Zeichen, ab denen die Zahl hervortritt. | number | 10% of maxLength, at most 20 |
announcementMeldung für Screenreader, wenn die Zeichenzahl den Schwellenwert überschreitet oder das Limit erreicht. | (remaining: number) => string | – |
| Attribut | Beschreibung |
|---|---|
data-slot="input-group-count" | Den Zähler in CSS ansprechen. |
data-state="near" | "limit" | Vorhanden innerhalb des Schwellenwerts und wenn keine Zeichen mehr übrig sind. |
data-bump | Kurz vorhanden, wenn am Limit eine Taste gedrückt wird. |
| Attribut | Beschreibung |
|---|---|
data-slot="input-group-text" | Addon-Text in CSS ansprechen. |
- ButtonButtons in allen Varianten und Größen, mit eingebautem Lade-, Erfolgs- und Fehlerablauf, der den Spinner bei schnellen Anfragen überspringt.
- 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.
- MotionDie Easing-Kurven, Dauern und der Reduced-Motion-Check, mit denen jede Komponente animiert, plus Hooks für Größen-Morphs und gleitende Hervorhebungen.
- useAutosizeLässt eine Textarea mit dem Geschriebenen zwischen minimaler und maximaler Höhe wachsen und animiert jede Änderung, ohne je den Text anzufassen.
- useComposedRefBehält eine Ref auf dein eigenes Element und leitet sie trotzdem an die Ref weiter, die der Parent übergeben hat.
- useInvalidShakeLässt ein Formularelement wackeln, wenn ein Absendeversuch es als ungültig findet, und nie, während noch getippt wird.
In Blocks verwendet
Blocks, die auf Input group aufbauen.
- BillingPlan & Nutzung für ein KI-Produkt, im Stil von Cursor, Claude und Vercel. Eine nach Modell aufgeteilte Nutzungsanzeige, die das Ende des Zyklus hochrechnet und warnt, bevor die Credits ausgehen, ein tägliches Diagramm zum Scrubben, ein Ausgabenlimit mit Warnungen, die du auf der Anzeige in der Vorschau siehst, Planwechsel mit exakter Anteilsberechnung, ein Kartenformular mit echter Validierung und Rechnungen als PDF-Download.
- Diff ReviewPrüfe die Änderungen eines Agenten über mehrere Dateien, bevor sie übernommen werden. Ein Dateibaum mit Zählern, jede Änderung, jede Datei oder alles annehmen oder ablehnen, Kommentare zu jeder Zeile oder jedem Bereich, die an den Agenten zurückgehen, Unified- und Split-Ansicht, Hervorhebung auf Wortebene, Rückgängig, streamende Änderungen und eine Zusammenfassung „4 Dateien bearbeitet“ für den Chat.
- ModelsDie Modelle-Seite in den Einstellungen eines KI-Produkts. Ein Standardmodell mit Kontext, Geschwindigkeit und Kosten auf einen Blick, ein Standard-Effort, der weiß, was jedes Modell unterstützt, eine durchsuchbare Modellliste nach Anbieter gruppiert mit Filtern, Pins und Sammelschaltern, OpenAI-kompatible Server mit echtem Verbindungstest und ein Refresh, der dir sagt, was neu ist.
- ProfileDer Bereich „Profil“ in den Einstellungen eines KI-Produkts. Ein Foto kreisförmig zuschneiden, einen Benutzernamen wählen, der beim Tippen geprüft wird, eine neue E-Mail mit einem 6-stelligen Code bestätigen, Links hinzufügen, die die Website erkennen, und eine Live-Karte sehen, wie andere dich sehen.