Skip to Content
ComponentsInput

Input

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

Preview

Anatomy

import { Input } from '@wire-ui/react' <Input.Root value={value} onChange={setValue}> <Input.Label>Email</Input.Label> <Input.Field type="email" placeholder="you@example.com" /> <Input.Error /> </Input.Root>

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