Input
Text fields with labels, helper text, addons and inline validation.
Playground
A field is a label, a control and one line of helper or error text. Addons sit inside the same border through InputGroup, so focus and error rings wrap the whole thing.
We send the invite to this address.
Props
1import { Mail } from "lucide-react"2import { InputGroup, InputGroupInput, InputGroupAddon } from "@/components/ui/input-group"3import { Label } from "@/components/ui/label"45<div className="grid gap-1.5">6 <Label htmlFor="work-email">7 Work email8 <span aria-hidden className="text-destructive">*</span>9 </Label>10 <InputGroup>11 <InputGroupInput id="work-email" type="email" placeholder="name@company.com" required aria-describedby="work-email-help" />12 <InputGroupAddon>13 <Mail />14 </InputGroupAddon>15 </InputGroup>16 <p id="work-email-help" className="text-xs text-muted-foreground">17 We send the invite to this address.18 </p>19</div>States
Validation shows after blur or submit, never on the first keystroke. Loading keeps the value editable and says what is being checked; success is quiet and only used when the check is meaningful.
We send the invite here.
DefaultrestWe send the invite here.
Hover:hoverWe send the invite here.
Focus:focus-visibleChecking the address…
Loadingaria-busyManaged by your identity provider.
DisableddisabledFinish the domain, like maya@acme.com.
Erroraria-invalidAddress verified.
Successdata-state=success
Patterns
Working compositions. Every one keeps a visible label (or an sr-only one for search) and connects its helper, counter or rules with aria-describedby.
- At least 8 characters, not met yet
- One number, not met yet
- One symbol, not met yet
- Acme Corporation
- Northwind
- Globex
- Initech
7 of 7 companies. Press / to jump here.
Keep it to one or two sentences.
Formats to two decimals when you leave the field.
Lowercase letters, numbers and dashes. Opens at https://acme.app/northwind
Shown on invoices and in the client portal.
Screen reader announces
Company name, required, edit text, blank. Shown on invoices and in the client portal.
Keyboard
- Move to the next field or addon button
- Tab
- Clear the search field
- Esc
- Jump to search (demo)
- /
- Submit the surrounding form
- Enter
Semantics and ARIA
- Every input has a
<Label htmlFor>. A placeholder is an example, not a label; it disappears on typing and has low contrast. - Helper and error text are linked with
aria-describedby, so they are read after the label. The error replaces the helper rather than stacking under it. - Errors set
aria-invalid, use an icon plus text (never color alone) and say how to fix the value. - Addon icons are decorative and hidden from assistive tech. Addon buttons are real buttons with an
aria-label; the reveal toggle usesaria-pressedwith a stable label. - Inputs use 16px text below the md breakpoint so iOS does not zoom on focus, and set
autoCompleteandinputModefor autofill and the right keyboard. - Required fields use the native
requiredattribute; the asterisk isaria-hiddenbecause the attribute is already announced.