Skip to main content
Theme UI provides a comprehensive set of form components with consistent styling and theme integration.

Components

Import

import {
  Input,
  Select,
  Textarea,
  Label,
  Checkbox,
  Radio,
  Switch,
  Slider,
} from 'theme-ui'

Input

Text input component with theme variants.

Usage

<Input placeholder="Enter text" />

Props

variant
string
default:"'input'"
Input variant from theme.forms.
<Input variant="input" />
<Input variant="search" />
autofillBackgroundColor
string
default:"'background'"
Background color for autofilled inputs. Maps to theme colors.
<Input autofillBackgroundColor="muted" />
type
string
HTML input type (text, email, password, etc.).
<Input type="email" placeholder="Email" />
<Input type="password" placeholder="Password" />

Examples

{/* Basic input */}
<Input placeholder="Your name" />

{/* Email input */}
<Input type="email" placeholder="[email protected]" />

{/* With label */}
<Label>
  Email
  <Input type="email" />
</Label>

{/* Custom styling */}
<Input
  sx={{
    borderColor: 'primary',
    '&:focus': {
      borderColor: 'secondary',
      outline: 'none',
    },
  }}
/>

Select

Dropdown select component with custom arrow indicator.

Usage

<Select>
  <option>Option 1</option>
  <option>Option 2</option>
</Select>

Props

variant
string
default:"'select'"
Select variant from theme.forms.
arrow
React.ReactElement
Custom arrow element to replace the default down arrow.
<Select arrow={<CustomArrow />}>
  <option>Option</option>
</Select>

Examples

{/* Basic select */}
<Select>
  <option>Choose one</option>
  <option value="1">Option 1</option>
  <option value="2">Option 2</option>
</Select>

{/* With label */}
<Label>
  Country
  <Select>
    <option>United States</option>
    <option>Canada</option>
    <option>Mexico</option>
  </Select>
</Label>

Textarea

Multi-line text input component.

Usage

<Textarea placeholder="Enter longer text" />

Props

variant
string
default:"'textarea'"
Textarea variant from theme.forms.
rows
number
Number of visible text rows.
<Textarea rows={5} />

Examples

{/* Basic textarea */}
<Textarea placeholder="Your message" />

{/* With label */}
<Label>
  Message
  <Textarea rows={4} />
</Label>

{/* Custom height */}
<Textarea sx={{ minHeight: 200 }} />

Label

Form label component for accessibility.

Usage

<Label>
  Field Name
  <Input />
</Label>

Props

htmlFor
string
Associates label with an input by ID.
<Label htmlFor="email">Email</Label>
<Input id="email" />
variant
string
default:"'label'"
Label variant from theme.forms.

Examples

{/* Wrapping input */}
<Label>
  Username
  <Input />
</Label>

{/* Using htmlFor */}
<Label htmlFor="email">Email Address</Label>
<Input id="email" type="email" />

{/* Inline label */}
<Label sx={{ display: 'inline-flex', alignItems: 'center' }}>
  <Checkbox />
  I agree to terms
</Label>

Checkbox

Checkbox input with custom styled appearance.

Usage

<Label>
  <Checkbox />
  Accept terms
</Label>

Props

variant
string
default:"'checkbox'"
Checkbox variant from theme.forms.
checked
boolean
Controlled checked state.
defaultChecked
boolean
Default checked state (uncontrolled).

Examples

{/* Basic checkbox */}
<Label>
  <Checkbox /> Subscribe to newsletter
</Label>

{/* Controlled checkbox */}
<Label>
  <Checkbox checked={isChecked} onChange={e => setIsChecked(e.target.checked)} />
  Toggle me
</Label>

{/* Multiple checkboxes */}
<Box>
  <Label><Checkbox /> Option 1</Label>
  <Label><Checkbox /> Option 2</Label>
  <Label><Checkbox /> Option 3</Label>
</Box>

Radio

Radio button input with custom styled appearance.

Usage

<Label>
  <Radio name="group" />
  Option 1
</Label>

Props

name
string
Radio group name. Required to link radio buttons together.
variant
string
default:"'radio'"
Radio variant from theme.forms.
checked
boolean
Controlled checked state.
value
string
Radio button value.

Examples

{/* Radio group */}
<Box>
  <Label>
    <Radio name="plan" value="basic" />
    Basic Plan
  </Label>
  <Label>
    <Radio name="plan" value="pro" />
    Pro Plan
  </Label>
  <Label>
    <Radio name="plan" value="enterprise" />
    Enterprise
  </Label>
</Box>

{/* Controlled radio */}
<Label>
  <Radio
    name="size"
    value="large"
    checked={size === 'large'}
    onChange={e => setSize(e.target.value)}
  />
  Large
</Label>

Switch

Toggle switch component for binary choices.

Usage

<Switch label="Enable notifications" />

Props

label
string
Label text for the switch.
<Switch label="Dark mode" />
variant
string
default:"'switch'"
Switch variant from theme.forms.
checked
boolean
Controlled checked state.
disabled
boolean
Disable the switch.

Examples

{/* Basic switch */}
<Switch label="Enable feature" />

{/* Controlled switch */}
<Switch
  label="Dark mode"
  checked={darkMode}
  onChange={e => setDarkMode(e.target.checked)}
/>

{/* Disabled switch */}
<Switch label="Feature disabled" disabled />

Slider

Range slider input component.

Usage

<Slider />

Props

variant
string
default:"'slider'"
Slider variant from theme.forms.
min
number
default:"0"
Minimum value.
max
number
default:"100"
Maximum value.
step
number
default:"1"
Step increment.
value
number
Controlled value.
defaultValue
number
Default value (uncontrolled).

Examples

{/* Basic slider */}
<Label>
  Volume
  <Slider />
</Label>

{/* Custom range */}
<Slider min={0} max={10} step={0.5} />

{/* Controlled slider */}
<Box>
  <Label>Brightness: {brightness}%</Label>
  <Slider
    value={brightness}
    onChange={e => setBrightness(e.target.value)}
  />
</Box>

{/* With display value */}
<Box>
  <Flex sx={{ justifyContent: 'space-between', mb: 2 }}>
    <Text>Price</Text>
    <Text>${price}</Text>
  </Flex>
  <Slider
    min={0}
    max={1000}
    value={price}
    onChange={e => setPrice(e.target.value)}
  />
</Box>

Form Example

Complete form example using multiple components:
<Box as="form" onSubmit={handleSubmit}>
  <Label htmlFor="name">
    Name
    <Input id="name" name="name" required />
  </Label>
  
  <Label htmlFor="email">
    Email
    <Input id="email" name="email" type="email" required />
  </Label>
  
  <Label htmlFor="country">
    Country
    <Select id="country" name="country">
      <option>United States</option>
      <option>Canada</option>
      <option>Other</option>
    </Select>
  </Label>
  
  <Label htmlFor="message">
    Message
    <Textarea id="message" name="message" rows={4} />
  </Label>
  
  <Label>
    <Checkbox name="newsletter" />
    Subscribe to newsletter
  </Label>
  
  <Label>
    <Switch label="Send me updates" name="updates" />
  </Label>
  
  <Button type="submit">Submit</Button>
</Box>

Build docs developers (and LLMs) love