Sticker OTP
A die-cut strip of code cells. Digits land with a pop and the strip glows as one object when the code completes.
InputsClient component
Preview
Installation
The CLI writes the source into your project and pulls in whatever it depends on.
$
pnpm dlx shadcn@latest add @duck/sticker-otpPulls in @duck/theme. Already installed items are skipped.
Usage
import { StickerOtp } from "@/components/ui/sticker-otp"The file lands in components/ui/sticker-otp.tsx and belongs to you from that point on. Edit it in place rather than wrapping it.
Props
Everything not listed here is forwarded to the underlying element.
| Prop | Type | Default | Description |
|---|---|---|---|
| length | number | 6 | Number of cells. |
| value / defaultValue / onValueChange | string | - | Digits only. Anything else is stripped as it arrives. |
| onComplete | (value: string) => void | - | Fires once the last cell fills. |
Rules
What keeps this component from turning into noise.
- One input, not one per cell. Six inputs break paste, break password managers, and announce "edit blank, one of six".
- autoComplete="one-time-code" is what triggers iOS SMS autofill. Without it this is worse than a plain text input on a phone.
- Errors go in the field, not in a toast. If you auto-submit on the last digit, still render a submit button.
