Preview
Design guidance
Use OTP Field for short, fixed-length codes and PINs. The default cells match the 32px Input height. Empty cells show a subtle dot; entered characters use the normal text color. Touch devices retain the larger input target.
Use mask for sensitive entry. It uses native password inputs and adds no reveal control. Masking hides the displayed value; the application still owns validation and storage. Choose the autocomplete hint for your task: one-time-code for a received code, or an explicit credential hint or off for a PIN. Browsers can apply their own autocomplete policy.
Provide a visible label. The first cell uses that label; give later cells position labels. Base UI handles paste, navigation, deletion, and rejected characters. onValueComplete reports a complete value; it does not verify the code.
Installation
Basic usage
Structure
Keep labels, descriptions, and optional actions outside OTPField.Root. A reveal action can be a sibling of Label in the same row. Do not place the button inside the label. The example uses the shared Label and IconButton owners; the caller controls visibility.
Examples
Thumbnail
Four digits
Grouped three plus three
Joined cells
Set layout="joined" to share cell borders. The value and editing behavior stay the same.
Without placeholders
Set placeholder="" on each Input to remove the default dot. Native placeholder text also supports a custom hint.
Sensitive PIN
Set mask on the root to conceal every cell. No reveal button is added.
Joined PIN
Layout and masking are independent. Combine them for a compact private code.
Reveal beside the label
An optional IconButton sits immediately after the label. It controls mask, announces Show PIN or Hide PIN, and preserves the entered value. Its type="button" keeps it from submitting a form.
Alphanumeric
Form
The form reports local acceptance only when the complete example code matches.
Partial entry
Keep the value controlled when it belongs to a larger verification flow. Each character remains editable.
Invalid code
Show a specific error and clear it when the code changes.
Disabled
Use a disabled field while code entry is unavailable.
Complete
A complete code stays editable. Verification belongs to the application.
API reference
| Prop | Type | Default | Description |
|---|---|---|---|
Root.length | number | Required number of code slots. Render the same number of Input parts. | |
Root.layout | 'separate' | 'joined' | separate | Separate cells or a joined row with shared borders. |
Root.mask | boolean | false | Use native password inputs. Does not add a reveal button. |
Root.autoComplete | string | one-time-code | Autocomplete hint on the first cell and hidden form input. Choose explicitly for PINs. |
Root.name | string | Form field name for the complete code. | |
Root.required / disabled / readOnly | boolean | false | Native validation and interaction state. |
Root.validationType | 'numeric' | 'alpha' | 'alphanumeric' | 'none' | numeric | Filters entered values using Base UI. |
Root.value / defaultValue | string | Controlled or initial code. | |
Root.onValueChange | (value: string) => void | Reports edits. | |
Root.onValueComplete | (value: string) => void | Reports a complete code. | |
Root.onValueInvalid | Base UI event handler | Reports rejected characters. | |
Input | Base UI OTPField.Input | A native editable cell. Supports native attributes, ref, render, and state-function className/style. | |
Input.placeholder | string | • | Subtle centered empty hint. An empty string removes it. |
Root native props | Base UI OTPField.Root | Preserves ref, render, state-function className/style, normalization and Base UI event details. | |
Separator | Base UI Separator | Separates visual code groups. |