MUI Components
NPMGithub

MUIOTPInput

MUIOTPInput renders a one-time-password field as length individual TextField boxes, one per character, backed by a single string value with no separators.

Working

MUIOTPInput works as follows:

  • Typing a character fills the current box and auto-advances focus to the next one.

  • Backspace on an empty box clears the previous box and moves focus back to it.

  • Arrow Left / Right move focus between boxes without changing the value.

  • Focusing a box selects its character, so typing replaces it instead of appending.

  • Pasting a code distributes its characters across the remaining boxes starting from the box where the cursor is — paste into the first box to fill the whole field.

  • By default only digits are accepted; a non-digit keystroke or paste is ignored. Set alphanumeric to also allow letters.

  • separatorIndexes renders a separator (default '-') after the given zero-based indexes.

    E.g. separatorIndexes={[2, 6]} with length={10} renders as *** - **** - ***.

  • There is no inline label. The label is hidden unless showLabelAboveFormField (or the allLabelsAboveFields config) renders it above the boxes; either way the accessible name is applied to every box.

Usage

import MUIOTPInput, { MUIOTPInputProps } from '@nish1896/mui-components/mui/otp-input';
const [code, setCode] = useState('');

<MUIOTPInput
  fieldName="otp"
  value={code}
  onValueChange={({ newValue }) => setCode(newValue)}
/>

Separators and alphanumeric codes

<MUIOTPInput
  fieldName="licenseKey"
  value={code}
  onValueChange={({ newValue }) => setCode(newValue)}
  length={10}
  alphanumeric
  separatorIndexes={[2, 6]}
  separator="–"
  textFieldProps={{ size: 'small' }}
/>

API

MUIOTPInput does not spread arbitrary TextFieldProps on itself — use textFieldProps to customize every character box. Props marked with * are required.

NameTypeDescription
fieldName*string
Name/path of the field. Used to derive the id, the default label, and the name attribute. This prop is required for all components.
valuestring
Current code, as a single string with no separators (e.g. '123456'). This is a controlled component — value and onValueChange must be supplied together. undefined is treated as an empty code. Only the first length characters are shown and editable — a longer value (or shrinking length) drops the overflow from the next onValueChange, so keep value.length <= length.
onValueChange*({ newValue, event }) => void
Called after every character entry, deletion, or paste with the next full code string (always length characters or fewer) and the original keystroke, backspace, or paste event.
lengthnumber
Number of individual character boxes.
Default: 6
separatorIndexesnumber[]
Zero-based character indexes after which a separator is rendered. For example, [2, 6] with length={10} renders as *** - **** - ***.
separatorReactNode
Content rendered at each separatorIndexes position.
Default: '-'
alphanumericboolean
When true, each box accepts letters and digits. When false, only digits can be typed or pasted — a non-digit keystroke or paste is ignored.
Default: false
textFieldPropsTextFieldProps
TextFieldProps forwarded to every character box — e.g. a custom size, variant or sx. Props the component derives or controls per box (name, id, value, onChange, onKeyDown, onPaste, error, multiline/rows, inputRef/ref) are omitted.
autoFocusboolean
When true, focuses the first empty box (or the first box, if the code is already complete) on mount.
Default: false
inputRefRef<HTMLInputElement>
Ref to the first character box's <input> element — use it to imperatively focus the field (e.g. React Hook Form's setFocus or focus-on-error handling).
labelReactNode
Label displayed for the field. Defaults to a human-readable label derived from fieldName, e.g. firstName becomes "First Name".
showLabelAboveFormFieldboolean
Renders the field label above the boxes. The label is otherwise hidden — there is no inline label, but the accessible name is still applied to every box. Set the value to true to render the FormLabel for this field.
Default: false
formLabelPropsFormLabelProps
FormLabelProps forwarded to the internal FormLabel. The id is managed by the component. Multiple fields can be configured using the ConfigProvider component.
requiredboolean
Indicates that the field is mandatory by adding an asterisk symbol (*) to the form label and setting the relevant accessibility attributes.
disabledboolean
When true, disables the field and associated controls.
errorMessagestring | string[]
Validation error for the field — pass a single message string, or a string[] when the field can fail multiple rules at once (every message is shown together). A non-empty string or array puts the field in an error state; undefined/''/[] clear it. Normalize your form library's error shape to this at the call site (e.g. an RHF FieldError via its .message). Use renderError to customize how the message(s) are rendered.
renderError(errors: string[]) => ReactNode
Custom renderer for the resolved error message(s), called only when the field is in an error state. Always receives a string[] — use errors[0] for the common single-message case, or map over errors when a field fails several rules. By default a single message renders as text and multiple messages render on separate lines.
hideErrorMessageboolean
If true, hides the error message text while keeping the field in an error state.
helperTextReactNode
Content displayed in the FormHelperText component below the field when there is no visible validation error.
formHelperTextPropsFormHelperTextProps
FormHelperTextProps forwarded to the internal FormHelperText. The id is managed by the component. Multiple fields can be configured using the ConfigProvider component.
customIds{ field, label, helperText, error }
Overrides the default field, label, helper text, and error IDs used for accessibility.

Playground

Controlled with plain React state — a 6-digit numeric SMS code with autoFocus, and a 10-character alphanumeric license key grouped 3–4–3 via separatorIndexes with a custom separator, showLabelAboveFormField and textFieldProps.