OTP Input
A verification code field with one box per character, on Base UI's OTP Field.
"use client"
import * as React from "react"
import { InputOTP, InputOTPGroup, InputOTPSeparator, InputOTPSlot } from "@/components/ui/input-otp"
// A verification code, as when signing in to an Apple Account.
export default function InputOTPDemo() {
const [code, setCode] = React.useState("")
return (
<div className="flex flex-col items-center gap-3">
<InputOTP length={6} value={code} onValueChange={setCode} aria-label="Verification code">
<InputOTPGroup>
<InputOTPSlot index={0} />
<InputOTPSlot index={1} />
<InputOTPSlot index={2} />
</InputOTPGroup>
<InputOTPSeparator />
<InputOTPGroup>
<InputOTPSlot index={3} />
<InputOTPSlot index={4} />
<InputOTPSlot index={5} />
</InputOTPGroup>
</InputOTP>
<p className="text-mac-subheadline text-mac-label-secondary">
{code.length === 6 ? `Code ${code} entered.` : "Enter the code sent to your iPhone."}
</p>
</div>
)
}Installation
pnpm dlx shadcn@latest add @cupertinoui/input-otpThe first install also adds the macOS theme. See Installation to set up the registry.
Usage
import { InputOTP, InputOTPGroup, InputOTPSlot } from "@/components/ui/input-otp"
<InputOTP length={6}>
<InputOTPGroup>
<InputOTPSlot index={0} />
{/* … */}
</InputOTPGroup>
</InputOTP>Built on Base UI's OTP Field rather than the input-otp package: typing moves to the next box, Backspace goes back and pasting fills them all.
API Reference
Every part forwards the props of the underlying Base UI OTP Field part. The props below are the ones CupertinoUI adds or changes.
InputOTP
| Prop | Type | Description |
|---|---|---|
length | number | How many characters. |
value / defaultValue | string | The code. |
onValueChange / onValueComplete | (value: string) => void | Called as it changes, and once every box is filled. |
className | string | Extra classes, merged with the component's own. |
InputOTPSlot
| Prop | Type | Description |
|---|---|---|
index | number | Its position, for the accessible label. |
className | string | Extra classes, merged with the component's own. |