Skip to main content

Input

Stable

Text 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

PropTypeDefaultDescription
size'sm' | 'md' | 'lg''md'Size of the input — maps to --vhyx-size-* height tokens.
iconReact.ReactNodeIcon rendered inside the input field.
iconPosition'left' | 'right''left'Side the icon appears on.
prefixReact.ReactNodeContent rendered before the input (inside the wrapper).
suffixReact.ReactNodeContent rendered after the input (inside the wrapper).
clearablebooleanfalseShows a clear button when the input has a value.
onClear() => voidCalled when the clear button is clicked.
errorbooleanfalseApplies error styling and sets aria-invalid.
contractPartial<ComponentContract>VhyxSeal contract override.
classNamestringAdditional 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-invalid set automatically when error=true.
  • Password toggle button has aria-label that updates with state ("Show password" / "Hide password").
  • Clear button has aria-label="Clear".
  • Icons are aria-hidden — decorative only.
  • Use with Field to automatically connect label, hint, and error via aria-describedby.
  • Focus ring via :focus-visible — visible on keyboard, hidden on mouse click.

Keyboard navigation

KeyAction
TabMove focus into / out of the input.
Shift + TabMove focus to the previous focusable element.
EscapeWhen 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>