Input

A flexible text input component for forms. Supports labels, hints, icons, validation states, and multiple sizes. Available as compound components for maximum flexibility or as a pre-composed TextInput for simple use cases.

Basic Usage

import { TextInput } from '@/components'

<TextInput placeholder="Enter your name..." />

With Label and Hint

Add a label and helper text to guide users.

<TextInput
  label="Email Address"
  placeholder="john@example.com"
  hint="We'll never share your email with anyone."
/>

We'll never share your email with anyone.

Sizes

The input comes in three sizes: small (36px), medium (40px, default), and large (44px).

Small (36px)

Medium (40px) - Default

Large (44px)

Small

<TextInput size="sm" label="Small Input" placeholder="Small size..." />

Medium (Default)

<TextInput size="md" label="Medium Input" placeholder="Medium size..." />

Large

<TextInput size="lg" label="Large Input" placeholder="Large size..." />

States

The input has multiple visual states: Default (idle), Hover, Focus, Filled, Disabled, and Error.

Default (Idle)

Filled

Focus (click to focus)

Required Fields

Use the required prop to show a required indicator (blue asterisk).

<TextInput
  label="Username"
  placeholder="Enter username..."
  hint="This field is required"
  required
/>

This field is required

Optional Fields

Use showOptionalBadge to indicate optional fields.

<TextInput
  label="Nickname"
  placeholder="Enter nickname..."
  showOptionalBadge
/>

This field is optional

With Tooltip

Add a tooltip to the info icon to provide additional context without cluttering the UI. The info icon automatically appears when a tooltip prop is provided.

<TextInput
  label="API Key"
  placeholder="Enter your API key..."
  hint="Keep your API key secure"
  tooltip="Your API key is used to authenticate requests to the server. Never share it publicly."
/>

Keep your API key secure

Keep your API key secure

With Icons

Add icons to the left and/or right of the input.

Left icon

Right icon

Both icons

Left Icon

<TextInput
  label="Username"
  placeholder="Enter username..."
  leftIcon={<User />}
/>

Right Icon

<TextInput
  label="Search"
  placeholder="Search..."
  rightIcon={<Search />}
/>

Both Icons

<TextInput
  label="Email"
  placeholder="Search contacts..."
  leftIcon={<Mail />}
  rightIcon={<Search />}
/>

Keyboard Shortcut Badge

Display a keyboard shortcut badge inside the input.

<TextInput
  label="Quick Search"
  placeholder="Search..."
  leftIcon={<Search />}
  kbd="⌘+K"
/>
⌘+K

Error State

Show validation errors with the error prop. Pass a string to display an error message, or true for styling only.

Error with message

Please enter a valid email address

Error styling only

Password must be at least 8 characters

Error with Message

<TextInput
  label="Email"
  placeholder="Enter email..."
  error="Please enter a valid email address"
/>

Error Styling Only

<TextInput
  label="Password"
  type="password"
  error
  hint="Password must be at least 8 characters"
/>

Disabled State

Disabled inputs cannot be interacted with.

Disabled empty

Disabled with value

<TextInput label="Disabled" placeholder="Cannot edit..." disabled />

Compound Components

For maximum flexibility, use the compound component API to build custom input layouts.

import { Input } from '@/components'

<Input.Root size="md" required>
  <Input.Label>
    Full Name
    <Input.RequiredIndicator />
    <Input.InfoIcon />
  </Input.Label>
  <Input.Field>
    <Input.LeftSlot>
      <User />
    </Input.LeftSlot>
    <Input.NativeInput placeholder="Enter your full name..." />
  </Input.Field>
  <Input.Hint>Please enter your legal name.</Input.Hint>
</Input.Root>

Please enter your legal name as it appears on documents.

Password Input

A convenience wrapper for password inputs with built-in visibility toggle and lock icon.

import { PasswordInput } from '@/components'

<PasswordInput label="Password" placeholder="Enter password..." />

Password Input Sizes

Small (36px)

Medium (40px) - Default

Large (44px)

Password Input States

Default

With hint

Must be at least 8 characters

Error

Password is too weak

Disabled

Without Lock Icon

Hide the lock icon with showLeftIcon={false}.

<PasswordInput label="Password" showLeftIcon={false} />

With Password Strength Indicator

Compose PasswordInput with PasswordStrength for password creation forms.

const [password, setPassword] = useState('')
const passedCount = defaultRequirements.filter((req) => req.validator(password)).length
const isComplete = passedCount === defaultRequirements.length

<PasswordInput
  label="Create Password"
  required
  value={password}
  onChange={(e) => setPassword(e.target.value)}
  error={password.length > 0 && !isComplete}
/>
<PasswordStrength password={password} />

Must contain at least;

At least 1 symbol
At least 1 uppercase
At least 1 number
At least 8 characters

Advanced: Compound Components

For maximum flexibility, use the compound component API to build custom password input layouts.

Must be at least 8 characters

const [showPassword, setShowPassword] = useState(false)

<Input.Root size="md" required>
  <Input.Label>
    Password
    <Input.RequiredIndicator />
  </Input.Label>
  <Input.Field>
    <Input.LeftSlot>
      <Lock />
    </Input.LeftSlot>
    <Input.NativeInput
      type={showPassword ? 'text' : 'password'}
      placeholder="Enter password..."
    />
    <Input.RightSlot>
      <button onClick={() => setShowPassword(!showPassword)}>
        {showPassword ? <EyeClosed /> : <Eye />}
      </button>
    </Input.RightSlot>
  </Input.Field>
  <Input.Hint>Must be at least 8 characters</Input.Hint>
</Input.Root>

Controlled Input

Control the input value externally with validation feedback.

Minimum 3 characters required

Current value: (empty)
const [value, setValue] = useState('')
const isValid = value.length >= 3

<TextInput
  label="Username"
  placeholder="Enter username..."
  value={value}
  onChange={(e) => setValue(e.target.value)}
  error={value.length > 0 && !isValid ? 'Username must be at least 3 characters' : undefined}
  hint={isValid ? 'Username is valid!' : 'Minimum 3 characters required'}
  required
/>

All States Overview

Small (36px)

Default

This is a hint text to help users.

Disabled

This is a hint text to help users.

Error

This is a hint text to help users.

Medium (40px)

Default

This is a hint text to help users.

Disabled

This is a hint text to help users.

Error

This is a hint text to help users.

Large (44px)

Default

This is a hint text to help users.

Disabled

This is a hint text to help users.

Error

This is a hint text to help users.

Accessibility

  • Labels are properly associated with inputs via htmlFor/id
  • aria-describedby connects hint/error text to the input
  • aria-invalid is set when in error state
  • aria-required is set for required fields
  • Focus states are clearly visible
  • Full keyboard navigation support

API Reference

TextInput Props

PropTypeDefaultDescription
labelstring-Label text above the input
hintstring-Helper text below the input
errorboolean | stringfalseError state or error message
size'sm' | 'md' | 'lg''md'Input size variant
leftIconReactNode-Icon on the left side
rightIconReactNode-Icon on the right side
kbdstring-Keyboard shortcut badge
showOptionalBadgebooleanfalseShow "(Optional)" badge
showInfoIconbooleanfalseShow info icon in label
tooltipstring-Tooltip content for the info icon (auto-shows icon)
disabledbooleanfalseDisable the input
requiredbooleanfalseMark as required

All standard HTML input attributes are also supported.

PasswordInput Props

PropTypeDefaultDescription
labelstring-Label text above the input
hintstring-Helper text below the input
errorboolean | stringfalseError state or error message
size'sm' | 'md' | 'lg''md'Input size variant
showVisibilityTogglebooleantrueShow/hide password toggle button
defaultVisiblebooleanfalseInitial password visibility state
onVisibilityChange(visible: boolean) => void-Callback when visibility changes
showLeftIconbooleantrueShow lock icon on left
showOptionalBadgebooleanfalseShow "(Optional)" badge
showInfoIconbooleanfalseShow info icon in label
tooltipstring-Tooltip content for the info icon (auto-shows icon)
disabledbooleanfalseDisable the input
requiredbooleanfalseMark as required

All standard HTML input attributes (except type) are also supported.

Compound Components

ComponentDescription
Input.RootContainer that provides context (size, state, error, required)
Input.LabelLabel element with proper association
Input.RequiredIndicatorBlue asterisk for required fields
Input.OptionalBadge"(Optional)" text badge
Input.InfoIconInfo icon in label row
Input.FieldInput field wrapper with border and states
Input.LeftSlotLeft icon/content container
Input.RightSlotRight icon/content container
Input.NativeInputThe actual <input> element
Input.KbdKeyboard shortcut badge
Input.HintHint/error text below the field