Skip to Content
⭐️ Leave a star →
ComponentsInput

Input

Compound component for text inputs. Works controlled and uncontrolled. Validation is entirely consumer-controlled — set invalidType to trigger the error state.

Features

Compound component with Label, Field, and Error parts.
Consumer-controlled validation via invalidType.
Success state support via isSuccess.
Can be controlled or uncontrolled.
Automatic aria-invalid and aria-required attributes.

Example

import { Input } from '@wire-ui/react' <Input.Root> <Input.Label>Full Name</Input.Label> <Input.Field placeholder="John Doe" /> </Input.Root>

Styling

Input exposes validation and focus states via data attributes on the Field element. Style error, success, and active states using attribute selectors.

<Input.Field className=" border border-black data-[active]:border-blue-500 data-[invalid]:border-red-500 data-[success]:border-green-500 " />

Using data attributes

Input.Field reflects the current state through data attributes set by the Root component.

/* Active (focused) */ input[data-active] { border-color: #3b82f6; } /* Invalid (consumer-controlled via invalidType) */ input[data-invalid] { border-color: #ef4444; } /* Success (consumer-controlled via isSuccess) */ input[data-success] { border-color: #22c55e; }

Root props

PropTypeDefaultDescription
valuestringControlled value
defaultValuestring''Initial value for uncontrolled use
onChange(value: string) => voidCalled on every keystroke
onFocus() => voidCalled when field gains focus
onBlur() => voidCalled when field loses focus
invalidTypestring''Key into errorMessage; set by consumer when invalid
errorMessageRecord<string, string>{}Map of error keys to display strings
isRequiredbooleanfalseShows * in label; sets aria-required
isSuccessbooleanfalseAdds data-success to field
idstringauto-generatedLinks label htmlFor to field id

Field data attributes

AttributeWhen present
data-activeField is focused
data-invalidinvalidType is non-empty
data-successisSuccess is true

aria-invalid="true" and aria-required="true" are also set automatically.

Validation pattern

wire-ui does not validate — you decide when and what is invalid:

const [value, setValue] = useState('') const [invalidType, setInvalidType] = useState('') function handleBlur() { if (!value) setInvalidType('required') else setInvalidType('') } function handleSubmit() { if (!value) { setInvalidType('required'); return } // proceed... } <Input.Root value={value} onChange={setValue} invalidType={invalidType} errorMessage={{ required: 'This field is required' }} > <Input.Field onBlur={handleBlur} /> <Input.Error /> </Input.Root>
Last updated on

MIT License © 2026 wire-ui

Input – Wire UI