Build Assets
UI Component
Text Input
Single-line text field for user-entered data with label, placeholder, and validation states.
Platform: bothTags: form, input, text, validation
Purpose
Collects a single line of text input. Always paired with a visible label — never use placeholder as label.
Anatomy
- Label: 14px medium, above the field, never inside
- Input container: 1px border, 8px corner radius
- Placeholder text: 14px, tertiary color (never replaces label)
- Helper text: 12px below field, secondary color
- Error message: 12px below field, error color + error icon
States
- Default: border var(--color-border)
- Focus: border var(--color-accent), focus ring
- Filled: same as default, content visible
- Error: border var(--color-error), error message shown below
- Disabled: 40% opacity, background var(--color-bg-secondary)
- Read-only: no border change, cursor default
Tokens
spacing
paddingX: 12pxpaddingY: 10pxlabelGap: 6pxhelperGap: 4px
sizing
height: 40pxborderRadius: 8pxborderWidth: 1px
Do
- Always show the label above the field — visible at all times
- Show validation errors inline, immediately below the field
- Use placeholder for example input, not instructions
- Mark required fields with an asterisk and legend
Don't
- Use placeholder text as the only label
- Show all validation errors only on form submit
- Use red borders without an error message explaining what went wrong
- Stack more than one instruction inside the field
Accessibility
- label element must be associated via htmlFor / id pair
- Error messages must be linked via aria-describedby
- aria-invalid="true" on the input when in error state
- autocomplete attribute for common fields (email, name, etc.)