Form components handle user input. They should be clear, accessible, and provide helpful feedback at every step.
| Control | Height | States |
|---|
| Text input | 40px | default, focus, error, disabled |
| Textarea | auto (min 80px) | default, focus, error, disabled |
| Select | 40px | default, focus, error, disabled |
| Checkbox | 20×20px | unchecked, checked, indeterminate, disabled |
| Radio | 20×20px | unselected, selected, disabled |
| Toggle / Switch | 24×44px | off, on, disabled |
- Labels sit above the input, use
text-sm font-medium
- Required fields append a red asterisk or “(Required)” hint
- Helper text sits below the input,
text-xs text-gray-500
- Error messages replace helper text, use
text-xs text-red-600
| State | Border | Description |
|---|
| Default | gray-300 | Normal resting state |
| Focus | brand-500 + ring | Active, user is typing |
| Error | red-500 + ring | Failed validation, show error |
| Success | green-500 | Validated and accepted |
| Disabled | gray-200, bg gray-50 | Non-editable |
- Single column for most forms (easier to scan)
- Two columns only for related short fields (first/last name, city/zip)
- Group related fields into fieldsets with a legend
- Submit button aligned to the left (below the last field)