Input OTP

Animated one-time password field with form-field chrome, spring slot focus, masked entry, and reduced-motion support.

Installation

npx shadcn@latest add @iconiq/input-otp

File Structure

Usage

"use client";

import { useState } from "react";

import { OTP, OTPSlots } from "@/components/ui/input-otp";

export function InputOtpPreview() {
  const [value, setValue] = useState("");

  return (
    <div className="flex w-full max-w-md flex-col items-center gap-4 px-4 py-10">
      <OTP
        description="Enter the 6-digit verification code sent to your device."
        id="verification-code"
        label="Verification code"
        length={6}
        onValueChange={setValue}
        value={value}
      >
        <OTPSlots separatorAfter={3} />
      </OTP>
    </div>
  );
}

Props

Props
Description

OTP

length

Number of OTP characters. Required so Base UI can clamp values, detect completion, and manage focus order.

Type number

value

Controlled OTP string. Pair with `onValueChange` when the parent owns the code.

Type string

defaultValue

Initial value for uncontrolled usage.

Type string

onValueChange

Called whenever the OTP value changes from typing, paste, backspace, or keyboard navigation.

Type (value: string, eventDetails) => void

onValueComplete

Called when all slots are filled, including when a complete code is pasted.

Type (value: string, eventDetails) => void

onValueInvalid

Called when entered text contains characters rejected by validation or normalization.

Type (value: string, eventDetails) => void

validationType

Built-in validation applied before values are stored. Use `alphanumeric` for backup or recovery codes.

Type "numeric" | "alpha" | "alphanumeric" | "none"·Default "numeric"

normalizeValue

Normalizes accepted values before state updates, such as uppercasing recovery codes.

Type (value: string) => string

mask

Obscures entered characters in the animated slot display and native inputs.

Type boolean·Default false

autoSubmit

Submits the owning form automatically when the OTP becomes complete.

Type boolean·Default false

autoComplete

Autocomplete hint applied to the first slot and hidden validation input for SMS autofill.

Type string·Default "one-time-code"

inputMode

Virtual keyboard hint applied to slot inputs. Override when `validationType` defaults are not ideal.

Type string

name

Identifies the field when a form is submitted.

Type string

form

Associates the hidden validation input with a form elsewhere in the document.

Type string

id

Applied to the first input. Subsequent inputs derive ids from it. Used by `label` and `htmlFor`.

Type string

label

Visible field label rendered above the OTP group with `htmlFor` wired to the first slot.

Type ReactNode

description

Supporting text below the field, linked through `aria-describedby`.

Type ReactNode

errorMessage

Error text below the field. Also sets invalid styling when present.

Type ReactNode

invalid

Marks the field invalid for `aria-invalid` and destructive slot borders.

Type boolean·Default false

required

Whether the user must enter a value before submitting a form.

Type boolean·Default false

disabled

Disables interaction across every slot.

Type boolean·Default false

readOnly

Prevents editing while keeping the value visible.

Type boolean·Default false

size

Slot dimensions and typography scale.

Type "default" | "sm"·Default "default"

className

Classes merged onto the root flex container.

Type string

wrapperClassName

Classes merged onto the outer field wrapper when label or help text is present.

Type string

containerClassName

Legacy alias merged onto the root container alongside `className`.

Type string

OTPSlots

separatorAfter

Inserts `OTPSeparator` before each listed zero-based index, such as `3` for 3-3 or `[3, 6]` for 3-3-3 codes.

Type number | number[]

placeholder

Hint shown in empty slots until the active slot receives focus.

Type string

slotClassName

Classes forwarded to every rendered `OTPSlot`.

Type string

className

Classes merged onto the internal `OTPGroup` wrapper.

Type string

OTPSlot

className

Classes merged onto the animated slot surface.

Type string

placeholder

Per-slot placeholder hint when composing slots manually.

Type string

aria-label

Accessible label for slots after the first one. The first slot inherits the field label from `OTP` or a surrounding `<label>`.

Type string

OTPGroup

className

Classes merged onto the group flex container.

Type string

OTPSeparator

className

Classes merged onto the separator element.

Type string

orientation

Separator orientation passed through to Base UI.

Type "horizontal" | "vertical"·Default "horizontal"

Registry bundle

Install the exact registry entry shown on the right when you want the component file and its declared runtime dependencies together.

Dependencies: @base-ui/react/otp-field, motion.

This page documents the Base UI OTP Field preview install only.

The generated registry file is /r/input-otp.json.

Contact

Additionally, if you find any bug or issue, feel free to raise an issue.

Enter the code sent to your device.