Creative Tim UICreative Tim UI

Shadcn Input

PreviousNext

A text input component that allows users to enter and edit text, perfect for forms, search bars, and data entry fields.

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

export function InputDemo() {
  return (
    <div className="w-72">
      <Input placeholder="Input" />
    </div>
  )
}

Installation

pnpm dlx @creative-tim/ui@latest add input

Usage

import { Input } from "@/components/ui/input"
<Input placeholder="Enter text..." />

Examples

Input Colors

Input components with different color schemes (primary, secondary, info, success, warning, error) to visually distinguish between different input states and provide visual variety.

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

export function InputColors() {
  return (
    <div className="w-72 space-y-4">
      <Input
        placeholder="Input Primary"
        className="border-primary/50 focus-visible:border-primary focus-visible:ring-primary/50"
      />
      <Input
        placeholder="Input Secondary"
        className="border-secondary/50 focus-visible:border-secondary focus-visible:ring-secondary/50"
      />
      <Input
        placeholder="Input Info"
        className="border-blue-500/50 focus-visible:border-blue-500 focus-visible:ring-blue-500/50"
      />
      <Input
        placeholder="Input Success"
        className="border-green-500/50 focus-visible:border-green-500 focus-visible:ring-green-500/50"
      />
      <Input
        placeholder="Input Warning"
        className="border-yellow-500/50 focus-visible:border-yellow-500 focus-visible:ring-yellow-500/50"
      />
      <Input
        placeholder="Input Error"
        className="border-destructive/50 focus-visible:border-destructive focus-visible:ring-destructive/50"
      />
    </div>
  )
}

Input Sizes

Input components in different sizes (small, medium, large) to accommodate various design needs and improve visual hierarchy.

import { cn } from "@/lib/utils"
import { Input } from "@/components/ui/input"

export function InputSizes() {
  return (
    <div className="w-72 space-y-4">
      <Input placeholder="Input Small" className={cn("h-8 text-sm")} />
      <Input placeholder="Input Medium" className={cn("h-9")} />
      <Input placeholder="Input Large" className={cn("h-10 text-base")} />
    </div>
  )
}

Disabled Input

A disabled input that cannot be interacted with, useful for displaying read-only fields or temporarily restricting user input.

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

export function InputDisabled() {
  return (
    <div className="w-72">
      <Input disabled placeholder="Input" />
    </div>
  )
}

Input with Label

An input component with an associated label that provides clear context and improves accessibility by properly linking the label to the input.

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

export function InputWithLabel() {
  return (
    <div className="w-72 space-y-1">
      <Label htmlFor="email" className="font-semibold">
        Email
      </Label>
      <Input id="email" type="email" placeholder="[email protected]" />
    </div>
  )
}

Input with Icon

An input component with icons positioned on the left or right side, providing visual cues and enhancing the user interface.

import { Lock, User } from "lucide-react"

import { cn } from "@/lib/utils"
import { Input } from "@/components/ui/input"

export function InputWithIcon() {
  return (
    <div className="w-72 space-y-4">
      <div className="relative">
        <User className="text-muted-foreground absolute top-1/2 left-3 h-4 w-4 -translate-y-1/2" />
        <Input placeholder="Username" className={cn("pl-9")} />
      </div>
      <div className="relative">
        <Lock className="text-muted-foreground absolute top-1/2 right-3 h-4 w-4 -translate-y-1/2" />
        <Input placeholder="Password" className={cn("pr-9")} />
      </div>
    </div>
  )
}

Input with Helper Text

An input component with helper text that provides additional context, guidance, or validation requirements to help users understand what to enter.

Use at least 8 characters, one uppercase, one lowercase and one number.

import { Info } from "lucide-react"

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

export function InputWithHelperText() {
  return (
    <div className="w-72 space-y-2">
      <Input type="password" placeholder="Password" />
      <div className="text-foreground flex gap-1.5">
        <Info className="h-3.5 w-3.5 shrink-0 translate-y-[3px] stroke-2" />
        <p className="text-sm">
          Use at least 8 characters, one uppercase, one lowercase and one
          number.
        </p>
      </div>
    </div>
  )
}

Input with Validation

An input component with validation states (error and success) that provides visual feedback to users about the validity of their input.

Something went wrong!

Congratulations 🎉

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

export function InputWithValidation() {
  return (
    <div className="w-72 space-y-6">
      <div>
        <Input
          aria-invalid="true"
          placeholder="Input Error"
          className="w-full"
        />
        <p className="text-destructive mt-1 block text-sm">
          Something went wrong!
        </p>
      </div>
      <div>
        <Input
          placeholder="Input Success"
          className="w-full border-green-500/50 focus-visible:border-green-500 focus-visible:ring-green-500/50"
        />
        <p className="mt-1 block text-sm text-green-500">Congratulations 🎉</p>
      </div>
    </div>
  )
}

Input with Button

An input component combined with a button, perfect for search forms, subscription forms, or any interface where users need to submit input immediately.

import { Button } from "@/components/ui/button"
import { Input } from "@/components/ui/input"

export function InputWithButton() {
  return (
    <form
      action="#"
      className="flex w-full max-w-sm items-center justify-center gap-2"
    >
      <Input type="email" placeholder="[email protected]" />
      <Button type="submit">Subscribe</Button>
    </form>
  )
}

Input with Dropdown

An input component combined with a dropdown menu, useful for phone number inputs with country codes, currency inputs, or any scenario requiring a prefix selector.

"use client"

import * as React from "react"
import { ChevronDown } from "lucide-react"

import { Button } from "@/components/ui/button"
import {
  DropdownMenu,
  DropdownMenuContent,
  DropdownMenuItem,
  DropdownMenuTrigger,
} from "@/components/ui/dropdown-menu"
import { Input } from "@/components/ui/input"

const countries = [
  { name: "United States", code: "+1", flag: "🇺🇸" },
  { name: "United Kingdom", code: "+44", flag: "🇬🇧" },
  { name: "Canada", code: "+1", flag: "🇨🇦" },
  { name: "Germany", code: "+49", flag: "🇩🇪" },
  { name: "France", code: "+33", flag: "🇫🇷" },
  { name: "Italy", code: "+39", flag: "🇮🇹" },
  { name: "Spain", code: "+34", flag: "🇪🇸" },
  { name: "Australia", code: "+61", flag: "🇦🇺" },
]

export function InputWithDropdown() {
  const [country, setCountry] = React.useState(countries[0])

  return (
    <div className="relative flex w-full max-w-[24rem]">
      <DropdownMenu>
        <DropdownMenuTrigger asChild>
          <Button
            variant="secondary"
            className="bg-secondary flex items-center gap-2 rounded-r-none border-r-0 pr-2 pl-3"
          >
            <span className="text-base">{country.flag}</span>
            {country.code}
            <ChevronDown className="h-4 w-4" />
          </Button>
        </DropdownMenuTrigger>
        <DropdownMenuContent className="h-72 max-w-[18rem] overflow-y-auto">
          {countries.map((item) => (
            <DropdownMenuItem
              key={item.name}
              onClick={() => setCountry(item)}
              className="flex items-center gap-2"
            >
              <span className="text-base">{item.flag}</span>
              {item.name}
              <span className="ml-auto">{item.code}</span>
            </DropdownMenuItem>
          ))}
        </DropdownMenuContent>
      </DropdownMenu>
      <Input placeholder="Mobile Number" className="rounded-l-none" />
    </div>
  )
}

Custom Input Styles

An input component with custom styling that demonstrates how to personalize the appearance to match your brand or design requirements, such as underlined inputs or custom borders.

import { User } from "lucide-react"

import { cn } from "@/lib/utils"
import { Input } from "@/components/ui/input"

export function InputCustomStyles() {
  return (
    <div className="w-72">
      <div className="relative">
        <User className="text-muted-foreground absolute top-1/2 left-1 h-4 w-4 -translate-y-1/2" />
        <Input
          placeholder="Username"
          className={cn(
            "rounded-none border-0 border-b border-gray-400 pr-0.5 pl-[26px] shadow-none ring-0 hover:border-gray-900 focus:border-gray-900 dark:border-gray-600 dark:hover:border-gray-50 dark:focus:border-gray-50"
          )}
        />
      </div>
    </div>
  )
}

Props

The input component is a native HTML input element with enhanced styling and accepts all standard input props:

PropTypeDefaultDescription
typestring"text"The type of input (text, email, password, number, etc.)
placeholderstring-Placeholder text displayed when the input is empty
valuestring-The controlled value of the input
defaultValuestring-The default value of the input (uncontrolled)
onChangefunction-Event handler called when the input value changes
disabledbooleanfalseWhen true, prevents the user from interacting with the input
requiredbooleanfalseWhen true, indicates that the input must be filled
namestring-The name of the input when used in a form
idstring-The id of the input for label association
aria-invalidboolean-Indicates that the input has invalid data
classNamestring-Additional CSS classes to apply to the input

Accessibility

The input component follows accessibility best practices:

  • Uses proper semantic HTML input elements
  • Supports keyboard navigation (Tab to focus, typing to enter text)
  • Focus states are clearly visible for keyboard users
  • Disabled state is properly communicated to assistive technologies
  • Works with form labels using htmlFor and id attributes
  • Supports aria-invalid for validation feedback
  • Maintains proper semantic HTML structure
  • Placeholder text provides context without replacing labels

Best Practices

  • Always provide labels for inputs to improve accessibility
  • Use appropriate input types (email, password, number, etc.) for better mobile experience
  • Provide helper text when the input's purpose might not be immediately clear
  • Use validation states to provide immediate feedback to users
  • Consider using icons to enhance visual clarity and user experience
  • Ensure sufficient contrast between text and background colors
  • Test keyboard navigation and screen reader compatibility
  • Use placeholder text as supplementary information, not as a replacement for labels
  • Group related inputs together for better organization
  • Use appropriate input sizes based on the importance and context of the field

The input component provides a clean and accessible way to create text input fields. It's ideal for forms, search bars, data entry, authentication, and any interface where users need to enter text or data.