InputGroup
An input with addons — prefixes, suffixes and inline actions inside one ring.
@luc/ui/formsExamples
Amount with a currency
Addons and the field share one shell, so focus rings the whole group rather than a fragment of it.
<InputGroup>
<InputGroupAddon>$</InputGroupAddon>
<InputGroupSeparator />
<InputGroupInput defaultValue="120000" aria-label="Notional" />
<InputGroupSeparator />
<InputGroupAddon>USD</InputGroupAddon>
</InputGroup>A leading icon
`align` decides which edge the addon sits on and which way the separator points; an icon addon is decoration, so the field keeps the accessible name.
<InputGroup>
<InputGroupAddon align="start"><RiSearchLine /></InputGroupAddon>
<InputGroupInput placeholder="Search instruments" aria-label="Search instruments" />
</InputGroup>A trailing unit
A unit is an addon on the `end` edge; make it `interactive` and it becomes a real target instead of a label — the difference between a suffix and an action inside the group.
<InputGroup>
<InputGroupInput placeholder="0.00" aria-label="Rebalance threshold" />
<InputGroupAddon align="end">%</InputGroupAddon>
</InputGroup>Sizes, disabled and invalid
The group owns the state so every part of the shell agrees: `disabled` reaches the input, and `invalid` draws one treatment around the whole group.
<InputGroup size="sm">…</InputGroup>
<InputGroup disabled>…</InputGroup>
<InputGroup invalid>…</InputGroup>Usage
import { InputGroup, InputGroupAddon, InputGroupInput } from "@luc/ui/forms";<InputGroup>
<InputGroupAddon>$</InputGroupAddon>
<InputGroupInput defaultValue="120000" aria-label="Notional" />
</InputGroup>Package setup — peer requirements, the stylesheet and the provider — is on installation.
API
Read from the published TypeScript API, so a prop that is not listed here does not exist and a default that is listed is the one the compiler sees.
| Export | Kind | Signature |
|---|---|---|
InputGroup | 3 documented props | ({ className, size, invalid, disabled, children, ...props }: InputGroupProps) => import("@types/react").JSX.Element |
InputGroupAddon | 2 documented props | ({ className, align, interactive, ...props }: InputGroupAddonProps) => import("@types/react").JSX.Element |
InputGroupInput | export | ({ className, ...props }: InputGroupInputProps) => import("@types/react").JSX.Element |
InputGroupSeparator | export | ({ className, ...props }: React.ComponentPropsWithRef<"span">) => import("@types/react").JSX.Element |
InputGroup props
Type: InputGroupProps
Values the compiler reads from the declaration.
| Prop | Type | Default | Notes |
|---|---|---|---|
disabled? | boolean | undefined | — | |
invalid? | boolean | undefined | — | |
size? | "sm" | "md" | "lg" | undefined | — |
InputGroupAddon props
Type: InputGroupAddonProps
Values the compiler reads from the declaration.
| Prop | Type | Default | Notes |
|---|---|---|---|
align? | "start" | "end" | undefined | — | Which edge the addon sits on. Drives the separator direction. |
interactive? | boolean | undefined | — | Make the addon interactive — it becomes a real button-like target. |
Guidelines
Do
- Use it when the affixes belong to the value — a currency, a unit, a search icon, a trailing action.
- Put the state on the group (`size`, `disabled`, `invalid`) so every part of the shell agrees.
- Use `InputGroupSeparator` when the pieces are different kinds of thing; skip it when a prefix simply sits against the value.
Don't
- Reach for addons when a `Field` description would carry the unit more cheaply.
- Make an addon interactive without saying so: only `interactive` addons are real targets, and the rest are labels.
- Split one value across two inputs with a separator in the middle.
Accessibility
The group draws one focus ring around field and affixes, and the state on the group reaches the input. A decorative icon addon is `aria-hidden`, so it never becomes part of the field's name.
Family
Forms
Inputs, their validation surfaces and the form lifecycle around them.
24 documented entries in this family. Open the family index
Related