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.)

Source Topic

ux psychology

Form Design

Reducing friction in data entry