framingui/docs
Components

Input

Text input field for forms and user entry.

Import

import { Input } from '@framingui/ui';

Basic Usage

<Input placeholder="Enter your email" />

Input Types

<Input type="text" placeholder="Text" />
<Input type="email" placeholder="Email" />
<Input type="password" placeholder="Password" />
<Input type="number" placeholder="Number" />
<Input type="tel" placeholder="Phone" />
<Input type="url" placeholder="URL" />
<Input type="search" placeholder="Search..." />
<Input type="date" />
<Input type="time" />

With Label

import { Label } from '@framingui/ui';

<div className="space-y-2">
  <Label htmlFor="email">Email</Label>
  <Input id="email" type="email" placeholder="you@example.com" />
</div>

With Icon

import { Search, Mail, Lock } from 'lucide-react';

// Icon on left
<div className="relative">
  <Search className="absolute left-3 top-1/2 -translate-y-1/2 w-4 h-4 text-neutral-400" />
  <Input className="pl-10" placeholder="Search..." />
</div>

// Icon on right
<div className="relative">
  <Input type="email" placeholder="Email" />
  <Mail className="absolute right-3 top-1/2 -translate-y-1/2 w-4 h-4 text-neutral-400" />
</div>

States

// Disabled
<Input disabled placeholder="Disabled input" />

// Read only
<Input readOnly value="Read only value" />

// Error state (via className)
<Input className="border-red-500 focus:ring-red-500" placeholder="Error" />

// With error message
<div className="space-y-1">
  <Input className="border-red-500" placeholder="Email" />
  <p className="text-sm text-red-500">Please enter a valid email</p>
</div>

Form Example

<form className="space-y-4">
  <div className="space-y-2">
    <Label htmlFor="name">Full Name</Label>
    <Input id="name" placeholder="John Doe" />
  </div>
  
  <div className="space-y-2">
    <Label htmlFor="email">Email</Label>
    <Input id="email" type="email" placeholder="john@example.com" />
  </div>
  
  <div className="space-y-2">
    <Label htmlFor="password">Password</Label>
    <Input id="password" type="password" placeholder="••••••••" />
  </div>
  
  <Button type="submit" className="w-full">
    Create Account
  </Button>
</form>

With React Hook Form

import { useForm } from 'react-hook-form';
import { zodResolver } from '@hookform/resolvers/zod';
import { z } from 'zod';

const schema = z.object({
  email: z.string().email('Invalid email'),
  password: z.string().min(8, 'Min 8 characters'),
});

function LoginForm() {
  const { register, handleSubmit, formState: { errors } } = useForm({
    resolver: zodResolver(schema),
  });

  return (
    <form onSubmit={handleSubmit(onSubmit)} className="space-y-4">
      <div className="space-y-1">
        <Input {...register('email')} placeholder="Email" />
        {errors.email && (
          <p className="text-sm text-red-500">{errors.email.message}</p>
        )}
      </div>
      
      <div className="space-y-1">
        <Input {...register('password')} type="password" placeholder="Password" />
        {errors.password && (
          <p className="text-sm text-red-500">{errors.password.message}</p>
        )}
      </div>
      
      <Button type="submit">Sign In</Button>
    </form>
  );
}

Search Input

function SearchInput() {
  const [query, setQuery] = useState('');

  return (
    <div className="relative">
      <Search className="absolute left-3 top-1/2 -translate-y-1/2 w-4 h-4 text-neutral-400" />
      <Input
        type="search"
        placeholder="Search..."
        value={query}
        onChange={(e) => setQuery(e.target.value)}
        className="pl-10 pr-10"
      />
      {query && (
        <button
          onClick={() => setQuery('')}
          className="absolute right-3 top-1/2 -translate-y-1/2"
        >
          <X className="w-4 h-4 text-neutral-400 hover:text-neutral-600" />
        </button>
      )}
    </div>
  );
}

Props

Input accepts all standard input element props.

PropTypeDescription
typestringHTML input type
placeholderstringPlaceholder text
disabledbooleanDisable input