Input
A flexible text field supporting single-line, multiline, password, and all HTML input types. Accepts icons, action elements, inline status indicators, and a clearable value.
Overview
Input wraps a native <input> (or <textarea> when multiline is set) and layers an accessible label via InputLabel, a status indicator via InputStatus, and optional icon or element slots on both sides.
The sensitive prop toggles a reveal/hide button for passwords. The onClear prop wires up a clear icon-button that appears whenever there is a value.
Import
import { Input } from '@unflow.io/ui/components/Input';Props
| Prop | Type | Default | Description |
|---|---|---|---|
name | string | required | Form field name |
label | string | — | Visible label above the field |
placeholder | string | — | Placeholder text |
hint | string | — | Helper text below the label |
type | 'email' | 'text' | 'number' | 'tel' | 'url' | 'search' | 'password' | 'text' | Input type |
value | string | — | Controlled value |
disabled | boolean | false | Disables the input |
required | boolean | false | Marks field as required |
fullWidth | boolean | false | Stretches to fill container |
status | 'valid' | 'invalid' | 'error' | — | Validation state — renders an InputStatus icon |
statusMessage | string | — | Message shown in the InputStatus tooltip |
sensitive | boolean | false | Adds a reveal/hide toggle (for passwords) |
sensitiveDefaultHidden | boolean | true | Whether value starts hidden |
multiline | boolean | false | Renders a <textarea> |
rows | number | — | Row count when multiline is true |
disableResize | boolean | false | Disables textarea resize handle |
startIcon | ReactNode | — | Icon inside the left edge |
endIcon | ReactNode | — | Icon inside the right edge |
startEl | ReactNode | — | Element attached to the left border (e.g. URL prefix) |
endEl | ReactNode | — | Element attached to the right border (e.g. action button) |
onClear | MouseEventHandler | — | Wires up a clear button — rendered when value is non-empty |
All standard HTMLInputElement props are forwarded.
Default
<Input
name="demo"
label="Label"
placeholder="Placeholder"
hint="This is a hint text to help user."
value={value}
onChange={(e) => setValue(e.currentTarget.value)}
onClear={() => setValue('')}
/>Textarea
<Input
name="description"
label="Description"
placeholder="Write something…"
multiline
rows={4}
disableResize
value={value}
onChange={(e) => setValue(e.currentTarget.value)}
/>Password
<Input
name="password"
label="Password"
type="password"
placeholder="Enter your password"
sensitive
value={value}
onChange={(e) => setValue(e.currentTarget.value)}
/>Toggle visibility is wired up automatically when sensitive={true}.
With icons
import { Envelope } from '@unflow-ui/icons/communication/envelope';
<Input
name="email"
label="Email"
type="email"
placeholder="you@example.com"
startIcon={<Envelope />}
value={value}
onChange={(e) => setValue(e.currentTarget.value)}
onClear={() => setValue('')}
/>Use startIcon and endIcon for decorative 16×16 icons inside the field boundary.
With action element
import { Cloud } from '@unflow-ui/icons/system-devices/cloud';
import { Button } from '@unflow.io/ui/components/Button';
<Input
name="demo"
label="With action"
placeholder="Placeholder"
startIcon={<Cloud />}
endEl={
<Button
variant="tertiary"
label="Copy"
type="button"
className="rounded-none rounded-tr-md rounded-br-md"
/>
}
value={value}
onChange={(e) => setValue(e.currentTarget.value)}
/>startEl and endEl attach a full-height element to the left or right border — useful for URL prefixes, currency selectors, or action buttons.
Status
<Input name="valid" label="Valid" status="valid" statusMessage="Looks good!" value={value} onChange={() => {}} />
<Input name="invalid" label="Invalid" status="invalid" statusMessage="Invalid format." value={value} onChange={() => {}} />
<Input name="error" label="Error" status="error" statusMessage="Something went wrong." value={value} onChange={() => {}} />status renders an InputStatus icon at the top-right of the field. Hovering the icon shows statusMessage in a tooltip.
Customization (slotProps)
| Slot | Props | Description |
|---|---|---|
inputContainer | HTMLDivElement props | The input wrapper div |
inputLabel | Omit<IInputLabel, 'label' | 'hint' | 'required' | 'fullWidth'> | The label component |
clearButton | Omit<IIconButton, 'icon' | 'onClick'> | The clear button |
sensitiveButton | Omit<IIconButton, 'icon' | 'onClick'> | The reveal/hide button |
status | Omit<IInputStatus, 'status' | 'message'> | The status icon |
startIcon | HTMLSpanElement props | Wrapper around startIcon |
endIcon | HTMLSpanElement props | Wrapper around endIcon |
startEl | HTMLDivElement props | Wrapper around startEl |
endEl | HTMLDivElement props | Wrapper around endEl |
Accessibility
- Label is rendered by
InputLabeland linked to the input viahtmlFor/id. requiredsets both the HTMLrequiredattribute and the visual required marker onInputLabel.- Password reveal/hide button uses
aria-labelto announce the current state. statusandstatusMessageare surfaced to screen readers via theInputStatustooltip.