Input

A text input component for forms with multiple sizes and built-in validation styles.

Usage

Basic Input

import { Input } from "@prisma-docs/eclipse";

export function MyComponent() {
  return <Input placeholder="Enter text..." />;
}

Live Example:

Input Types

The Input component supports all native HTML input types:

import { Input } from "@prisma-docs/eclipse";

export function InputTypes() {
  return (
    <div className="space-y-4 max-w-md">
      <Input type="text" placeholder="Text input" />
      <Input type="email" placeholder="email@example.com" />
      <Input type="password" placeholder="Password" />
      <Input type="number" placeholder="123" />
      <Input type="tel" placeholder="(555) 555-5555" />
      <Input type="url" placeholder="https://example.com" />
      <Input type="search" placeholder="Search..." />
      <Input type="date" />
    </div>
  );
}

Live Example:

Input Sizes

import { Input } from "@prisma-docs/eclipse";

export function InputSizes() {
  return (
    <div className="space-y-4 max-w-md">
      <Input size="lg" placeholder="Large (default)" />
      <Input size="xl" placeholder="Extra Large" />
      <Input size="2xl" placeholder="2X Large" />
    </div>
  );
}

Live Example:

With Field Component

Use the Field component for proper form structure with labels and descriptions:

import { Input, Field, FieldLabel, FieldDescription } from "@prisma-docs/eclipse";

export function InputWithField() {
  return (
    <Field>
      <FieldLabel htmlFor="username">Username</FieldLabel>
      <FieldDescription>Choose a unique username for your account.</FieldDescription>
      <Input id="username" placeholder="Enter your username" />
    </Field>
  );
}

Live Example:

Choose a unique username for your account.

With Basic Labels

You can also use plain labels without the Field component:

import { Input } from "@prisma-docs/eclipse";

export function InputWithLabel() {
  return (
    <div className="space-y-2 max-w-md">
      <label htmlFor="username" className="text-sm font-medium">
        Username
      </label>
      <Input id="username" placeholder="Enter your username" />
    </div>
  );
}

Live Example:

Disabled State

import { Input } from "@prisma-docs/eclipse";

export function DisabledInput() {
  return (
    <div className="space-y-4 max-w-md">
      <Input placeholder="Disabled input" disabled />
      <Input defaultValue="Disabled with value" disabled />
    </div>
  );
}

Live Example:

Invalid State with Field

Use the Field component with FieldError for proper error handling:

import { Input, Field, FieldLabel, FieldDescription, FieldError } from "@prisma-docs/eclipse";

export function InvalidInputWithField() {
  return (
    <Field>
      <FieldLabel htmlFor="email-invalid">Email</FieldLabel>
      <FieldDescription>We'll send updates to this address.</FieldDescription>
      <Input
        id="email-invalid"
        type="email"
        defaultValue="invalid-email"
        aria-invalid="true"
      />
      <FieldError>Please enter a valid email address</FieldError>
    </Field>
  );
}

Live Example:

We'll send updates to this address.

Invalid State (Basic)

Use the aria-invalid attribute to mark an input as invalid for validation errors:

import { Input } from "@prisma-docs/eclipse";

export function InvalidInput() {
  return (
    <div className="space-y-4 max-w-md">
      <div className="space-y-2">
        <label htmlFor="invalid-email" className="text-sm font-medium">
          Email
        </label>
        <Input
          id="invalid-email"
          type="email"
          defaultValue="invalid-email"
          aria-invalid="true"
        />
        <span className="text-sm text-foreground-error block">
          Please enter a valid email address
        </span>
      </div>
      <div className="space-y-2">
        <label htmlFor="invalid-password" className="text-sm font-medium">
          Password
        </label>
        <Input
          id="invalid-password"
          type="password"
          defaultValue="123"
          aria-invalid="true"
        />
        <span className="text-sm text-foreground-error block">
          Password must be at least 8 characters
        </span>
      </div>
    </div>
  );
}

Live Example:

Please enter a valid email address

Password must be at least 8 characters

Form Example

import { Input, Button } from "@prisma-docs/eclipse";

export function FormExample() {
  return (
    <form className="space-y-4 max-w-md">
      <div className="space-y-2">
        <label htmlFor="name" className="text-sm font-medium">
          Name
        </label>
        <Input id="name" placeholder="John Doe" required />
      </div>
      <div className="space-y-2">
        <label htmlFor="email" className="text-sm font-medium">
          Email
        </label>
        <Input id="email" type="email" placeholder="john@example.com" required />
      </div>
      <div className="space-y-2">
        <label htmlFor="message" className="text-sm font-medium">
          Message
        </label>
        <Input id="message" placeholder="Your message..." />
      </div>
      <Button type="submit">Submit</Button>
    </form>
  );
}

Live Example:

File Input

import { Input } from "@prisma-docs/eclipse";

export function FileInput() {
  return (
    <div className="space-y-2 max-w-md">
      <label htmlFor="file" className="text-sm font-medium">
        Upload file
      </label>
      <Input id="file" size="2xl" type="file" />
    </div>
  );
}

Live Example:

Component Props

Input

The Input component extends all native HTML input attributes and adds custom props:

  • type - Input type (text, email, password, number, etc.) (string, default: "text")
  • size - Size variant ("lg" | "xl" | "2xl", default: "lg")
  • className - Additional CSS classes (string, optional)
  • disabled - Disable the input (boolean, default: false)
  • placeholder - Placeholder text (string, optional)
  • defaultValue - Default value for uncontrolled inputs (string, optional)
  • value - Value for controlled inputs (string, optional)
  • onChange - Change event handler (function, optional)
  • onFocus - Focus event handler (function, optional)
  • onBlur - Blur event handler (function, optional)
  • aria-invalid - Mark input as invalid for validation errors (boolean, optional)
  • All other standard HTML input attributes

Features

  • ✅ Multiple size variants (lg, xl, 2xl)
  • ✅ All native input types supported
  • ✅ Focus state with shadow and border highlight
  • ✅ Disabled state with reduced opacity
  • ✅ Invalid state with error styling (aria-invalid)
  • ✅ Placeholder styling
  • ✅ File input styling
  • ✅ Accessible and keyboard navigable
  • ✅ Fully typed with TypeScript
  • ✅ Customizable with className prop

Best Practices

  • Always pair inputs with labels for accessibility
  • Use appropriate input types (email, tel, url, etc.) for better mobile UX
  • Provide clear placeholder text that doesn't replace labels
  • Use the required attribute for required fields
  • Use aria-invalid to mark invalid inputs and provide error messages
  • Consider adding helper text below inputs for additional context
  • Use disabled state only when necessary
  • For forms, consider using form validation libraries like React Hook Form or Formik
  • Test keyboard navigation and screen reader compatibility

Common Use Cases

The Input component is perfect for:

  • Form fields - Collecting user data in forms
  • Search bars - Implementing search functionality
  • Login forms - Username and password inputs
  • Settings - Configuration and preference inputs
  • Filters - Filtering data with text input
  • Contact forms - Email and message inputs
  • User profiles - Editing profile information
  • File uploads - Selecting files to upload

Accessibility

The Input component follows accessibility best practices:

  • Uses semantic HTML <input> element
  • Supports all ARIA attributes including aria-invalid
  • Keyboard navigable (Tab, Shift+Tab)
  • Focus indicators with shadow and border
  • Works with screen readers
  • Supports labels via id and htmlFor attributes
  • Error states announced to screen readers via aria-invalid
  • Respects prefers-reduced-motion for animations
  • Proper contrast ratios for text and borders

Styling

The Input component uses design tokens and can be customized:

  • Border: border-stroke-neutral with border-stroke-neutral-strong on focus
  • Invalid border: border-stroke-error when aria-invalid is true
  • Background: bg-background-default
  • Text: text-foreground-neutral with size text-sm
  • Invalid text: text-foreground-error when aria-invalid is true
  • Placeholder: text-foreground-neutral-weak
  • Radius: rounded-square (6px)
  • Focus shadow: shadow-drop-low
  • Transition: Smooth color transitions

Customize by passing className props:

<Input className="border-2 border-blue-500 focus:border-blue-700" />

On this page