Skip to main content

Overview

The Input component is a customizable form input that supports icons, prefixes, suffixes, and various visual styles. It maintains focus state and integrates seamlessly with form libraries.

Import

import { Input } from '@repo/ui/input'

Usage

Basic Input

import { Input } from '@repo/ui/input'

export default function Example() {
  return <Input placeholder="Email" type="email" />
}

With Icon

import { Input } from '@repo/ui/input'
import { SearchIcon } from 'lucide-react'

export default function Example() {
  return (
    <Input 
      placeholder="Search for an organization" 
      icon={<SearchIcon width={17} />}
    />
  )
}

With Prefix

import { Input } from '@repo/ui/input'

export default function Example() {
  return (
    <Input 
      placeholder="yourdomain"
      prefix="https://"
    />
  )
}

With Suffix

import { Input } from '@repo/ui/input'

export default function Example() {
  return (
    <Input 
      placeholder="Enter value"
      suffix="USD"
    />
  )
}

Props

icon
ReactNode
Icon element to display within the input field.
iconPosition
string
default:"right"
Position of the icon within the input.Options: left, right
prefix
ReactNode
Prefix element to display at the start of the input (e.g., “https://”).
suffix
string
Suffix text to display at the end of the input (e.g., “USD”, “kg”).
variant
string
Visual style variant of the input.Options: medium, light, searchTable
onIconClick
() => void
Callback function triggered when the icon is clicked.
maxWidth
boolean
When true, sets the input to take full width (w-full).
type
string
HTML input type attribute.Examples: text, email, password, number, tel, url
placeholder
string
Placeholder text displayed when the input is empty.
disabled
boolean
When true, disables the input and applies disabled styles.
className
string
Additional CSS classes to apply to the input element.
onFocus
(e: FocusEvent) => void
Callback function triggered when the input receives focus.
onBlur
(e: FocusEvent) => void
Callback function triggered when the input loses focus.

Variants

Medium

<Input variant="medium" placeholder="Email" />
Fixed width input (280px) suitable for form fields.

Light

<Input variant="light" placeholder="Search" />
Light background variant for use on dark backgrounds.

Search Table

<Input variant="searchTable" placeholder="Search..." />
Compact variant optimized for table search interfaces.

Examples

Search Input

import { Input } from '@repo/ui/input'
import { SearchIcon } from 'lucide-react'

export default function Example() {
  return (
    <Input 
      type="text"
      placeholder="Search for an organization" 
      icon={<SearchIcon width={17} />}
      maxWidth
    />
  )
}

URL Input with Prefix

import { Input } from '@repo/ui/input'

export default function Example() {
  return (
    <Input 
      type="url"
      placeholder="yourdomain"
      prefix="https://"
      maxWidth
    />
  )
}

Clickable Icon

import { useState } from 'react'
import { Input } from '@repo/ui/input'
import { EyeIcon, EyeOffIcon } from 'lucide-react'

export default function Example() {
  const [showPassword, setShowPassword] = useState(false)
  
  return (
    <Input 
      type={showPassword ? 'text' : 'password'}
      placeholder="Enter password"
      icon={showPassword ? <EyeOffIcon /> : <EyeIcon />}
      onIconClick={() => setShowPassword(!showPassword)}
    />
  )
}

With Form Validation

import { Input } from '@repo/ui/input'
import { Form, FormField, FormControl, FormMessage } from '@repo/ui/form'
import { useForm } from 'react-hook-form'

export default function Example() {
  const form = useForm()
  
  return (
    <Form {...form}>
      <FormField
        control={form.control}
        name="email"
        render={({ field }) => (
          <FormControl>
            <Input 
              {...field}
              type="email"
              placeholder="Email"
            />
          </FormControl>
        )}
      />
      <FormMessage />
    </Form>
  )
}

InputRow

The InputRow component provides a wrapper for displaying multiple inputs in a horizontal layout.
import { Input, InputRow } from '@repo/ui/input'

export default function Example() {
  return (
    <InputRow>
      <Input placeholder="First Name" />
      <Input placeholder="Last Name" />
    </InputRow>
  )
}

Features

  • Focus State: Automatically applies brand color border on focus
  • Icon Support: Display icons on left or right with optional click handlers
  • Prefix/Suffix: Add contextual prefixes (URLs) or suffixes (units)
  • Responsive: Adapts padding based on prefix width
  • Accessible: Maintains standard HTML input attributes and events

Accessibility

  • Maintains all standard HTML input attributes
  • Properly handles focus and blur events
  • Icon click handlers use pointer cursor for discoverability
  • Disabled state uses cursor-not-allowed and reduced opacity

Source

View source: packages/ui/src/input/input.tsx

Build docs developers (and LLMs) love