Skip to content

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

Free

OTP with Error State Input OTP for Ark UI

A six-digit code field with a hint to try 123456, which marks any other complete code invalid.

Six boxes in two groups of three, and a hint that says Hint: Try entering 123456. Another complete code shows Invalid code. Please try again.

Show the error as soon as the code is complete and wrong. A Field error on submit is enough when you only check after a button press. In React, Ark UI does not verify the code.

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-2">
  <InputOTP
    invalid={invalid}
    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>
  {invalid ? (
    <p className="text-destructive text-sm" role="alert">
      {error}
    </p>
  ) : null}
  <p className="text-muted-foreground text-xs">Hint: Try entering 123456</p>
</div>

FAQ

When is the code checked?

In the change handler, once the code has six characters. A shorter code clears the error, so it disappears as soon as people start correcting.

How do the slots turn red?

invalid on InputOTP marks every slot invalid.

How is the error shown?

A paragraph in text-destructive with role alert, rendered only while there's an error, so screen readers announce it when it appears.

Which code is accepted?

123456, the VALID_CODE constant, as the hint under the field says. In your app, send the code to the server and show its error instead.

How do people try again?

Backspace or select and retype. Any change that leaves the code shorter than six clears the error; a new six-digit code is checked again.

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

Input OTP

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