Skip to content
HyperDesign System

Input group

An input or textarea with addons inside its border: icons, units, keycaps and small buttons. The group is the pill and owns the focus ring, so the whole thing reads as one field. Source: src/components/ui/input-group.tsx.

Addons

An addon is inline-start by default. Icons are 16px and muted; InputGroupText carries units. Click an icon and the input takes focus.

/
icon + keycap
USD / month
icon + unit text

Buttons

InputGroupButton is a ghost Button scaled to fit (24px). Use icon-xs with an aria-label for a lone icon, xs for a word.

Show or hide a secret

Copy a value

Textarea and block addons

Put an InputGroupTextarea inside and add a block-end addon: the group becomes a 12px-corner column with a toolbar under the text. This is the composer's shape.

Type, then press the arrow or Cmd/Ctrl+Enter.

States

The group mirrors its control: focus rings the whole shell, aria-invalid on the control turns it destructive, a disabled control fades the group to 50%. The error text is yours; there is no Field primitive.

Handles can't contain spaces.

Props

Six parts. None of them has a variant of its own beyond what is listed.

Input group props
PropTypeDefaultDescription
InputGroupComponentProps<"div">—The shell: role="group", a 32px pill with the input outline. It reads focus, disabled and aria-invalid from its control with :has(), so you style nothing.
InputGroupAddon align"inline-start" | "inline-end" | "block-start" | "block-end""inline-start"Where the addon sits. block-* stacks it above or below and turns the shell into a 12px-corner column. Clicking an addon focuses the group's input.
InputGroupButton size"xs" | "sm" | "icon-xs" | "icon-sm""xs"A Button (default variant="ghost", type="button") sized to sit inside the field. All other Button props pass through.
InputGroupInputComponentProps<"input">—An Input with its own border and ring removed; marked data-slot="input-group-control".
InputGroupTextareaComponentProps<"textarea">—A Textarea without its box and with resize off. The shell grows with it.
InputGroupTextComponentProps<"span">—Muted inline text for a unit, a prefix or a domain.

Best practices

When to use

  • When something belongs inside the field: a search icon, a currency, a domain suffix, a reveal or copy button.
  • A plain field with no addon is an Input; don't wrap it in a group for nothing.

Behavior

  • Keep addons to one or two per side. A row of buttons is a toolbar under the field (block-end).
  • Don't put a submit button inside the group of a single-field form if Enter already submits; it doubles the action.
  • The shell is a pill (rounded-full); it changes to 12px corners only for textareas and block addons.

Accessibility

  • The control needs its own label: a Label with htmlFor, or an aria-label. The addon icon is decorative and aria-hidden.
  • Icon-only InputGroupButtons take an aria-label; a toggle (show/hide) also takes aria-pressed.
  • Announce transient results such as Copied in an aria-live region.

Content

  • Units go in InputGroupText, not in the placeholder, so they stay visible after typing.