Hone UI
Components

TextField

A single-line or multiline text input with a label and helper text.

TextField combines a label, an input and helper text. It builds on React Aria's TextField, Input and TextArea, so the label and helper text link to the input for you. With select it renders a Select. It is a client component and reads components.TextField.defaultProps.

import TextField from '@hone-ui/react/TextField';

Variants

<TextField label="Outlined" />
<TextField label="Filled" variant="filled" />
<TextField label="Standard" variant="standard" />

Helper text, errors and sizes

We never share it

Enter a name

<TextField label="Email" type="email" required helperText="We never share it" />
<TextField label="Name" error helperText="Enter a name" />
<TextField label="Compact" size="small" />

Controlled input

<TextField label="Name" value={name} onChange={(event) => setName(event.target.value)} />

Multiline

<TextField label="Notes" multiline minRows={3} maxRows={8} />

Adornments

$
<TextField label="Price" slotProps={{ input: { startAdornment: <span>$</span> } }} />

Select

<TextField select label="Currency" defaultValue="eur">
  <MenuItem value="eur">Euro</MenuItem>
  <MenuItem value="usd">US dollar</MenuItem>
</TextField>

With select, slotProps.input startAdornment, endAdornment and readOnly go to the Select, so a start adornment shrinks the label and a read-only field never opens its menu.

Set SelectProps={{ native: true }} (or slotProps.select.native) for a real select with option children. onChange then gets the real change event. See Select.

Props

PropTypeDefaultDescription
variant'outlined', 'filled', 'standard''outlined'The frame.
labelReactNodenoneFloats inside the input and shrinks on focus or with a value.
helperTextReactNodenoneLinked to the input with aria-describedby.
errorbooleanfalseSets aria-invalid.
requiredbooleanfalseSets the native required attribute and shows an asterisk.
disabled, fullWidthbooleanfalse
size'small', 'medium''medium'The size.
margin'none', 'dense', 'normal''none'Vertical margin.
color'primary', 'secondary', 'error', 'info', 'success', 'warning''primary'The focused color.
typestring'text'The input type.
value, defaultValuestring, numbernonevalue makes the field controlled.
onChange(event) => voidnoneThe real change event. Read event.target.value.
onFocus, onBlur(event) => voidnoneReal focus events.
placeholder, name, id, autoFocus, autoCompleteReach the input. id goes to the input.
multilinebooleanfalseRenders a textarea that grows with its text.
rowsnumbernoneA fixed row count.
minRows, maxRowsnumbernoneBounds of the growing textarea.
inputRefRefnoneA ref to the input or textarea. ref goes to the root div.
focused, hiddenLabelbooleannoneForce the focused state, or hide the label in the filled variant.
selectbooleanfalseRenders a Select. Put MenuItem options in children.
slotPropsobjectnoneinput (startAdornment, endAdornment, readOnly, className, sx, style), htmlInput (maxLength, pattern, aria-*, data-*), inputLabel, formHelperText, select, root.
SelectPropsobjectnoneProps for the Select (multiple, renderValue, displayEmpty, MenuProps).
InputProps, inputProps, InputLabelProps, FormHelperTextPropsobjectnoneLegacy aliases of the slots. InputProps also takes inputProps, disableUnderline and inputComponent (ignored).
sx, className, style, refStandard. They go to the root div.

With select, onChange receives the Select's change object, with event.target.value and event.target.name. It is not a DOM event. See Select.

Notes

  • No slots or component props.
  • children is only for select.
  • With select, onChange gets a plain object.

Accessibility

The label is a real label linked with for. Helper text becomes the input's description. error sets aria-invalid. The asterisk is hidden from screen readers, and the input carries required. A placeholder never replaces a label, so add label or slotProps.htmlInput['aria-label'].

On this page