Skip to Content
Columbus

OTP Field

A segmented input for one-time passwords and verification codes.

Installation

pnpm dlx shadcn@latest add @columbus/otp-field

Usage

Set length to the number of characters and render that many OTPFieldInputs. Typing moves to the next slot, Backspace moves back, and pasting a code fills every slot.

import { Field, FieldLabel } from "@/components/ui/field";
import { OTPField, OTPFieldInput } from "@/components/ui/otp-field";

<Field>
  <FieldLabel>Verification code</FieldLabel>
  <OTPField length={4} onValueComplete={(code) => console.log(code)}>
    <OTPFieldInput />
    <OTPFieldInput aria-label="Character 2 of 4" />
    <OTPFieldInput aria-label="Character 3 of 4" />
    <OTPFieldInput aria-label="Character 4 of 4" />
  </OTPField>
</Field>;

Accessibility

Each slot is its own input. The first slot takes its name from the FieldLabel. Give the other slots an aria-label like "Character 2 of 6" so screen readers say where the user is.

With separator

Validation

onValueComplete runs when every slot is filled. Check the code there, mark the field invalid, and show a FieldError with match.

Enter 123456 to pass.

Letters and numbers

Only digits are accepted by default. Use validationType="alphanumeric" for recovery or invite codes.

Letters and numbers, like A7C9XZ.

API reference

OTPField and OTPFieldInput wrap OTPField.Root and OTPField.Input from Base UI OTP Field and accept all their props. OTPFieldSeparator draws a short line between slot groups.

Prop

Type

On this page