Input
Compound component for text inputs. Works controlled and uncontrolled. Validation is entirely consumer-controlled — set invalidType to trigger the error state.
Preview
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
| Prop | Type | Default | Description |
|---|---|---|---|
value | string | — | Controlled value |
defaultValue | string | '' | Initial value for uncontrolled use |
onChange | (value: string) => void | — | Called on every keystroke |
onFocus | () => void | — | Called when field gains focus |
onBlur | () => void | — | Called when field loses focus |
invalidType | string | '' | Key into errorMessage; set by consumer when invalid |
errorMessage | Record<string, string> | {} | Map of error keys to display strings |
isRequired | boolean | false | Shows * in label; sets aria-required |
isSuccess | boolean | false | Adds data-success to field |
id | string | auto-generated | Links label htmlFor to field id |
Field data attributes
| Attribute | When present |
|---|---|
data-active | Field is focused |
data-invalid | invalidType is non-empty |
data-success | isSuccess 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