Forms

OTP input for verification flows

OTPInput renders a segmented one-time code field for sign-in, two-factor authentication, payment approval, and invite-code flows. It keeps native inputs under the hood while handling auto-advance, paste fill, backspace behavior, hidden form value, and completion callbacks.

Workspace verification

Paste a 6 digit code or type one cell at a time.

Verified code

Examples

OTPInput handles the interaction contract for authentication and payment verification screens: segmented entry, paste fill, completion, and controlled state.


Payment approval

Enter the code sent to your authenticator.


Secure sign in

Waiting for a complete code.

OTP input variants examples

Use Show output / Show code on each row. Snippets start with a Variant line naming the axis and token.


Appearance: DEFAULT | Size: MD

One-time code

Try typing or pasting into the first cell.


Appearance: OUTLINE | Size: MD

One-time code

Try typing or pasting into the first cell.


Appearance: GLASS | Size: MD

One-time code

Try typing or pasting into the first cell.


Appearance: SUCCESS | Size: MD

One-time code

Try typing or pasting into the first cell.


Appearance: ERROR | Size: MD

One-time code

Try typing or pasting into the first cell.


Appearance: WARNING | Size: MD

One-time code

Try typing or pasting into the first cell.


Appearance: INFO | Size: MD

One-time code

Try typing or pasting into the first cell.


Appearance: VIOLET | Size: MD

One-time code

Try typing or pasting into the first cell.


Appearance: AMBER | Size: MD

One-time code

Try typing or pasting into the first cell.


Appearance: PINK | Size: MD

One-time code

Try typing or pasting into the first cell.


Appearance: INDIGO | Size: MD

One-time code

Try typing or pasting into the first cell.


Appearance: ORANGE | Size: MD

One-time code

Try typing or pasting into the first cell.


Appearance: OUTLINE | Size: SM

One-time code

Try typing or pasting into the first cell.


Appearance: OUTLINE | Size: MD

One-time code

Try typing or pasting into the first cell.


Appearance: OUTLINE | Size: LG

One-time code

Try typing or pasting into the first cell.


Allowed characters: ALPHANUMERIC | Length: 8

Invite code

Try typing or pasting into the first cell.


State: ERROR | Completion: onComplete

One-time code

Try typing or pasting into the first cell.

The code has expired. Request a new one.

CSS variable overrides

OTP input CSS variables

Override these OTP input variables on :root, a theme selector, or a component wrapper.

46 variables

Pattern: --zui-<component>-<slot?>-<variant?>-<property>-<state?>-dark?

:root {
  --zui-otp-label-fg: oklch(20.8% 0.042 265.755);
  --zui-otp-hint-fg: oklch(55.4% 0.046 257.417);
  --zui-otp-bg: #ffffff;
  --zui-otp-fg: oklch(20.8% 0.042 265.755);
  --zui-otp-ring-offset-focus: #ffffff;
  --zui-otp-separator: #94a3b8;
  --zui-otp-error-fg: oklch(58.6% 0.253 17.585);
  --zui-otp-default-border: #cbd5e1;
  --zui-otp-default-border-focus: oklch(44.6% 0.043 257.281);
  --zui-otp-default-ring-focus: oklch(44.6% 0.043 257.281 / 0.25);
  --zui-otp-outline-border: #64748b;
  --zui-otp-outline-border-focus: oklch(54.6% 0.245 262.881);
  --zui-otp-outline-ring-focus: oklch(54.6% 0.245 262.881 / 0.28);
  --zui-otp-glass-border: #ffffff66;
  --zui-otp-glass-bg: #ffffffcc;
  --zui-otp-glass-border-focus: oklch(70.7% 0.165 254.624);
  --zui-otp-glass-ring-focus: oklch(70.7% 0.165 254.624 / 0.32);
  --zui-otp-success-border: oklch(69.6% 0.17 162.48 / 0.6);
  --zui-otp-success-border-focus: oklch(59.6% 0.145 163.225);
  --zui-otp-success-ring-focus: oklch(59.6% 0.145 163.225 / 0.28);
  --zui-otp-error-border: oklch(58.6% 0.253 17.585 / 0.7);
  --zui-otp-error-border-focus: oklch(58.6% 0.253 17.585);
  --zui-otp-error-ring-focus: oklch(58.6% 0.253 17.585 / 0.28);
}

/* Dark theme variables follow the same names with -dark appended. */
.dark {
  --zui-otp-label-fg-dark: oklch(98.4% 0.003 247.858);
  --zui-otp-hint-fg-dark: oklch(70.4% 0.04 256.788);
  /* ...same variables with -dark at the end */
}

What it does

Provide a purpose-built code entry primitive with individual cells that still behave like a single verification value.

The component sanitizes input, advances focus after entry, moves backward on Backspace, and fires onComplete when every cell is filled.

Composition and API

Import OTPInput from the otp-input entrypoint. Use length, allowedCharacters, separatorEvery, size, appearance, mask, name, value, defaultValue, onValueChange, and onComplete to tune the experience.

Common use cases

  • Two-factor authentication and passwordless sign-in.
  • Payment or wire-transfer approval codes.
  • Phone and email verification during onboarding.
  • Invite, recovery, and device pairing codes.

Accessibility

OTPInput renders a role=group wrapper with labelled native input cells. Provide label text or an accessible name, use hint for delivery instructions, and keep errorMessage concise so screen reader users hear the actionable state.

Next.js integration notes

Use OTPInput in client components when value changes in the browser. Static defaultValue examples can be rendered on preview pages, while verification calls should run from your own server action or API route after onComplete.

FAQ

Can OTPInput paste a full code?

Yes. Paste into any cell and OTPInput distributes valid characters across the remaining cells.

Does OTPInput support controlled state?

Yes. Use value with onValueChange for controlled state, or defaultValue for uncontrolled state.

Can OTPInput submit with a form?

Yes. Pass name to render a hidden input containing the full sanitized code.