fetaUI
GitHub

Padlock

A gunmetal padlock whose shackle lifts as a code is checked and pops free when it is right.

FreeWeb and MobileMotion

Preview

npx shadcn add @fetaui/padlock
Playground
Locked
Locked
Checking
Open
Error
Sizes
Themes
Status
Icons animation
Motion

Installation

Terminal· bash
 npx shadcn add @fetaui/padlock

Accessibility

  • Decorative by default, and role img when you pass aria-label.
  • With announce, a polite live region reads the status words on each change. Leave it off when the page already announces the result.

Motion

  • Checking lifts the shackle 10 px on the press spring and a faint glint crosses the face every 2.2 s. The glint pauses offscreen.
  • Open pops the shackle 28 px on the stamp spring with a 4 degree swing about the left leg, over 560 ms. The right leg comes free, the body gives 2.5 px, and the rings light green 35 ms apart.
  • Locking from open lands on the snap spring and the body takes the click 100 ms later.
  • Error tugs the shackle 6 px and holds, then the lock shakes once over 360 ms while the rings light red.
  • With reduced motion, the shackle fades out and back in its new place over 200 ms and the rings only fade. With animated false nothing moves.

Responsive behavior

  • Scales with width. Keep it at 72 px or more so the emblem stays readable.

Performance

  • One SVG. Motion runs on motion values only when status changes, so no React state changes per frame.
  • The only loop is the checking glint, a CSS transform that pauses offscreen and stops outside checking.
  • Filters are static and gradient ids come from useId, so several locks can share a page.

Note for AI

Give your coding assistant the Markdown reference instead of screenshots.

  • Import Padlock from @/components/fetaui/padlock.
  • status is locked, checking, open or error, and you drive it from your own check.
  • It is decorative unless you pass aria-label. Pass announce only when nothing else on the page reads the result.
  • Its metal comes from the fixed zinc ramp on purpose and reads the same in Light and Dark. Only the emblem follows the status tokens.

Related