Password strength

Show how strong a new password is while it is typed.

npm install https://animui.stracture.net/__local/package.tgz
Live · keyboard ready
  • At least 12 characters, not met
  • Upper and lowercase letters, not met
  • At least one number, not met
  • At least one symbol, not met
  • Sign up and change password forms.
  • Password rules that should check off live as the person types.
  • Use password-field for sign in.
  • Use progress for measurable progress unrelated to passwords.

Installation

Install animui once, then import any component or block from its typed package entry.

animui · 250 components and blocks

React 19 and React DOM 19 are required. The package includes Free and Pro entries, styles and TypeScript declarations.

npm install https://animui.stracture.net/__local/package.tgz

Load the stylesheet once at your app root, then use the typed component import:

import 'animui/styles.css';
import { PasswordStrength } from 'animui/password-strength';

Read the Code tab for the implementation files and the API reference below for required props.

Download animui 0.3.0 · Agent guide
example.tsx
import { PasswordStrength } from "animui/password-strength"; export function NewPasswordField() {  const [strong, setStrong] = useState(false);  return (    <PasswordStrength      label="New password"      name="password"      autoComplete="new-password"      onValueChange={(_, strength) => setStrong(strength.level >= 3)}    />  );}

Gate submit on strength

example.tsx
const [level, setLevel] = useState(0); <PasswordStrength  label="New password"  name="password"  autoComplete="new-password"  onValueChange={(_, strength) => setLevel(strength.level)}/><Button type="submit" disabled={level < 3}>Create account</Button>

Translated, with your own length policy

example.tsx
import { PasswordStrength, createPasswordRules } from "animui/password-strength"; const rules = createPasswordRules({  minLength: 10,  labels: {    length: min => `Mindestens ${min} Zeichen`,    case: "Gross- und Kleinbuchstaben",    number: "Mindestens eine Zahl",    symbol: "Mindestens ein Sonderzeichen",  },}); export function NewPassword() {  return (    <PasswordStrength      label="Neues Passwort"      rules={rules}      shortLength={10}      messages={{        levels: { tooShort: "Zu kurz", weak: "Schwach", fair: "Mittel", good: "Gut", strong: "Stark" },        showPassword: "Passwort anzeigen",        meterLabel: "Passwortstärke",        noPassword: "Noch kein Passwort",        rulesLabel: "Passwortanforderungen",

PasswordStrength

A new-password field with a four-segment meter, rule checklist, and a morphing strength word.

PropTypeDefaultDescription
labelRequiredstring–Visible label tied to the input.
valuestring–Controlled password.
defaultValuestring""Initial value when uncontrolled.
onValueChange(value: string, strength: PasswordStrengthResult) => void–Called on every change with the value and its { level, label, met } score.
rulesPasswordRule[]defaultPasswordRules{ id, label, test, remaining? } rules. Strength is the share met across four steps.
errorstring–Error copy; sets aria-invalid and shakes the field once per new error.
revealedboolean–Controlled show or hide state.
onRevealedChange(revealed: boolean) => void–Called when the reveal toggle is pressed.
messagesPasswordStrengthMessagesInputdefaultPasswordStrengthMessagesEvery built-in string, for translation: levels { tooShort, weak, fair, good, strong }, showPassword, meterLabel, noPassword, rulesLabel, ruleMet, ruleNotMet, remainingPrefix, remainingSuffix, and summary({ label, met, total }). Pass only what you change; the rest stay English.
shortLengthnumber8Below this many characters the meter holds at its first step and reads the tooShort word.
countCharacters(password: string) => numbercountCodePointsHow shortLength counts characters. Code points by default (an emoji counts once); pass password => password.length to match a policy that counts UTF-16 units.
...propsOmit<InputHTMLAttributes<HTMLInputElement>, "type" | "value" | "defaultValue" | "children">–Forwarded to the input, including ref, name, autoComplete, and onChange.
EnterorSpace
On the reveal button, shows or hides the password.
  • The meter is role="meter" with aria-valuenow 0 to 4 and aria-valuetext set to the strength word.
  • The rules list is linked to the input through aria-describedby along with any error; errors set aria-invalid.
  • A role="status" region summarizes strength and rules met; the reveal button uses aria-pressed and aria-controls.
  • Segments fill and change tone in a staggered wave, rules check off with drawn ticks, remaining counts roll, and the word morphs up or down with strength.
  • Reduced motion, applied after hydration, drops the shake, wave, and roll in favor of instant changes.
  • On coarse pointers the input grows to the base font size, so iOS does not zoom on focus.
  • The four-segment meter shares the row width evenly and shrinks with the column.
  • Scoring runs on the device on every keystroke with simple rule tests; there is no dictionary check.
  • One ResizeObserver per field measures the helper row for its height spring; cheap for a form, but avoid hundreds in a table.

Notes for AI

Give your coding assistant the Markdown reference instead of screenshots.

  • Use when creating or changing a password. Use password-field for sign in.
  • Controlled or uncontrolled; read strength from onValueChange to gate submit. Scoring runs on the device.
  • Also exports estimateStrength(password, rules, { shortLength, levels, countCharacters }), defaultPasswordRules, and createPasswordRules({ minLength, labels, countCharacters }) for server-side checks, translated rule labels, or your own length policy.
  • To translate, pass messages for the component's own copy and build rules with createPasswordRules({ labels }) for the rule labels. Keep shortLength and the rules' minLength in line with your server's policy.

The full library index for assistants is at /llms.txt.