Components · shadcn field, input, textarea, checkbox, radio-group
Form fields
Label, optional marker, control, helper, error. Labels are always visible, optional fields are marked instead of required ones, and every error says how to fix it.
Anatomy
Used on your member card.
Two or three sentences are enough.
Show codeHide code
<Field>
<FieldLabel htmlFor="nickname" optional>Nickname</FieldLabel>
<Input id="nickname" autoComplete="nickname" aria-describedby="nickname-help" />
<FieldDescription id="nickname-help">Used on your member card.</FieldDescription>
</Field>States
| State | Behavior |
|---|---|
| Hover | The border darkens to text. |
| Focus-visible | The global outline. |
| Invalid | aria-invalid: the border turns danger and thickens without shifting layout; the error message appears. |
| Disabled | surface fill, subtle text. |
| Read-only | surface fill, normal text. |
| Loading | Async validation (checking a student ID): a small spinner in the field, aria-busy. |
Filled in from your registration.
Show codeHide code
<Input aria-invalid aria-describedby="nim-error" />
<FieldError id="nim-error">Enter your 9-digit student ID without spaces.</FieldError>Checkbox and radio
Base UI controls that fill with the accent when checked, each in a full-row label at least 44px tall. Groups use <fieldset> and <legend>. Multi-select is a checkbox group, never a multi-select dropdown.
Show codeHide code
<FieldSet>
<FieldLegend>Preferred division</FieldLegend>
<RadioGroup defaultValue="humas">
<Field orientation="horizontal">
<RadioGroupItem value="humas" id="humas" />
<FieldLabel htmlFor="humas">Hubungan Masyarakat</FieldLabel>
</Field>
</RadioGroup>
</FieldSet>Error summary
Validate on blur and on submit, never per keystroke. A failed submit shows a summary at the top (role="alert") with links to each field, and moves focus to it. Try submitting the form empty.
Show codeHide code
<Alert variant="danger" live>
<AlertTitle>Check these 2 answers</AlertTitle>
<AlertDescription><ul><li><a href="#nim">Enter your 9-digit student ID without spaces.</a></li></ul></AlertDescription>
</Alert>Rules
- Placeholders show example formats only, never instructions.
- Use
autoCompleteandinputMode. Input text is at least 16px so iOS doesn't zoom. <label for>on every control;aria-describedbypointing at the helper and error ids that exist.
Don’t
Placeholders as labels, a disabled submit until the form is valid, “Invalid input”.
Do
Visible labels, “(optional)” markers, an error summary plus inline fixes: “Enter your campus email ending in .edu.cn”.

