Skip to content
NewService Map: 30 components for hosts, ports and routes
<hf-pin>Custom elementInputsFree

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.

View as Markdown
<hf-pin>

Trytry a wrong PIN first.

Playground

Change a prop and the component updates. Props marked live animate to the new value; the others rebuild the element.

Loading <hf-pin>
Props
coderemounts
labelremounts
hintremounts
successremounts
<HfPin
  code="2468"
  label="Enter your PIN"
  hint="Demo PIN: 2468"
  success="Unlocked"
/>

Installation

pnpm dlx shadcn@latest add @lumesec/hf-pin
First 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}.json

Or skip the setup and install by URL:

npx shadcn@latest add https://elements.lumesec.ai/r/hf-pin.json

Usage

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 propcodeTypestringDefault2468

The expected PIN. Its length sets the number of dots. Compared in the browser.

labelReact proplabelTypestringDefaultEnter your PIN

Title above the dots. Read once on connect.

hintReact prophintTypestring

Status text under the title. Defaults to <n> digits, where <n> is the length of code.

successReact propsuccessTypestringDefaultUnlocked

Status 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)Typestring

The code attribute, or 2468.

Keyboard

KeysAction
0–9Enter a digit while the pad or one of its keys has focus.
BackspaceDelete the last digit.
EscapeClear all digits.

Accessibility

  • The pad is focusable (tabindex="0") with aria-label="PIN entry" but no role.
  • Keys are native buttons; the delete key has aria-label="Delete".
  • The dots have role="img" and an aria-label such as 2 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-hidden canvas.
  • 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: code sits 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.
  • error stays on the element, so it does not reach window or global error handlers such as error-tracking scripts. unlock bubbles and is composed.
  • The pad is a fixed 236px wide and the host is inline-block.

Was this page helpful?