Skip to content

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

Free

OTP with Enhanced Focus Management Input OTP for Ark UI

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, Ark 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 onValueChange={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?

Each slot is its own input, so a click focuses that slot. The label only adds the gaps around them.

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 an array of strings, one per slot, and each change arrives as details.value.

API Reference

Label

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

Input OTP

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