Input
A text field as an inset well: the void for a fill, a quiet outline, the accent for a caret. A click almost anywhere on the slab lands in it.
Install
# once per project: where @zeroui items come frompnpm dlx shadcn@latest registry add @zeroui=https://zeroui.catforest.dev/r/{name}.jsonpnpm dlx shadcn@latest add @zeroui/inputExamples
Basic
import { Input } from "@/components/zero/input";export default function InputBasic() { return ( <Input placeholder="Search the board" aria-label="Search the board" className="max-w-xs" /> );}Sizes
import { Input } from "@/components/zero/input";export default function InputSizes() { return ( <div className="grid w-full max-w-xs gap-4"> <Input size="sm" placeholder="Small" aria-label="Small" /> <Input size="md" placeholder="Medium" aria-label="Medium" /> <Input size="lg" placeholder="Large" aria-label="Large" /> </div> );}An icon or an action at either end
import { useState } from "react";import { ClearIcon, EyeIcon, EyeOffIcon, SearchIcon,} from "@/components/zero/icons";import { Input, InputAction } from "@/components/zero/input";export default function InputSlots() { const [query, setQuery] = useState("rail yards"); const [shown, setShown] = useState(false); return ( <div className="grid w-full max-w-xs gap-4"> <Input value={query} onChange={(event) => setQuery(event.target.value)} placeholder="Search the board" aria-label="Search the board" start={<SearchIcon />} end={ query ? ( <InputAction aria-label="Clear" onClick={() => setQuery("")}> <ClearIcon /> </InputAction> ) : null } /> <Input type={shown ? "text" : "password"} defaultValue="lantern-42" aria-label="Access key" end={ <InputAction aria-label={shown ? "Hide the key" : "Show the key"} onClick={() => setShown((value) => !value)} > {shown ? <EyeOffIcon /> : <EyeIcon />} </InputAction> } /> </div> );}Invalid and disabled
import { Input } from "@/components/zero/input";export default function InputStates() { return ( <div className="grid w-full max-w-xs gap-4"> <Input defaultValue="no@" aria-invalid aria-label="Invalid" /> <Input placeholder="Disabled" disabled aria-label="Disabled" /> </div> );}Behaviour
Focus draws the selection frame, also while an InputAction inside it has focus. An invalid value turns the outline to danger: inside a Field that follows its validation, outside one it follows aria-invalid.
className styles the frame (its width, its margins); every other prop goes to the input itself.
Props
Input
| Prop | Type | Default | Description |
|---|---|---|---|
| size | "sm" | "md" | "lg" | "md" | 32, 40 or 52 px tall. |
| cut | "end" | "start" | "both" | "none" | "end" | Which edges of the well are cut on the slant. |
| start | ReactNode | — | Before the text: usually an icon. The input gives up its padding on that side. |
| end | ReactNode | — | After the text: an icon or an InputAction (clear, show the password). |
Also takes every prop of Base UI's Input.
InputAction
| Prop | Type | Default | Description |
|---|---|---|---|
| aria-label | string | — | Required: the action holds only an icon, so this is its name. |
Also takes every prop of Base UI's Button.