Skip to content

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

Free

Masked OTP Input Input OTP for React

A six-digit code field that stays blurred until an eye button is pressed, with a note about showing the code.

Six boxes sit blurred beside an eye button. A line under them says Toggle visibility to show/hide the entered code.

Blur the code when it might be read over someone's shoulder. A Password Input fits a password, not a one-time code. 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">
  <div className="flex items-center gap-2">
    <div className={cn(!showValue && "select-none blur-sm")}>
      <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>
    </div>
    <Button
      aria-label={showValue ? "Hide code" : "Show code"}
      onClick={handleToggle}
      size="icon-md"
      type="button"
      variant="ghost"
    >
      {showValue ? (
        <EyeOffIcon aria-hidden="true" />
      ) : (
        <EyeIcon aria-hidden="true" />
      )}
    </Button>
  </div>
{/* The rest of the file is under Installation. */}

FAQ

How is the code hidden?

The field's wrapper gets blur-sm and select-none while the code is hidden. The digits are still typed normally; they're just unreadable on screen.

How does the eye button work?

Whether the code is shown lives in state. The ghost Button at size icon-md flips it and swaps EyeIcon for EyeOffIcon.

How do screen readers know what the button does?

Its aria-label follows the state: Show code while hidden, Hide code while shown. The icons have aria-hidden.

Can the slots show dots instead?

The slots draw the typed characters, so blurring the field, as here, is the simplest way to hide them.

Is the code hidden from screen readers too?

No. The blur is visual, so assistive technology still reads the digits. That's usually right: the person typing is the one listening.

How is the value kept?

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

API Reference

Input OTP

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

Button

Sets aria-label={showValue ? "Hide code" : "Show code"}, onClick={handleToggle}, size="icon-md", type="button" and variant="ghost". The rest is on the Button page.