Forms
Input, Textarea, Label and Switch: smooth focus rings, native :user-invalid validation (red only after interaction), aria-invalid, auto-growing textarea with an optional character count, and a spring switch.
Create account
Focus, invalid and disabled states.
import { Input } from "@/components/ui/input";import { Label } from "@/components/ui/label";import { Switch } from "@/components/ui/switch";import { Textarea } from "@/components/ui/textarea";export function SignUp({ error }: { error: boolean }) { return ( <form className="grid gap-4"> <div className="grid gap-2"> <Label htmlFor="email">Email</Label> <Input id="email" type="email" aria-invalid={error} /> </div> <div className="grid gap-2"> <Label htmlFor="bio">Bio</Label> <Textarea id="bio" maxLength={160} /> </div> <Switch defaultChecked /> </form> );}<Input>
Works inside <Field> (id and ARIA filled in) and <InputGroup> (chrome handed to the group).
Also accepts every <input> prop (none of its own).
<Textarea>
Auto-grows with content (field-sizing: content); cap with max-h-*. Resizable where unsupported (Firefox).
showCountbooleanShow "used / maxLength" in the corner (needs
maxLength). Turns warning, then red, near the end.
| Prop | Type | Default |
|---|---|---|
showCountShow "used / maxLength" in the corner (needs | boolean | — |
Also accepts every <textarea> prop.
<Label>
Also accepts every <label> prop (none of its own).
<Switch>
Native checkbox (role="switch") with a spring knob. Controlled or uncontrolled.
checkedbooleanControlled state; pair with
onCheckedChange.defaultCheckeddefaultfalsebooleanState at first render (uncontrolled).
onCheckedChange(checked: boolean) => voidCalled with the new state.
| Prop | Type | Default |
|---|---|---|
checkedControlled state; pair with | boolean | — |
defaultCheckedState at first render (uncontrolled). | boolean | false |
onCheckedChangeCalled with the new state. | (checked: boolean) => void | — |
Also accepts every <input> prop.
* required. Every component also takes className.