Skip to content

shadcn.io is an independent project built on shadcn/ui

Free

OTP with Enhanced Focus Management Input OTP for React

A six-digit code field with a note that says a click anywhere on the input focuses it so you can type.

Six boxes in two groups of three. Under them a line says Click anywhere on the input to focus and type. The visible page has no other label.

Use the wide click target when the boxes are small and easy to miss. A normal Input is easier to hit when the code is one string. In React, Base UI moves to the next box as you type.

Preview

Preview width

Installation

Sign in to get your install command
Free with an account. It carries your token, so the CLI installs everything in one go.
Use email insteadNo credit card

Anatomy

Input OTP anatomy: root, group, separator, slot

Usage

<div className="flex flex-col gap-4">
  <Label className="w-fit cursor-text">
    <span className="sr-only">One-time password</span>
    <InputOTP maxLength={6} onChange={handleValueChange} value={value}>
      <InputOTPGroup>
        <InputOTPSlot className="bg-background" index={0} />
        <InputOTPSlot className="bg-background" index={1} />
        <InputOTPSlot className="bg-background" index={2} />
      </InputOTPGroup>
      <InputOTPSeparator />
      <InputOTPGroup>
        <InputOTPSlot className="bg-background" index={3} />
        <InputOTPSlot className="bg-background" index={4} />
        <InputOTPSlot className="bg-background" index={5} />
      </InputOTPGroup>
    </InputOTP>
  </Label>
  <p className="text-muted-foreground text-sm">
    Click anywhere on the input to focus and type.
  </p>
</div>

FAQ

How does a click anywhere focus the field?

A label sends a click on itself to the first field inside it. Wrapping InputOTP in Label makes the whole area, gaps included, a click target for the code.

How is the field named for screen readers?

A span with sr-only inside the label reads One-time password, which becomes the field's accessible name.

Why the text cursor?

cursor-text on the label shows that the area takes typing, not a button press.

What happens when I click a box directly?

The slots are drawn over one input that covers the field, so a click on any box focuses it and the caret goes to the next empty slot.

Does the keyboard work as usual?

Yes. Tab reaches the field, and the arrow keys and Backspace move between slots. The label adds a pointer target, not another tab stop.

How is the value kept?

In state, written on every change. The value is one string, and onChange receives the next string.

API Reference

Label

No extra props in this demo. The rest is on the Label page.

Input OTP

Sets maxLength={6}, onChange={handleValueChange}, value={value}, index={0}, index={1} and index={2}. The rest is on the Input OTP page.