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
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 element to display within the input field.
Position of the icon within the input.Options: left, right
Prefix element to display at the start of the input (e.g., “https://”).
Suffix text to display at the end of the input (e.g., “USD”, “kg”).
Visual style variant of the input.Options: medium, light, searchTable
Callback function triggered when the icon is clicked.
When true, sets the input to take full width (w-full).
HTML input type attribute.Examples: text, email, password, number, tel, url
Placeholder text displayed when the input is empty.
When true, disables the input and applies disabled styles.
Additional CSS classes to apply to the input element.
Callback function triggered when the input receives focus.
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
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
/>
)
}
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)}
/>
)
}
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>
)
}
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