Input
StableText input with icon, prefix, suffix, clear button, and password show/hide toggle. Error state triggers the shake animation.
Form elementInteractiveVhyxSeal
Interactive example
Controlled input
Import
tsx
import { Input } from '@vhyxui/react'Variants
Different input configurations.
Default
With icon
With prefix and suffix
Search with clear button
Password with show/hide toggle
Error state
Sizes
sm, md, lg
States
Disabled
Read-only
Props
| Prop | Type | Default | Description |
|---|---|---|---|
size | 'sm' | 'md' | 'lg' | 'md' | Size of the input — maps to --vhyx-size-* height tokens. |
icon | React.ReactNode | — | Icon rendered inside the input field. |
iconPosition | 'left' | 'right' | 'left' | Side the icon appears on. |
prefix | React.ReactNode | — | Content rendered before the input (inside the wrapper). |
suffix | React.ReactNode | — | Content rendered after the input (inside the wrapper). |
clearable | boolean | false | Shows a clear button when the input has a value. |
onClear | () => void | — | Called when the clear button is clicked. |
error | boolean | false | Applies error styling and sets aria-invalid. |
contract | Partial<ComponentContract> | — | VhyxSeal contract override. |
className | string | — | Additional CSS classes appended to the input wrapper. |
Also accepts all standard HTMLInputElement attributes. The native size attribute is replaced by the size prop above.
Accessibility
-
aria-invalidset automatically whenerror=true. - Password toggle button has
aria-labelthat updates with state ("Show password" / "Hide password"). - Clear button has
aria-label="Clear". - Icons are
aria-hidden— decorative only. - Use with
Fieldto automatically connect label, hint, and error viaaria-describedby. - Focus ring via
:focus-visible— visible on keyboard, hidden on mouse click.
Keyboard navigation
| Key | Action |
|---|---|
| Tab | Move focus into / out of the input. |
| Shift + Tab | Move focus to the previous focusable element. |
| Escape | When clearable and focused, clears the value. |
Agent contract
Default VhyxSeal contract shipped with every Input.
Default contract
{
"type": "input",
"intent": "enter-text",
"description": "Accepts a text value entered by the user",
"requires": [],
"requiredPermissions": [],
"consequence": "Updates the field value in the parent form context",
"affects": [
"form"
],
"reversible": true,
"safetyLevel": "low",
"requiresConfirmation": false,
"destructive": false,
"contractVersion": "0.0.1",
"fingerprint": "vhyxs_04a1343d"
}Override via the contract prop — fields are merged with the default.
Theming
Override these CSS tokens to theme Input without touching component code.
--vhyx-size-sm/md/lgInput height per size
--vhyx-color-borderDefault border color
--vhyx-color-border-focusFocus border and ring color
--vhyx-color-dangerError border color
--vhyx-color-surfaceInput background
--vhyx-radius-mdBorder radius
--vhyx-shadow-focusFocus ring
--vhyx-shadow-focus-dangerError focus ring
--vhyx-duration-slowShake animation duration (error state)
Examples
Email field with icon
Email with left icon
Inside a Field for full label + error wiring
tsx
<Field name="email" label="Email address" required>
<Input
{...form.register('email')}
type="email"
placeholder="you@example.com"
error={!!form.formState.errors.email}
/>
</Field>