Input OTP
Accessible one-time password input with copy/paste. Each character gets its own cell; built on the input-otp library.
Default (6-digit)
"use client";
import * as React from "react";
import { InputOTP, InputOTPGroup, InputOTPSlot } from "@tidal-ds/react";
export function Example() {
const [value, setValue] = React.useState("");
return (
<InputOTP maxLength={6} value={value} onChange={setValue}>
<InputOTPGroup>
<InputOTPSlot index={0} />
<InputOTPSlot index={1} />
<InputOTPSlot index={2} />
<InputOTPSlot index={3} />
<InputOTPSlot index={4} />
<InputOTPSlot index={5} />
</InputOTPGroup>
</InputOTP>
);
}With separator
<InputOTP maxLength={6} value={value} onChange={setValue}>
<InputOTPGroup>
<InputOTPSlot index={0} />
<InputOTPSlot index={1} />
<InputOTPSlot index={2} />
</InputOTPGroup>
<InputOTPSeparator />
<InputOTPGroup>
<InputOTPSlot index={3} />
<InputOTPSlot index={4} />
<InputOTPSlot index={5} />
</InputOTPGroup>
</InputOTP>Props
| Component | Notable props |
|---|---|
| InputOTP | maxLength (required), value, onChange, disabled, pattern (e.g. REGEXP_ONLY_DIGITS from input-otp), containerClassName |
| InputOTPGroup | wraps a run of slots; first/last get outer radii automatically |
| InputOTPSlot | index (required) — reads char / caret / active state from OTPInputContext |
| InputOTPSeparator | decorative dash between groups; role="separator" |
Source
packages/react/src/components/input-otp.tsx · built on input-otp