Input
In the appSearch and text entry. The label owns the border, so the focus colour wraps icon, field and trailing hint together.
@varick/ui/components/inputAdded 26 Aug 2026
Usage
import { Input } from "@varick/ui/components/input";
export function Example() {
return (
<Input
icon={<SearchIcon />}
placeholder="Search runs"
onChange={(e) => setQuery(e.target.value)}
/>
);
}Variants
Sizes
<Input size="sm" placeholder="Small" />
<Input size="md" placeholder="Medium" />States
<Input defaultValue="order-to-cash" />
<Input invalid defaultValue="not an email" />
<Input disabled placeholder="Disabled" />API reference
Every component also accepts className and the native props of its root element.
| Prop | Type | Default | Description |
|---|---|---|---|
| size | 'sm' | 'md' | 'md' | 28px or 32px tall. |
| icon | ReactNode | undefined | Leading 14px icon, muted. |
| trailing | ReactNode | undefined | Right-aligned slot: a Kbd, a count, a clear button. |
| invalid | boolean | false | Red border and aria-invalid on the field. |
| ...props | ComponentProps<'input'> | value, onChange, placeholder, disabled, name and the rest. |
Accessibility
- Give the field a name: a visible Field label, or aria-label for a lone search box.
- invalid sets aria-invalid="true"; pair it with a Field error so the reason is spoken.
Styles
The CSS as it appears in the app. The live component above is the same values as Tailwind classes.
.input {
display: flex;
align-items: center;
gap: 8px;
height: 32px;
border: 1px solid var(--hairline);
border-radius: 4px;
padding: 0 12px;
background: #FFFFFF;
transition: border-color 140ms var(--ease-out);
}
.input:focus-within { border-color: var(--accent); }
.input[aria-invalid="true"] { border-color: var(--danger); }
.input input { border: 0; outline: 0; font-size: 12.5px; min-width: 0; flex: 1; }
.input svg { color: var(--fg-mid); flex-shrink: 0; }