Skip to main content
A foundational input component that provides consistent styling across form fields while remaining highly customizable.

Installation

The Input component uses:
  • Custom utility functions from @/lib/utils
  • Native HTML input element as base

Basic Usage

import { Input } from "@/components/ui/input";

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

Input Types

<Input
  type="email"
  placeholder="[email protected]"
/>
Email input with browser validation.

Real-World Examples

Login Form Email Input

From modules/auth/components/LoginForm.tsx:54-62:
import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label";
import { useState } from "react";

export function LoginForm() {
  const [email, setEmail] = useState("");
  
  return (
    <div className="space-y-2">
      <Label htmlFor="email">Correo electrónico</Label>
      <Input
        id="email"
        type="email"
        value={email}
        onChange={(e) => setEmail(e.target.value)}
        placeholder="[email protected]"
        className="py-6"
        required
      />
    </div>
  );
}

Password Input with Toggle

From modules/auth/components/LoginForm.tsx:68-76:
import { Input } from "@/components/ui/input";
import { Button } from "@/components/ui/button";
import { EyeIcon, EyeOffIcon } from "lucide-react";
import { useState } from "react";

export function PasswordField() {
  const [password, setPassword] = useState("");
  const [showPassword, setShowPassword] = useState(false);
  
  return (
    <div className="relative">
      <Input
        id="password"
        type={showPassword ? "text" : "password"}
        value={password}
        onChange={(e) => setPassword(e.target.value)}
        placeholder="••••••••"
        className="py-6"
        required
      />
      <Button
        type="button"
        variant="ghost"
        size="sm"
        className="absolute right-2 top-1/2 -translate-y-1/2"
        onClick={() => setShowPassword(!showPassword)}
      >
        {showPassword ? <EyeOffIcon className="h-4 w-4" /> : <EyeIcon className="h-4 w-4" />}
      </Button>
    </div>
  );
}

Form Integration

import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label";

<div className="space-y-2">
  <Label htmlFor="username">Username</Label>
  <Input id="username" placeholder="johndoe" />
</div>

Props

type
string
default:"text"
HTML input typeCommon options: text | email | password | number | tel | url | search | date | file
placeholder
string
Placeholder text displayed when input is empty
value
string
Controlled input value
onChange
function
Change event handler: (e: React.ChangeEvent<HTMLInputElement>) => void
className
string
Additional CSS classes to apply to the input
disabled
boolean
default:"false"
Disables the input and applies disabled styles (cursor-not-allowed, 50% opacity)
required
boolean
default:"false"
Makes the input required for form submission
aria-invalid
boolean
Indicates input validation state for screen readers
id
string
HTML id attribute, used to associate with Label component

Accessibility

  • Fully extends native HTML input attributes
  • Supports disabled state with appropriate cursor and opacity
  • Placeholder text uses text-muted-foreground for sufficient contrast
  • Works seamlessly with Label component using id and htmlFor
  • Use aria-invalid and aria-describedby for validation feedback
  • Required inputs should be marked with required attribute

Styling Details

  • Width: w-full (100% of container)
  • Background: Transparent by default
  • Text size: Base (16px) on mobile, small (14px) on desktop (md breakpoint)
  • File input: Styled file button with transparent background
  • Placeholder: Uses muted foreground color
  • Disabled state: cursor-not-allowed with 50% opacity

Customization

The Input component accepts any custom classes through the className prop:
<Input
  className="py-6 text-lg border-2 border-blue-500"
  placeholder="Custom styled input"
/>

TypeScript

type InputProps = React.ComponentProps<"input">;
The component extends all native HTML input attributes without additional custom props (except className merging via cn).

Build docs developers (and LLMs) love