Inputs

Recessed fields with strict state management. The halo is reserved exclusively for the focused (active) state.

Input States
Default
Success
Error
Disabled
Default
Hover

Hover over the inputs above to see border color changes

Focus

Click an input to see the focus halo and lift animation

Physics Inputs use concave shadows (inset shadows) creating a recessed feel. The border changes instantly on interaction, while the focus halo (outer glow) appears with a subtle lift (-1px). This choreographed timing emphasizes the "pressed into surface" metaphor.

Helper text
Current State: default
Default
Resting state with concave inner shadow creating recessed feel
Hover
Border darkens instantly (no halo), maintaining concave depth
Focus
Blue halo appears with subtle lift (-1px) while maintaining inner shadow

Best Practices

Do

We'll never share your email
Always provide clear labels and helpful context
Must include numbers and symbols
Use placeholder for format hints, helper for requirements
Show real-time validation feedback with status

Don't

Don't omit labels—they're essential for accessibility
Don't show error state without explanation message
Don't use placeholder as primary instruction—use labels

Examples

We'll never share your email
<div className="input-anatomy">
  <label className="input-label">Email Address</label>
  <Input type="email" placeholder="you@example.com" />
  <div className="input-helper">
    <Icon name="info" size="sm" />
    We'll never share your email
  </div>
</div>
Great choice!
<div className="input-anatomy">
  <label className="input-label">
    Username
    <span className="input-label-status success">
      <Icon name="check" size="sm" />
      Available
    </span>
  </label>
  <Input status="success" value="gloss_designer" readOnly />
  <div className="input-helper" style={{ color: 'var(--alias-text-success)' }}>
    Great choice!
  </div>
</div>
Please enter a valid email
<div className="input-anatomy">
  <label className="input-label">
    Email
    <span className="input-label-status error">Invalid</span>
  </label>
  <Input status="error" value="not-an-email" readOnly />
  <div className="input-helper error">
    <Icon name="alert-circle" size="sm" />
    Please enter a valid email
  </div>
</div>
Click X to clear the input
<Input
  placeholder="Search..."
  value={searchValue}
  onChange={(e) => setSearchValue(e.target.value)}
  clearable
  onClear={() => setSearchValue('')}
/>
Click the copy icon to copy to clipboard
<Input
  value="sk_live_abc123xyz789"
  readOnly
  copyable
  onCopy={(value) => console.log('Copied:', value)}
/>
0/140
Character count shown when maxLength is set
<Input
  placeholder="Tell us about yourself..."
  maxLength={140}
  showCounter
/>
$USD
<Input
  placeholder="0.00"
  leftIcon={<span>$</span>}
  rightIcon={<span>USD</span>}
/>

Props Reference

PropTypeDefaultDescription
status'default' | 'success' | 'error' | 'pending''default'Validation/interaction status
leftIconReactNode-Icon or element on left side
rightIconReactNode-Icon or element on right side
clearablebooleanfalseShow clear button when input has value
onClear() => void-Callback when clear button is clicked
copyablebooleanfalseShow copy button to copy input value
onCopy(value: string) => void-Callback after successful copy
showCounterbooleanfalseShow character counter (requires maxLength)
renderCounter(current, max) => ReactNode-Custom counter renderer
iconAlign'top' | 'center''center'Vertical alignment of icons
labelstring-Label text for the input