Input Group
An input group wraps a form input together with optional prefix and suffix addons (icons, units, currency symbols, action buttons) inside a single ARIA group so that they are perceived and announced as one composite control.
Use it for currency fields with leading symbols, search fields with trailing icon buttons, percentage fields with trailing units, and any input where contextual addons clarify the value.
Implementation Notes
- Renders a
<div>withrole="group"andclass="input-group" - Optional prefix renders inside
<span class="input-group-prefix"> - Optional suffix renders inside
<span class="input-group-suffix"> - Children (the actual input) sit between the prefix and suffix
aria-labelis rendered when thelabelprop is provided- Does not modify the inner input — the consumer is responsible for label association on the input itself
Props
label: string (optional) -- aria-label for the groupprefix: slot (optional) -- content rendered before the inputsuffix: slot (optional) -- content rendered after the inputchildren: slot -- the input the consumer places inside...restProps: any additional HTML attributes
Usage
Currency input with leading symbol:
<InputGroup label="Amount">
<span slot="prefix">$</span>
<TextInput label="Amount" value={amount} onChange={setAmount} />
</InputGroup>
Search input with trailing icon button:
<InputGroup label="Search">
<SearchInput label="Search" value={query} onChange={setQuery} />
<IconButton slot="suffix" label="Submit search" onclick={submit}>
🔍
</IconButton>
</InputGroup>
Percentage input with trailing unit:
<InputGroup label="Discount">
<NumberInput label="Discount" value={discount} onChange={setDiscount} />
<span slot="suffix">%</span>
</InputGroup>
Keyboard Interactions
- The wrapped input retains its native keyboard behavior.
- Focusable controls inside
prefix/suffixslots (e.g., IconButton) follow their own keyboard behavior.
ARIA
role="group"on the wrapping<div>so assistive technology treats the addons and input as one unitaria-labelrendered whenlabelis provided- The inner input still requires its own accessible name (label, aria-label, or aria-labelledby)
When to Use
- Use to attach a prefix or suffix addon to a form input.
- Use for currency, percentage, and unit inputs.
- Use for search inputs with trailing action buttons.
When Not to Use
- Do not use as a generic form layout (use Field for label/input/error composition).
- Do not omit a label on the inner input — the group's aria-label does not replace the input's accessible name.
Headless
Provides only the structural wrapper, the prefix and suffix slot containers, and the ARIA group semantics. Visual treatment such as connected borders, addon backgrounds, and focus styling is entirely consumer-supplied.
Styles
Consumer CSS targets .input-group, .input-group-prefix, and .input-group-suffix to apply visual treatment such as shared borders, addon backgrounds, and connected radii.
Testing
- Verify the component renders a
<div>element with classinput-groupandrole="group" - Verify
aria-labelis rendered when thelabelprop is provided - Verify the prefix renders inside
<span class="input-group-prefix">when provided - Verify the suffix renders inside
<span class="input-group-suffix">when provided - Verify children render between prefix and suffix
- Verify focus order is prefix → input → suffix
Advice
- Designers: Use prefix and suffix addons sparingly — overusing them clutters forms. Reserve them for unit symbols, currency markers, and trailing action buttons.
- Developers: Continue to apply a label on the inner input itself (via
<label>,aria-label, oraria-labelledby); the group'slabelprop names the composite control, not the input.
Related components
input— a generic HTML input elementfield— a form field wrapper with label, input, and error messageform— a form element for collecting and submitting user data
References
- WAI-ARIA group role: https://www.w3.org/TR/wai-aria-1.2/#group
- WCAG 1.3.1 Info and Relationships: https://www.w3.org/WAI/WCAG22/Understanding/info-and-relationships