Installation
Barrel
// code example
Granular
// code example
Usage
With Built-in Field (Recommended)
Pass the label prop to InputGroup to enable the built-in Field wrapper with
label, description, and error support.
export default function Example() {
return (
<InputGroup label="Search" description="Find pages, components, and more">
<InputGroup.Addon>
<MagnifyingGlassIcon />
</InputGroup.Addon>
<InputGroup.Input placeholder="Search..." />
</InputGroup>
);
}
Bare InputGroup (Custom Layouts)
For custom form layouts, use InputGroup without label. Must provide aria-label on InputGroup.Input for accessibility.
export default function Example() {
return (
<InputGroup>
<InputGroup.Addon>
<MagnifyingGlassIcon />
</InputGroup.Addon>
<InputGroup.Input placeholder="Search..." aria-label="Search" />
</InputGroup>
);
}
Examples
Icon
Use Addon to place an icon at the start of the input as a visual identifier.
Text
Use Addon to place text prefixes or suffixes alongside the input.
Button
Place InputGroup.Button inside an Addon for actions that operate directly on
the input value, such as reveal/hide or clear.
Button with Tooltip
Pass a tooltip prop to InputGroup.Button to show a tooltip on hover. When
no explicit aria-label is provided, the button derives it from a string
tooltip value.
Kbd
Place a keyboard shortcut hint inside an end Addon.
Loading
Place a Loader inside an end Addon as a status indicator while validating the input value.
Inline Suffix
Suffix renders text that flows seamlessly next to the typed value — useful for
domain inputs like .workers.dev. Pair with a status icon Addon to show
validation state.
Sizes
Four sizes: xs, sm, base (default), and lg. The size applies to the
entire group.
States
Various input states including error, disabled, and with description. Pass label, error, and description props directly to InputGroup.
API Reference
InputGroup
The root container that provides context to all child components. Accepts
Field props (label, description, error) and wraps content in a Field
when label is provided.
InputGroup.Input
The text input element. Inherits size, disabled, and error from
InputGroup context. Accepts all standard input attributes except Field-related
props which are handled by the parent.
InputGroup.Addon
Container for icons, text, or compact buttons positioned at the start or end of the input.
InputGroup.Button
Button for secondary actions like toggle, copy, or help. Renders inside an
Addon. Pass a tooltip prop to show a tooltip on hover.
InputGroup.Suffix
Inline text that flows seamlessly next to the typed value (e.g., .workers.dev). The input width adjusts automatically as the user types.
Validation Error Types
When using error as an object, the match property corresponds to HTML5 ValidityState values:
| Match | Description |
|---|---|
| valueMissing | Required field is empty |
| typeMismatch | Value doesn't match type (e.g., invalid email) |
| patternMismatch | Value doesn't match pattern attribute |
| tooShort | Value shorter than minLength |
| tooLong | Value longer than maxLength |
| rangeUnderflow | Value less than min |
| rangeOverflow | Value greater than max |
| true | Always show error (for server-side validation) |
Accessibility
### Label Requirement
InputGroup requires an accessible name via one of:
<ul class="mt-2 ml-4 list-disc space-y-1">
<li>
`label` prop on InputGroup (renders a visible label with built-in
Field support)
</li>
<li>
`aria-label` on InputGroup.Input for inputs without a visible label
</li>
<li>
`aria-labelledby` on InputGroup.Input for custom label association
</li>
</ul>
<p class="mt-2">
Missing accessible names trigger console warnings in development.
### Group Role
InputGroup automatically renders with `role="group"`, which semantically
associates the input with its addons for assistive technologies.