Staaarter

PIN Keypad Unlock

Full-height numeric keypad lock screen. A row of PIN dots fills in as digits are entered, and a 3x3 keypad plus biometric shortcut, 0, and backspace buttons drive real local state, showing a brief success message once the PIN reaches full length.

By Staaarter Team
Auth
Docs
Live preview

Docs

Installation

A real shadcn registry command, not a copy-paste stand-in: it fetches this block plus its dependencies and any missing npm packages, and installs them straight into your project.

npx shadcn add https://staaarter.com/r/pin-keypad-unlock.json

Prefer not to use the CLI? Copy the source from the Code toggle above into src/components/blocks/auth/auth30.tsx instead.

Usage

The file also exports auth30Demo, the exact props behind the preview above. Spread it to get a working section in one line, then replace it with your own data.

import { Auth30, auth30Demo } from "@/components/blocks/auth/auth30";

export default function Page() {
  return <Auth30 {...auth30Demo} />;
}

Props

PropTypeDefaultDescription
headingstring"Welcome back"Heading above the PIN dots.
descriptionstring"Enter your PIN to unlock"Helper text shown until the PIN is complete.
pinLengthnumber4Number of digits required, e.g. 4 or 6.
successMessagestring"Unlocked, redirecting…"Message shown in place of the description once the PIN reaches pinLength.
classNamestringnoneExtra classes for the outer section element.

Behavior notes

  • Real client state: digit and 0 buttons append to a local PIN string, the backspace button removes the last digit, and the dot row fills in live as digits are entered.
  • Once the entered digits reach pinLength, the digit and 0 buttons disable and the description text swaps to successMessage; this is a purely local, in-demo "unlock", nothing is actually authenticated.
  • The biometric shortcut button is decorative only, it has no click handler wired up since it would require a real device API.
  • Success state is derived directly from digits.length during render, not set via an effect, so it never needs a `set-state-in-effect` workaround.