A one-time code in boxes, one character each: typed, pasted or filled from a text message.
$ pnpm dlx shadcn@latest add https://dashral.com/r/input-otp.jsonInstallation
$ pnpm dlx shadcn@latest add https://dashral.com/r/input-otp.jsonAdds the component, the components it builds on, its npm packages and the theme tokens it uses. Using Dashral often? Add the registry to components.json once:
{
"registries": {
"@dashral": "https://dashral.com/r/{name}.json"
}
}Then add components by name:
$ pnpm dlx shadcn@latest add @dashral/input-otpUsage
import { InputOTP } from "@/components/dashral/input-otp"
<InputOTP label="Verification code" description="We sent it to your phone." onComplete={(code) => verify(code)} />Examples
API reference
InputOTP
Also takes every prop of <input>(opens in a new tab).
| Prop | Type | Default |
|---|---|---|
label | ReactNodeShown above, linked to the control. | — |
description | ReactNodeA hint under the control. | — |
error | boolean | ReactNodetrue shows the error style; a message also shows under the control. | — |
labelAction | ReactNodeAt the end of the label's row, e.g. a “Forgot password?” link or the current value. | — |
withAsterisk | booleanMarks the label with an asterisk, e.g. alongside required. | false |
length | numberHow many characters the code has. | 6 |
value / defaultValue | stringControlled or initial code. | — |
onValueChange | (value: string) => voidCalled as it changes, with what's typed so far. | — |
onComplete | (value: string) => voidCalled once every box is filled, e.g. to verify the code. | — |
pattern | "digits" | "alphanumeric"What can be typed. Digits bring up the number keypad on phones; letters are uppercased. | "digits" |
groups | number[]Splits the boxes with a dash, e.g. [3, 3]. Ignored unless they add up to length. | — |
mask | booleanDots in place of the characters, for a PIN. | false |
size | "default" | "lg"40px or 48px boxes. | "default" |
classNames | { root, label, description, error, slots, slot }Classes for each part. | — |
className | stringExtra classes, merged with cn() so yours win. | — |
Keyboard
| Keys | Action |
|---|---|
| 0–9 (or letters) | Fill the next box |
| Backspace | Clear the last box |
| ⌘VorCtrl+V | Paste a whole code |
Accessibility
- With label, description or error, the id, aria-describedby and aria-invalid are wired up for you.
- One real input under the boxes, with autocomplete="one-time-code": screen readers hear one field and its value, and phones offer the code from a text message.
- Without a label, give it an aria-label.