Skip to main content

Overview

The Input component provides a fully accessible text input with built-in support for labels, helper text, error messages, and icons. Built on React Aria Components for complete keyboard navigation and form integration.

Import

import { Input } from 'stride-ds';

Basic Usage

import { Input } from 'stride-ds';

function Example() {
  return (
    <Input 
      label="Email" 
      placeholder="Enter your email"
    />
  );
}

Variants

Default

Standard input appearance.
<Input 
  label="Username" 
  placeholder="Enter username"
/>

Success

Indicate successful validation.
<Input 
  label="Username" 
  variant="success"
  helperText="Username is available!"
  defaultValue="johndoe"
/>

Error

Show validation errors.
<Input 
  label="Email" 
  errorMessage="Please enter a valid email address"
  defaultValue="invalid-email"
/>

Sizes

Three size options are available:
<Input size="sm" label="Small Input" placeholder="Small" />
<Input size="md" label="Medium Input" placeholder="Medium" />
<Input size="lg" label="Large Input" placeholder="Large" />

With Icons

Left Icon

import { Mail } from 'lucide-react';

<Input 
  label="Email" 
  placeholder="Enter your email"
  leftIcon={<Mail size={16} />}
/>

Right Icon

import { Eye } from 'lucide-react';

<Input 
  label="Password" 
  type="password"
  placeholder="Enter password"
  rightIcon={<Eye size={16} />}
/>

Password Field Example

import { Lock, Eye, EyeOff } from 'lucide-react';
import { useState } from 'react';

function PasswordInput() {
  const [showPassword, setShowPassword] = useState(false);

  return (
    <Input 
      label="Password" 
      type={showPassword ? "text" : "password"}
      placeholder="Enter password"
      leftIcon={<Lock size={16} />}
      rightIcon={
        <button 
          type="button"
          onClick={() => setShowPassword(!showPassword)}
          className="cursor-pointer"
        >
          {showPassword ? <EyeOff size={16} /> : <Eye size={16} />}
        </button>
      }
    />
  );
}

Helper Text

<Input 
  label="Username" 
  placeholder="Enter username"
  helperText="Must be at least 3 characters long"
/>

Required Fields

<Input 
  label="Full Name" 
  placeholder="Enter your full name"
  isRequired
  helperText="This field is required"
/>

Disabled State

<Input 
  label="Disabled Input" 
  placeholder="This input is disabled"
  isDisabled
  defaultValue="Cannot edit this"
/>

Props

label
string
Label text displayed above the input.
placeholder
string
Placeholder text shown when the input is empty.
helperText
string
Helper text displayed below the input.
errorMessage
string
Error message displayed below the input. Automatically sets variant to “error”.
size
'sm' | 'md' | 'lg'
default:"'md'"
Size of the input field.
variant
'default' | 'error' | 'success'
default:"'default'"
Visual variant of the input. Automatically set to “error” when errorMessage is provided.
leftIcon
React.ReactNode
Icon to display on the left side of the input.
rightIcon
React.ReactNode
Icon to display on the right side of the input. Can be an interactive element.
isRequired
boolean
default:"false"
Whether the input is required. Shows an asterisk (*) next to the label.
isDisabled
boolean
default:"false"
Whether the input is disabled.
type
string
default:"'text'"
HTML input type (text, email, password, number, etc.).
defaultValue
string
Default value for uncontrolled input.
value
string
Value for controlled input.
onChange
(value: string) => void
Handler called when the input value changes.
className
string
Additional CSS classes for the wrapper.
inputClassName
string
Additional CSS classes for the input element.

Accessibility

The Input component provides full accessibility features:
  • Keyboard Navigation: Standard text input keyboard navigation
  • Focus Management: Clear focus indicators
  • Screen Reader Support: Proper labeling and ARIA attributes
  • Error Announcements: Error messages are properly announced
  • Required Field Indication: Visual and semantic indication of required fields

Best Practices

  1. Always provide a label for accessibility:
    <Input label="Email" placeholder="Enter email" />
    
  2. Use helperText for additional context:
    <Input 
      label="Password" 
      helperText="Must be at least 8 characters"
    />
    
  3. Show validation feedback with errorMessage:
    <Input 
      label="Email" 
      errorMessage="Please enter a valid email"
    />
    

Examples

Sign Up Form

import { Input } from 'stride-ds';
import { User, Mail, Lock } from 'lucide-react';

function SignUpForm() {
  return (
    <div className="space-y-4">
      <Input 
        label="Full Name" 
        placeholder="Enter your full name"
        isRequired
        leftIcon={<User size={16} />}
      />
      <Input 
        label="Email" 
        type="email"
        placeholder="Enter your email"
        isRequired
        leftIcon={<Mail size={16} />}
        helperText="We'll never share your email with anyone else"
      />
      <Input 
        label="Password" 
        type="password"
        placeholder="Create a password"
        isRequired
        leftIcon={<Lock size={16} />}
        helperText="Must be at least 8 characters long"
      />
    </div>
  );
}

All Sizes Comparison

import { User } from 'lucide-react';

<div className="space-y-4">
  <Input 
    label="Small Input" 
    size="sm"
    placeholder="Small size"
    leftIcon={<User size={14} />}
  />
  <Input 
    label="Medium Input" 
    size="md"
    placeholder="Medium size"
    leftIcon={<User size={16} />}
  />
  <Input 
    label="Large Input" 
    size="lg"
    placeholder="Large size"
    leftIcon={<User size={18} />}
  />
</div>

With Validation States

<div className="space-y-4">
  <Input 
    label="Default Input" 
    placeholder="Default state"
    helperText="This is a helper text"
  />
  <Input 
    label="Success Input" 
    variant="success"
    placeholder="Success state"
    helperText="Everything looks good!"
    defaultValue="[email protected]"
  />
  <Input 
    label="Error Input" 
    errorMessage="This field has an error"
    placeholder="Error state"
    defaultValue="invalid input"
  />
  <Input 
    label="Disabled Input" 
    isDisabled
    placeholder="Disabled state"
    defaultValue="Cannot edit"
  />
</div>

React Hook Form Integration

The Input component works seamlessly with React Hook Form:
import { useForm } from 'react-hook-form';
import { Input } from 'stride-ds';

function FormExample() {
  const { register, handleSubmit, formState: { errors } } = useForm();

  return (
    <form onSubmit={handleSubmit(onSubmit)}>
      <Input 
        label="Email"
        {...register('email', { 
          required: 'Email is required',
          pattern: {
            value: /^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,}$/i,
            message: 'Invalid email address'
          }
        })}
        errorMessage={errors.email?.message}
      />
    </form>
  );
}

Build docs developers (and LLMs) love