Input
A fully accessible text input with an optional label, hint text, error message, icon slots, search-icon helpers, and multiple sizes. Forwards refs and spreads all native input attributes.
Import
tsx
import { Input } from 'https://git.cameronlow.com/cam/VelocityUI/packages'Preview
Basic
Floating label
Press Enter to search
Search presets
With error
Password must be at least 8 characters.
Floating label with error
Password must be at least 8 characters.
Disabled
Props
| Prop | Type | Default | Description |
|---|---|---|---|
| label | string | — | Label rendered above the input. |
| size | 'sm' | 'md' | 'lg' | 'md' | Controls padding and font size. |
| error | string | — | Error message displayed below the input. Sets aria-invalid. |
| hint | string | — | Helper text shown when there is no error. |
| leftIcon | ReactNode | — | Icon rendered inside the input on the left. |
| rightIcon | ReactNode | — | Icon rendered inside the input on the right. |
| search | boolean | false | Renders a built-in search icon when no icon is provided in the configured searchIconPosition. |
| searchIcon | ReactNode | — | Custom search icon node used when search behaviour is enabled (or standalone). |
| searchIconPosition | 'left' | 'right' | 'left' | Sets which side the search icon prefers to render on. |
| leftIconClassName | string | — | Optional className applied to the left icon wrapper for styling overrides. |
| rightIconClassName | string | — | Optional className applied to the right icon wrapper for styling overrides. |
| required | boolean | false | Marks the field as required with a visual asterisk. |
| fullWidth | boolean | false | Makes the wrapper fill its container. |
Examples
Basic
tsx
import { Input } from 'https://git.cameronlow.com/cam/VelocityUI/packages'
export default function Example() {
return <Input label="Email address" placeholder="you@example.com" type="email" />
}With error
tsx
import { Input } from 'https://git.cameronlow.com/cam/VelocityUI/packages'
export default function Example() {
return (
<Input
label="Password"
type="password"
error="Password must be at least 8 characters."
defaultValue="short"
/>
)
}With hint
tsx
import { Input } from 'https://git.cameronlow.com/cam/VelocityUI/packages'
export default function Example() {
return (
<Input
label="Username"
hint="Only letters, numbers, and underscores."
placeholder="john_doe"
/>
)
}Sizes
tsx
import { Input } from 'https://git.cameronlow.com/cam/VelocityUI/packages'
export default function Example() {
return (
<div style={{ display: 'flex', flexDirection: 'column', gap: '0.75rem' }}>
<Input size="sm" placeholder="Small" />
<Input size="md" placeholder="Medium" />
<Input size="lg" placeholder="Large" />
</div>
)
}Search style inputs
tsx
import { Input } from 'https://git.cameronlow.com/cam/VelocityUI/packages'
const SearchIcon = () => (
<svg width="16" height="16" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z" />
</svg>
)
export default function Example() {
return (
<div style={{ display: 'flex', flexDirection: 'column', gap: '0.75rem' }}>
<Input search placeholder="Search users..." />
<Input search searchIconPosition="right" placeholder="Search products..." />
<Input
searchIcon={<SearchIcon />}
leftIconClassName="text-vui-primary"
placeholder="Custom search icon"
/>
</div>
)
}Theming
Apply a named theme class to <body> or any parent element. All VelocityUI components inside that element will automatically adopt its colors, shadows, and effects. Combine with a density modifier for complete control:
css
/* Pick any named theme */
<body class="vui-theme-ocean">
/* Add a density modifier (optional) */
<body class="vui-theme-midnight vui-density-compact">
<body class="vui-theme-construction vui-density-spacious">
/* Available themes */
/* default midnight ocean */
/* construction glass soft high-contrast monochrome-red */
/* Available densities */
/* vui-density-compact vui-density-comfortable vui-density-spacious */