PIN pad
Numeric PIN pad with rippling keys and dot feedback: a wrong code shakes into red static, the right one sends a green wave.
Playground
Change a prop and the component updates. Props marked live animate to the new value; the others rebuild the element.
<HfPin code="2468" label="Enter your PIN" hint="Demo PIN: 2468" success="Unlocked" />
Installation
pnpm dlx shadcn@latest add @lumesec/hf-pinFirst timeRegister the @lumesec registry once, or install by URL+
Adds @lumesec to your components.json:
pnpm dlx shadcn@latest registry add @lumesec=https://elements.lumesec.ai/r/{name}.jsonOr skip the setup and install by URL:
npx shadcn@latest add https://elements.lumesec.ai/r/hf-pin.jsonUsage
import { HfPin } from "@/components/lumesec/hf-pin";
export function Example() {
return (
<HfPin code="2468" hint="Demo PIN: 2468" />
);
}Behaviour
Keys ripple when pressed, dots pop in with bloom, a wrong code turns them to red static and shakes, and the right one sends a green wave. Your keyboard works too.
API reference
Attributes
codeReact propcodeTypestringDefault2468The expected PIN. Its length sets the number of dots. Compared in the browser.
labelReact proplabelTypestringDefaultEnter your PINTitle above the dots. Read once on connect.
hintReact prophintTypestringStatus text under the title. Defaults to <n> digits, where <n> is the length of code.
successReact propsuccessTypestringDefaultUnlockedStatus text after a correct PIN.
Events
Events bubble and cross the shadow boundary unless the description says otherwise.
unlockReact proponUnlockDetail{}Fires when the entered digits match code.
errorReact proponErrorDetail{ tries: number }Fires on a wrong PIN. tries is the number of attempts left: 2, 1, then 0. Does not bubble and is not composed: listen on the element itself, as the React onError prop does.
Properties
code (read-only)TypestringThe code attribute, or 2468.
Keyboard
| Keys | Action |
|---|---|
| 0–9 | Enter a digit while the pad or one of its keys has focus. |
| Backspace | Delete the last digit. |
| Escape | Clear all digits. |
Accessibility
- The pad is focusable (
tabindex="0") witharia-label="PIN entry"but no role. - Keys are native buttons; the delete key has
aria-label="Delete". - The dots have
role="img"and anaria-labelsuch as2 of 4 digits entered, updated on every key. - The status line under the title is an
aria-live="polite"region: hint, wrong PIN with tries left, and success. - Ripples and dots are drawn on an
aria-hiddencanvas. - Reduced motion: dots do not pop, a wrong PIN does not shake or jitter, and the status changes without rolling; key ripples, red static and the green wave remain.
Theming
The element reads your shadcn theme tokens through its shadow root, so light and dark follow your theme. The accent comes from --lumesec. See Theming.
This component reads --foreground, --lumesec and --muted-foreground.
To restyle only LumeSec elements, set the matching --ui-* overrides: --ui-accent, --ui-fg and --ui-muted.
Notes
- Demo control:
codesits in the markup and is compared in the browser, so it provides no security. Check real PINs on a server and use the events for the UI. - The PIN is checked 160 ms after the last digit. Entry clears 0.9 s after a wrong PIN and 2.4 s after a correct one.
- After three wrong PINs the status reads
Too many attempts · try again later, then the counter resets to three; there is no lockout. errorstays on the element, so it does not reachwindowor globalerrorhandlers such as error-tracking scripts.unlockbubbles and is composed.- The pad is a fixed 236px wide and the host is
inline-block.
Related
Was this page helpful?