Label, control and hint line with ids wired for screen readers; errors shake the control once and blur in under it.
formlabelhinterrorvalidationinput
Installation
$npx shadcn@latest add @geturui/field
Usage
usage.tsx
1import { Field, fieldWellClasses } from "@/components/ui/field";
2
3export function HandleField({ error }: { error?: string }) {
4 return (
5 <Field label="Workspace handle" required hint="Shown in your install command." error={error}>
6 {({ id, describedBy, invalid }) => (
7 <div className={fieldWellClasses({ invalid })}>
8 <input id={id} aria-describedby={describedBy} aria-invalid={invalid || undefined} className="h-full flex-1 bg-transparent outline-none" />
9 </div>
10 )}
11 </Field>
12 );
13}
Props
| Prop | Type | Default | Description |
|---|---|---|---|
label | ReactNode | — | Label text, linked to the control with htmlFor. |
hint | ReactNode | — | Helper text under the control. Hidden while an error message shows. |
error | ReactNode | boolean | — | Marks the field invalid. A string or node is shown and announced; true only colours it. |
required | boolean | false | Adds a volt asterisk after the label (pair with the control's required attribute). |
labelAside | ReactNode | — | Right side of the label row: Optional, a character count, a link. |
shakeOnError | boolean | true | Shake the control once when it turns invalid. |
children* | ReactNode | (ids: FieldIds) => ReactNode | — | The control. The function form gets id, labelId, describedBy and invalid to spread on it. |
fieldWellClasses() | ({ size, invalid, disabled, className }) => string | — | Class string for the sunken well text controls sit in. Heights 32 / 40 / 48 match Button. |
Accessibility
- The label targets the control by id, and the hint or error line is linked with aria-describedby.
- Errors carry an icon and a word, never colour alone; set aria-invalid on the control from the invalid flag.
- The shake is skipped when reduced motion is on.