Input OTP
weekendsuperhero-io-sistine/input-otpUnverifiedComponent
Accessible one-time password component with copy paste functionality.
Install it
npx shadcn@latest add https://raw.githubusercontent.com/Weekendsuperhero-io/sistine/main/input-otp.jsonSource
1"use client";23import { Dot } from "@phosphor-icons/react";4import { OTPInput, type RenderProps, type SlotProps } from "input-otp";5import * as React from "react";67import { type MaterialAxisProps, materialSurface, splitAxisProps } from "@/lib/material";8import { cn } from "@/lib/utils";910/* Root role: bordered adaptive glass. */11const ROOT_ROLE = {12 border: true,13};1415/* Slot role: borderless adaptive glass (the slot draws its own border-y/border-r chrome). */16const SLOT_ROLE = {};1718const InputOTP = React.forwardRef<19 React.ElementRef<typeof OTPInput>,20 Omit<React.ComponentPropsWithoutRef<typeof OTPInput>, "render" | "children"> &21 MaterialAxisProps & {22 variant?: "default" | "glass";23 render?: (props: RenderProps) => React.ReactNode;24 }25>(({ className, variant = "glass", render, ...props }, ref) => {26 const [axes, rest] = splitAxisProps(props);27 /* Variant classes carry BEHAVIOR only; the surface comes from materialSurface. */28 const variants = {29 default: "",30 glass: "rounded-lg",31 };3233 const m = materialSurface(variant === "default" ? null : ROOT_ROLE, axes);3435 const defaultRender = ({ slots }: { slots: SlotProps[] }) => (36 <InputOTPGroup variant={variant}>37 {slots.map((slot, index) => (38 <InputOTPSlot key={index} {...slot} variant={variant} />39 ))}40 </InputOTPGroup>41 );4243 return (44 <OTPInput45 ref={ref}46 data-slot="input-otp"47 data-material={m?.["data-material"]}48 containerClassName={cn(m?.className, "flex items-center gap-2 has-disabled:opacity-50", variants[variant], className)}49 className="disabled:cursor-not-allowed"50 render={render || defaultRender}51 {...rest}52 />53 );54});55InputOTP.displayName = "InputOTP";5657const InputOTPGroup = React.forwardRef<58 React.ElementRef<"div">,59 React.ComponentPropsWithoutRef<"div"> & {60 variant?: "default" | "glass";61 /** Resting glow (folded from the glass wrapper). */62 glow?: boolean;63 }64>(({ className, variant = "glass", glow, ...props }, ref) => {65 const variants = {66 default: "flex items-center gap-1",67 glass: "flex items-center gap-1",68 };6970 return <div ref={ref} data-slot="input-otp-group" className={cn(variants[variant], glow && "glass-glow", className)} {...props} />;71});72InputOTPGroup.displayName = "InputOTPGroup";7374const InputOTPSlot = React.forwardRef<75 React.ElementRef<"div">,76 SlotProps &77 React.ComponentPropsWithoutRef<"div"> &78 MaterialAxisProps & {79// … truncated
What it pulls in
npm packages
Other registry items
Files it writes
More from weekendsuperhero-io/sistine
All 71 items| Component | Registry | Kind | Access | Installs | Command |
|---|---|---|---|---|---|
| Accordionaccordion | weekendsuperhero-io/sistine | Components | Unverified | 5 deps · 4 files | |
| Alertalert | weekendsuperhero-io/sistine | Components | Unverified | 3 deps · 4 files | |
| Alert Dialogalert-dialog | weekendsuperhero-io/sistine | Components | Unverified | 4 deps · 4 files | |
| Auto Foregroundauto-foreground | weekendsuperhero-io/sistine | Components | Unverified | no deps | |
| Avataravatar | weekendsuperhero-io/sistine | Components | Unverified | 4 deps · 4 files | |
| Badgebadge | weekendsuperhero-io/sistine | Components | Unverified | 4 deps · 4 files | |
| Breadcrumbbreadcrumb | weekendsuperhero-io/sistine | Components | Unverified | 5 deps · 4 files | |
| Buttonbutton | weekendsuperhero-io/sistine | Components | Unverified | 4 deps · 4 files |
