Classic OTP Input
A crisp, modern bordered verification input featuring spring-animated character drops, dynamic active slot glow tracking, masking toggle, and built-in error shake physics.
Security Verification
Enter your code or test with 123456
Installation
bunx shadcn@latest add https://jackui.com/r/classic-otp-input.jsonnpx shadcn@latest add https://jackui.com/r/classic-otp-input.jsonpnpm dlx shadcn@latest add https://jackui.com/r/classic-otp-input.jsonThe CLI will install motion and lucide-react dependencies and add the component to your project at:
components/jackui/otp-input/classic-otp-input.tsxUsage
"use client";
import React, { useState } from "react";
import { ClassicOtpInput } from "@/components/jackui/otp-input/classic-otp-input";
export default function ClassicOtpVerification() {
const [otp, setOtp] = useState("");
const [isError, setIsError] = useState(false);
const [isSuccess, setIsSuccess] = useState(false);
const handleComplete = (code: string) => {
// Validate the OTP code
if (code === "123456") {
setIsSuccess(true);
setIsError(false);
} else {
setIsError(true);
setIsSuccess(false);
setTimeout(() => setIsError(false), 2000);
}
};
return (
<div className="flex flex-col items-center justify-center p-8">
<ClassicOtpInput
length={6}
value={otp}
onChange={(val) => {
setOtp(val);
if (isError) setIsError(false);
}}
onComplete={handleComplete}
isError={isError}
isSuccess={isSuccess}
autoFocus
/>
</div>
);
}Props
| Prop | Type | Description |
|---|---|---|
length | number | Optional. Number of OTP digit slots (typically 4, 6, or 8). Default: 6 |
value | string | Optional. Controlled input value string. |
onChange | (value: string) => void | Optional. Callback fired whenever the entered value changes. |
onComplete | (value: string) => void | Optional. Callback fired when all digit slots are filled. |
type | "number" | "text" | "password" | Optional. Input character filter type. Default: "number" |
mask | boolean | Optional. Whether to mask entered characters with bullet dots. Default: false |
disabled | boolean | Optional. Disables input interaction and dims the slots. Default: false |
autoFocus | boolean | Optional. Automatically focuses the first slot on mount. Default: false |
isError | boolean | Optional. Displays error visual state and triggers spring shake animation. Default: false |
isSuccess | boolean | Optional. Displays celebratory emerald glow on completion. Default: false |
size | "sm" | "md" | "lg" | Optional. Size scale of the input slots (sm, md, lg). Default: "md" |
separator | React.ReactNode | Optional. Custom separator element rendered between digit groups (e.g. dash -). |
placeholder | string | Optional. Placeholder character displayed in empty slots. Default: "" |
className | string | Optional. Additional container CSS class names. |
slotClassName | string | Optional. Additional individual slot CSS class names. |
ref | React.Ref<ClassicOtpInputRef> | Optional. Imperative ref handle exposing focus(), blur(), and clear() methods. |
Spring Animated Button
A high-precision tactile button with a continuous luminous sinusoidal spring waveform that travels seamlessly around its perimeter. Features integrated loading states, success confirmations, color variants, keyboard shortcut badges, and micro-ripple feedback.
Underlined OTP Input
A sleek, minimalist bottom-border verification input featuring an expanding focus accent line, sliding character spring physics, and mobile SMS authentication styling.
