shadcn.io is not affiliated with official shadcn/ui
Shadcn Input OTP for React and Tailwind
Accessible one-time password input.
Installation
bunx --bun shadcn@latest add https://kit.dev/r/input-otp.jsonpnpm dlx shadcn@latest add https://kit.dev/r/input-otp.jsonnpx shadcn@latest add https://kit.dev/r/input-otp.jsonyarn shadcn@latest add https://kit.dev/r/input-otp.jsonThis component depends on Input. Install it first if you haven't already.
Install the following dependencies:
bun add @ark-ui/reactpnpm add @ark-ui/reactnpm install @ark-ui/reactyarn add @ark-ui/reactCopy and paste the following code into your project.
"use client";
import { ark } from "@ark-ui/react/factory";
import { PinInput as ArkPinInput } from "@ark-ui/react/pin-input";
import type React from "react";
import { cn } from "@/lib/utils";
import { Input, type InputProps } from "@/components/ui/input";
interface InputOTPProps
extends React.ComponentProps<typeof ArkPinInput.Root>,
Pick<InputProps, "size"> {}
export const InputOTP = (props: InputOTPProps) => {
const { placeholder, otp = true, className, children, ...rest } = props;
return (
<ArkPinInput.Root
className="group/input-otp"
data-slot="input-otp"
otp={otp}
placeholder={placeholder ?? ""}
{...rest}
>
<ArkPinInput.Control
className={cn(
"flex items-center gap-2",
"*:data-[slot=input-otp-input]:size-9",
className
)}
data-slot="input-otp-control"
>
{children}
</ArkPinInput.Control>
<ArkPinInput.HiddenInput />
</ArkPinInput.Root>
);
};
export const InputOTPSlot = (
props: React.ComponentProps<typeof ArkPinInput.Input>
) => {
const { className, ...rest } = props;
return (
<ArkPinInput.Input asChild data-slot="input-otp-input" {...rest}>
<Input
className={cn(
"relative p-0 text-center text-base tabular-nums",
className
)}
/>
</ArkPinInput.Input>
);
};
export const InputOTPSeparator = (
props: React.ComponentProps<typeof ark.hr>
) => {
const { className, ...rest } = props;
return (
<ark.hr
className={cn("h-0.5 w-2 rounded-full bg-foreground", className)}
data-slot="input-otp-separator"
{...rest}
/>
);
};Update the import paths to match your project setup.
Anatomy
InputOTP
├── InputOtpLabel
├── InputOTPSlot
└── InputOtpControlUsage
import {
InputOTP,
InputOTPSeparator,
InputOTPSlot,
} from "@/components/ui/input-otp";<InputOTP>
<InputOTPSlot index={0} />
<InputOTPSlot index={1} />
<InputOTPSlot index={2} />
<InputOTPSeparator />
<InputOTPSlot index={3} />
<InputOTPSlot index={4} />
<InputOTPSlot index={5} />
</InputOTP>Accessibility
| Key | Description |
|---|---|
Backspace | Delete backward. |
Delete | Delete. |
ArrowLeft | Move left. |
ArrowRight | Move right. |
Enter | Activate the focused item. |
Home | Go to the start. |
End | Go to the end. |
Demos
Blur On Complete
Controlled
Custom Size
Disabled
Four Digits
Invalid
Mask
Separator
With Placeholder
API Reference
InputOTP
div
PropType
AttributeType
InputOTPSlot
input
PropType
AttributeType
InputOtpControl
div
PropType
InputOTPSeparator
hr
PropType
AttributeType