KQ-1505 · PIN/SLOTS

Pin Slots

A one-time-code field whose characters drop into their slots: one real, transparent input carries the code, and each new character falls from above on springs.recoil with two small landing bounces while its slot's border catches the colour, the next empty slot holds a glow that slides along on springs.snap, a paste fills every slot in one cascade and Backspace lifts the last character out on the exit ease. When the host accepts the code the slots slide together on springs.snap until the gaps close and lock into one success bar; a refusal shakes the row on a keyframe tween and typing again starts a fresh code. Typing, Backspace, paste and SMS autofill are the browser's own, with the caret held at the end.

KQ-1505 · PIN/SLOTS

Check your phone

We sent a code to the number ending 4821.

It stays valid for ten minutes.

0 of 6 entered · try 246810

Install

One command — the source lands in your repo. Or copy it from the Code tab.

$ pnpm dlx shadcn@latest add @kinetiq/pin-slots

Props

value / defaultValue
string
default — / ""
The code, controlled or uncontrolled; anything outside the charset is dropped and it is cut to length.
onValueChange
(value: string) => void
default —
Fires from the typing, paste or Backspace that changed the code.
onComplete
(code: string) => void
default —
Fires once, from the keystroke or paste that fills the last slot.
length
number
default 6
How many slots (1 to 12).
mask
boolean
default false
Show each character as it lands, then cross-fade it into a dot.
maskDelay
number
default 600
How long a masked character stays readable, in ms.
state
"idle" | "checking" | "success" | "error"
default "idle"
The host's verdict: checking dims the glyphs under a passing light, success locks the slots into one bar, error shakes them and turns them danger.
label
string
default "Verification code"
The input's label, shown above the slots.
hideLabel
boolean
default false
Keep the label for assistive technology only.
hint
string
default —
A line under the slots while nothing has been decided.
successMessage
string
default "Code accepted."
Shown under the bar and announced when state is success.
errorMessage
string
default "That code didn’t match. Try again."
Shown under the slots and announced when state is error.
charset
"numeric" | "alphanumeric"
default "numeric"
Digits only with a numeric keypad on phones, or letters and digits, upper-cased.
split
number
default —
Draw a separator after this many slots, as in 123–456; it folds away when the slots lock.
size
"sm" | "md" | "lg"
default "md"
Slot size (largest width; narrow rows shrink below it) and glyph size.
color
"cobalt" | "signal" | "ember" | "rose" | string
default "cobalt"
The caret slot's glow, the caret and the landing flash: a preset tuned for both themes or any CSS colour.
name
string
default —
A form field name for the input.
autoFocus
boolean
default false
Focus the input on mount.
sound
boolean
default false
Tick as each typed or pasted character lands (rising along the row), chime when the slots lock, buzz on a refusal; only for a code the visitor typed.
disabled
boolean
default false
Disables the input and dims the slots.
className
string
default —
Classes for the outer column.