OTP Input
rare-ui/otp-inputFreeComponent
A one-time-code input whose characters roll into place behind a caret that slides from slot to slot.
Install it
npx shadcn@latest add https://rareui.com/r/otp-input.jsonSource
1"use client";23import { useRef, useState, type ComponentProps } from "react";4import { AnimatePresence, motion, useReducedMotion } from "motion/react";5import { cn } from "@/lib/utils";67const PATTERNS = {8 numbers: /^[0-9]$/,9 letters: /^[a-zA-Z]$/,10 both: /^[a-zA-Z0-9]$/,11} as const;1213// success draws its own ring in svg, so no css ring here14const RING = {15 idle: "focus-visible:ring-2 focus-visible:ring-[#868593]/50",16 success: "",17 error: "ring-2 ring-[#FF3B30]/70 delay-150",18} as const;1920const SUCCESS = "#34C759";2122const SIZES = {23 sm: {24 box: "size-10 rounded-lg",25 text: "text-base",26 caret: "h-5",27 gap: "gap-1.5",28 px: 40,29 radius: 8,30 },31 md: {32 box: "size-12 rounded-xl",33 text: "text-lg",34 caret: "h-6",35 gap: "gap-2",36 px: 48,37 radius: 12,38 },39 lg: {40 box: "size-14 rounded-2xl",41 text: "text-xl",42 caret: "h-7",43 gap: "gap-2.5",44 px: 56,45 radius: 16,46 },47} as const;4849const SLOT_CLASS =50 "bg-[#F4F4F9] dark:bg-[#262626] text-center font-medium text-transparent caret-transparent outline-none transition-shadow duration-200 selection:bg-transparent disabled:cursor-not-allowed disabled:opacity-50";5152const ROLL_SPRING = { type: "spring", stiffness: 500, damping: 34 } as const;53const CARET_SPRING = { type: "spring", stiffness: 500, damping: 40 } as const;54const BLINK = {55 duration: 1.1,56 times: [0, 0.5, 0.5, 1],57 repeat: Infinity,58 ease: "linear" as const,59};6061const ROLL = {62 initial: { y: "110%" },63 exit: (cleared: boolean) => ({ y: cleared ? "110%" : "-110%" }),64};6566const SHAKE = [0, -5, 4, -2, 0];6768const toSlots = (code: string, length: number) =>69 Array.from({ length }, (_, i) => code[i] ?? "");7071export type OtpStatus = "idle" | "success" | "error";7273export type OtpInputProps = Omit<74 ComponentProps<"div">,75 "onChange" | "value" | "defaultValue"76> & {77 length?: number;78 value?: string;79 defaultValue?: string;80 onChange?: (value: string) => void;81 onComplete?: (value: string) => void;82 type?: keyof typeof PATTERNS;83 size?: keyof typeof SIZES;84 status?: OtpStatus;85 mask?: boolean;86 disabled?: boolean;87 autoFocus?: boolean;88 slotClassName?: string;89};9091export function OtpInput({92 length = 6,93 value,94 defaultValue = "",95 onChange,96 onComplete,97 type = "numbers",98 size = "md",99 status = "idle",100 mask = false,101 disabled,102 autoFocus,103 className,104 slotClassName,105 ...props106}: OtpInputProps) {107 const [uncontrolled, setUncontrolled] = useState(() =>108// … truncated
What it pulls in
npm packages
Other registry items
Files it writes
More from rare-ui
All 13 items| Component | Registry | Kind | Access | Installs | Command |
|---|---|---|---|---|---|
| Bounce Sidebarbounce-sidebar | rare-ui | Components | Free | 1 dep | |
| Code Blockcode-block | rare-ui | Components | Free | 3 deps | |
| Duration Pickerduration-picker | rare-ui | Components | Free | 5 deps | |
| Emoji Reactionemoji-reaction | rare-ui | Components | Free | 4 deps | |
| Family Drawerfamily drawer | rare-ui | Components | Free | 2 deps | |
| Fluid Orbfluid-orb | rare-ui | Components | Free | no deps | |
| Folder Componentfolder-component | rare-ui | Components | Free | 1 dep | |
| GitHub Activitygithub-activity | rare-ui | Components | Free | 1 dep |
