Strength meter
ProHow strong a password (or a passphrase, a key) is, on a 0 to 4 scale in four segments, with the word for the score ("Fair"). The score is the app's, from an estimator such as zxcvbn; the meter never guesses. basis is required and shown under the meter, so a person can tell what measured it ("Measured by zxcvbn's estimate"): a meter that doesn't say what it measures can't be trusted. With score null it says "Not checked" and fills nothing.
Screen readers hear a meter named by label with the word as its value. The segments are drawn as bordered boxes, so forced colours keep how far it is filled.
Version 5.2.0· other versions
This page is for 5.2.0, the current release. An earlier release’s page is the Markdown that release published, so the docs match the version you have installed (candor-lock.json records it).
Not in the docs of 1.3.0, 1.4.0, 1.5.0, 1.5.1, 1.6.0, 1.7.0, 1.8.0, 1.8.1, 1.9.0, 1.9.1, 2.0.0, 2.1.0, 2.2.0, 2.3.0, 2.4.0, 2.5.0, 2.5.1, 2.6.0, 2.6.1, 2.6.2, 2.7.0, 2.8.0, 2.9.0, 2.10.0, 3.0.0, 4.0.0, 4.0.1, 4.0.2, 4.1.0, 4.2.0 and 4.3.0: the page came later, or had another name then.
Docs pages weren’t kept for 1.0.0, 1.0.1, 1.1.0, 1.1.1, 1.2.0 and 1.2.1: they are kept from 1.3.0 on, and before that only llms.txt was published.
Preview
Loading the preview
Install
First time? Get started sets up the registry and theme. Or with shadcn directly: npx shadcn@latest add @candor/strength-meter
Usage
"use client"
import * as React from "react"
import { Field } from "@/components/candor/ui/field"
import { Input } from "@/components/candor/ui/input"
import { StrengthMeter, type StrengthScore } from "@/components/candor/ui/strength-meter"
// The score is the app's, from its estimator; here a stand-in by length and kinds of character, and the basis says so.
// A real app passes zxcvbn's score and says "zxcvbn's estimate".
const estimate = (text: string): StrengthScore | null => {
if (!text) return null
const kinds = [/[a-z]/, /[A-Z]/, /\d/, /[^\w]/].filter((r) => r.test(text)).length
return Math.max(0, Math.min(4, Math.floor(text.length / 4) + kinds - 2)) as StrengthScore
}
export default function Example() {
const [password, setPassword] = React.useState("")
return (
<div className="flex w-full max-w-sm flex-col gap-3">
<Field label="New password">
<Input type="password" autoComplete="new-password" value={password} onChange={(e) => setPassword(e.target.value)} />
</Field>
<StrengthMeter score={estimate(password)} basis="this example's length and character check" />
</div>
)
}<StrengthMeter>
| Prop | Type | Default | Description |
|---|---|---|---|
| scorerequired | StrengthScore | null | — | The app's score, 0 (very weak) to 4 (very strong), or `null` while nothing has been checked. |
| basisrequired | string | — | What the score is measured by, shown under the meter: "zxcvbn's estimate", "the server's policy check". Required. |
| label | string | undefined | — | The meter's name: "Password strength" by default. |
| className | string | undefined | — | Classes for the outer box. |
Strings
The fixed words, in English by default. Change any of them under strengthMeter in <LocaleProvider strings={{ … }}>; the table is exported as strengthMeterStrings.
| Key | English |
|---|---|
| label | Password strength |
| score0 | Very weak |
| score1 | Weak |
| score2 | Fair |
| score3 | Strong |
| score4 | Very strong |
| notChecked | Not checked |
| basis | Measured by {basis} |
Motion
| Moment | Family | What it does |
|---|---|---|
| score | fill | The segments fill to the app's new score; one drawn with a score is still. |
Set with --cd-motion-strength-meter-<moment>-* in your brand file; the families are in the design reference.
Types
- StrengthScore
- A score on the 0 to 4 scale password estimators use (zxcvbn's), or `null` for not checked.
0 | 1 | 2 | 3 | 4