Skip to content
WANCRAFT

F.53Forms & Inputs

Password Strength

A password field with show/hide, a four-segment strength meter and a live requirement checklist.

NewReactMotionTailwindintermediate

Overview

Password Strength pairs a native password input with a labelled show/hide toggle (aria-pressed), an animated four-segment meter and a live requirement checklist whose ticks draw in as rules are met. Strength comes from a small, transparent heuristic exported as estimatePasswordStrength: character-pool entropy, minus penalties for repeats, sequences, years and a short list of common passwords and keyboard walks, with caps for short or common passwords. It is a UI guide, not zxcvbn and not a security guarantee. Requirements are customisable ({ id, label, test }), the meter and checklist are linked to the input with aria-describedby, and the strength label is announced politely after a pause in typing. The ref and every native input prop are forwarded.

01Installation

Method 01 · Registry

CLI verified

Uses the shadcn CLI in a project initialised with shadcn init. Installs the file to components/ui/password-strength.tsx and adds its dependencies.

npx shadcn@latest add https://wancraft.my/r/password-strength.json

Method 02 · Copy and paste

  1. 1. Install the dependencies below.
  2. 2. Copy the source from the Code tab into components/ui/password-strength.tsx.
  3. 3. Import it and adjust props.
npm install motion
Dependencies
motion
Peer
react ≥ 18, tailwindcss ≥ 4
Added
13 Oct 2026
Updated
—

02Usage

The default configuration. Change properties above to generate a tailored example in the Usage tab.

example.tsx
import { PasswordStrength } from "@/components/ui/password-strength";

export function PasswordStrengthExample() {
  return (
    <div className="w-full max-w-sm">
      <PasswordStrength name="password" required />
    </div>
  );
}

03Props

PropTypeDefaultDescription
labelReactNode"Password"Visible <label htmlFor>.
minLengthnumber8Used by the default requirements, the heuristic cap and native minLength validation.
requirements{ id: string; label: string; test: (value: string) => boolean }[]—Checklist rules. Defaults to defaultPasswordRequirements(minLength).
showRequirementsbooleantrueShow the live checklist.
showFeedbackbooleantrueShow the heuristic's top suggestion.
allowRevealbooleantrueShow the show/hide toggle.
strengthLabels[string, string, string, string, string]["Very weak", "Weak", "Fair", "Good", "Strong"]Labels for scores 0–4.
onStrengthChange(result: { score; bits; feedback }) => void—Called when typing changes the score.
hint / errorReactNode—Helper text and error message (aria-describedby; error sets aria-invalid).
accentstring"#FF7448"Focus ring colour.
inputClassNamestring—Classes for the <input>; className targets the wrapper.
...propsInputHTMLAttributes—Native input props (name, value, onChange, required…). Ref goes to the <input>; autoComplete defaults to new-password.

04Features

  • 01Show/hide toggle with an animated eye slash; focus stays on the toggle
  • 02Four-segment meter that fills and recolours with a short stagger
  • 03Live checklist with spring-drawn ticks; rules are plain { id, label, test } objects
  • 04Transparent heuristic (estimatePasswordStrength) exported for server-side reuse or tests
  • 05Controlled or uncontrolled; forwards ref and every native input prop
motion · springmotion · tweeninput · keyboardinput · focusinput · click

05Accessibility

  • Real <label htmlFor>; the toggle is a button named "Show password" with aria-pressed and aria-controls.
  • The meter is role="meter" with a text value ("Good"); strength is always shown as text, never colour alone.
  • aria-describedby links the strength label, checklist, hint and error to the input.
  • Checklist items carry screen-reader text ("met" / "not met"); a polite live region announces the strength 0.9 s after typing pauses.
  • prefers-reduced-motion removes the segment stagger, tick drawing and slash animation.

06Limitations

  • The heuristic is a rough estimate with a tiny common-password list. It is not zxcvbn, does not check breach corpora, and must not replace server-side policy.