Capítulo 23 de 108

Input Group

Core Idea

InputGroup embeds icons, text, buttons, kbd hints, dropdowns, or spinners directly inside an input or textarea's visual boundary, replacing the plain Input/Textarea with group-aware variants (InputGroupInput, InputGroupTextarea) plus positioned InputGroupAddon slots.

Key Concepts

  • InputGroupInput / InputGroupTextarea: drop-in replacements for Input/Textarea inside a group; pre-styled and share data-slot="input-group-control" for unified focus handling. All native input/textarea props pass through.
  • InputGroupAddon: positions content relative to the control via align: "inline-start" (default) | "inline-end" | "block-start" | "block-end". Inline aligns pair with InputGroupInput; block aligns pair with InputGroupTextarea.
  • DOM order matters for focus: InputGroupAddon must be placed after the input/textarea in the DOM regardless of visual align position, this is required for correct focus navigation.
  • InputGroupButton: button styled for embedding inside an addon; size: xs | icon-xs | sm | icon-sm (default xs), variant same set as Button (default ghost).
  • InputGroupText: plain text/label content inside an addon (e.g. a static https:// prefix).
  • Multiple buttons/icons per addon: an InputGroupAddon can contain several InputGroupButtons or icons together.

Code Examples

<InputGroup className="max-w-xs">
  <InputGroupInput placeholder="Search..." />
  <InputGroupAddon>
    <Search />
  </InputGroupAddon>
  <InputGroupAddon align="inline-end">12 results</InputGroupAddon>
</InputGroup>
  • O que demonstra: ícone de busca no início + contador de resultados no final, dois addons no mesmo grupo.
<InputGroup>
  <InputGroupTextarea placeholder="Enter message..." />
  <InputGroupAddon align="block-end">
    <InputGroupButton>Send</InputGroupButton>
  </InputGroupAddon>
</InputGroup>
  • O que demonstra: textarea com botão de envio ancorado embaixo (block-end), padrão de chat input.
<InputGroupAddon>
  <InputGroupButton>Button</InputGroupButton>
  <InputGroupButton>Button</InputGroupButton>
</InputGroupAddon>
<InputGroupButton size="icon-xs" aria-label="Copy">
  <CopyIcon />
</InputGroupButton>
  • O que demonstra: múltiplos botões no mesmo addon, e botão apenas-ícone com aria-label.

Reference Tables

ComponentPropTypeDefault
InputGroupclassNamestring
InputGroupAddonalign"inline-start" | "inline-end" | "block-start" | "block-end""inline-start"
InputGroupButtonsize"xs" | "icon-xs" | "sm" | "icon-sm""xs"
InputGroupButtonvariant"default" | "destructive" | "outline" | "secondary" | "ghost" | "link""ghost"
InputGroupInput(all Input props pass through)
InputGroupTextarea(all Textarea props pass through)

Composition

InputGroup
├── InputGroupInput or InputGroupTextarea
├── InputGroupAddon
├── InputGroupButton
└── InputGroupText

Anti-patterns

  • Placing InputGroupAddon before the input/textarea in the DOM: breaks focus navigation even if align="inline-start" makes it look correct visually.
  • Using block-start/block-end with InputGroupInput (or inline-* with InputGroupTextarea): mismatched, block aligns are for textarea, inline for single-line input.
  • Using plain Input/Textarea inside InputGroup: use InputGroupInput/InputGroupTextarea instead, they carry the required group styling and focus data-slot.

Key Takeaways

  1. Also supports Kbd hints, DropdownMenu triggers, and Spinner as addon content (documented in dedicated sub-sections beyond this summary), same addon/align mechanics apply.
  2. This is the mechanism referenced from Input's own docs for anything beyond a bare text field (prefixes, icons, inline buttons).
  3. InputGroupButton defaults to ghost variant and small sizes since it lives inside a bordered group, not as a standalone CTA.

Connects To

  • components-input: InputGroup is the escape hatch when a plain Input isn't enough.
  • components-button: InputGroupButton shares the same variant vocabulary as Button.
  • components-button-group: both compose together (see Button Group's "Input Group" section).