Bundles save up to 25%. See every bundle

Code Boss
Dark

Full screen

What it does

A complete "enter the code we sent you" card drawn as a padlock. Four wheels sit in the lock body under a steel shackle. A glowing ring glides to the wheel that takes the next digit, and each digit rolls into view like a combination dial, further digits taking a little longer. While the code is checked, a light sweeps across the body. A wrong code is someone tugging a locked padlock: the shackle is yanked twice, the body shudders, the wheels rim red and roll back to blank. A right one lifts the shackle, swings it open round its long leg and turns the lock green, and a Continue button rises.

Good for
Two-step sign-in, phone and email confirmation, PIN and passcode screens, anywhere "unlocking" is the right word for what the user is doing.
How it works
One real input sits invisibly over the wheels, so paste, SMS autofill and screen readers work the usual way. Your check runs as soon as the last digit is in, and its answer picks the ending. The wheels are strips of digits moved with CSS transitions, so a roll that is interrupted continues from where it is. A resend button counts down before it can be pressed.
How to use
Copy two files, paste the markup, pass your own onComplete(code). Four or six wheels: add or remove slots.

Specs

Price
$5, one payment
Version
1.0.0
Code size
7.7 KB gzipped
Dependencies
None
Built with
HTML, CSS, JavaScript, SVG
Category
Form
Licence
Unlimited personal and client projects
In the zip
  • hasp.css hasp.jsthe component
  • index.htmla plain example page
  • README.md package.json vite.config.js LICENSE.md

Use it in your project

  1. Copy hasp.css and hasp.js into your project.
  2. Add the markup from index.html (the block between the COMPONENT comments). One .hasp-wheel per digit: four are in the example, six work the same (the body grows with them).
  3. Start it and connect your own check:
import { init } from './hasp.js';

const hasp = init(document.querySelector('.hasp'), {
  onComplete: async (code) => {
    const res = await fetch('/api/verify', { method: 'POST', body: JSON.stringify({ code }) });
    if (!res.ok) throw new Error('That code has expired. Send a new one.'); // shown under the lock
  },
  onResend: () => fetch('/api/send-code', { method: 'POST' }),
  onContinue: () => { location.href = '/dashboard'; },
});

onComplete runs as soon as the last digit is in. Return false or throw to show an error: the shackle is tugged twice, the body shudders, the wheels rim red and roll back to blank so the user can type again. Resolve and the shackle rises, swings open round its long leg and turns green with the body, and a Continue button appears.

There is one real <input> under the wheels, so the things that normally work with a code field still do: paste, SMS and email autofill (autocomplete="one-time-code"), the numeric keyboard on phones, and screen readers.

Questions

What exactly do I get?

The full source, an example page and a README. No account, no framework.

Can I use it in client projects?

Yes, in unlimited projects. You can't resell or share the source itself.

Does it check the code?

It calls your function with the code and shows the answer. Checking belongs on your server; the demo only compares against a fixed code.

Does autofill from SMS work?

Yes. It's a normal input with autocomplete="one-time-code", so iOS and Android offer the code from the message, and the wheels roll in one after another.

Is it accessible?

One labelled field, numeric keyboard on phones, live status messages, aria-invalid on errors, and focus moves to Continue once verified. With reduced motion nothing rolls, shakes or swings.

Light and dark?

Both are designed, and every colour is a CSS variable, including the metal and the wheels.

What if it doesn't work for me?

If it doesn't work like the demo, you get a refund within 14 days.

Still have a question? Email us. The person who made it answers.

Your cart

Your cart is empty. Browse components

Full screen