@ngx-zen/mat-password-meter
v2.0.2
Published
An Angular Material password strength indicator
Downloads
1,377
Maintainers
Readme
@ngx-zen/mat-password-meter
Three Angular Material password strength components with a signals-based API. Live Demo →
| Rule-based | Entropy-based |
|:---:|:---:|
|
|
|
PasswordStrengthComponent— combines rule enforcement + zxcvbn entropy in two phases.PasswordRulesComponent— policy checks only; zxcvbn is never loaded.PasswordAnalysisComponent— zxcvbn entropy only; no policy enforcement.
Features
- Three components: rules-only, entropy-only, or combined — use only what you need
- Signals-based API — reactive
input(),output(), andcomputed()throughout - Three feedback modes:
'contextual'hint,'full'panel, or'hidden' - Extensible with app-specific rules via
customRules— e.g. "must not contain username" - Fully customizable display strings via
messages— tailor labels, hints, and nudges to your brand or UX - zxcvbn lazy-loaded — no bundle cost when using only
PasswordRulesComponent - Fully themeable via CSS custom properties; adapts to light/dark themes automatically
Version compatibility
| Library | Angular | Angular Material | zxcvbn |
|---------|---------|------------------|--------|
| 2.x | ^20 | ^20 | ^4.4.2 |
| 1.x | ^19 | ^19 | ^4.4.2 |
Installation
npm install @ngx-zen/mat-password-meter zxcvbn[!TIP] Only using
PasswordRulesComponent? You can skipzxcvbn— it's not needed for that entry point.
[!NOTE] Requires Angular Material with animations and a theme. See the Angular Material getting started guide.
Usage
import { PasswordStrengthComponent } from '@ngx-zen/mat-password-meter/strength';
import { PasswordRulesComponent } from '@ngx-zen/mat-password-meter/rules';
import { PasswordAnalysisComponent } from '@ngx-zen/mat-password-meter/analysis';Add to imports and bind [password] to your form control value:
<!-- PasswordStrengthComponent -->
<mat-password-strength [password]="password" [options]="{ min: 12 }" (isValid)="submitDisabled = !$event" />
<!-- PasswordRulesComponent -->
<mat-password-rules [password]="password" [options]="{ min: 12, specialChar: false }" (isValid)="submitDisabled = !$event" />
<!-- PasswordAnalysisComponent -->
<mat-password-analysis [password]="password" [userInputs]="[user.name, user.email]" (isValid)="submitDisabled = !$event" />feedback defaults to 'contextual' (single inline hint). Use feedback="full" for the progressive panel or feedback="hidden" to hide all feedback text.
API
All three components share the same base inputs and outputs. Differences are noted in the descriptions.
Inputs
| Input | Type | Default | Description |
|-------|------|---------|-------------|
| password | string | '' | Password to evaluate |
| options | PasswordRuleOptions | see below | Policy rules. Not used by PasswordAnalysisComponent. |
| hideStrength | boolean | true | Hide the strength label below the bar |
| feedback | FeedbackMode | 'contextual' | 'contextual', 'full', or 'hidden' |
| userInputs | string[] | [] | Strings passed to zxcvbn to penalize personal info. Not used by PasswordRulesComponent. |
| customRules | CustomRulesFn | — | App-specific policy gates. Block isValid and show as failing hints when violated; do not affect score. Not used by PasswordAnalysisComponent. |
| messages | PasswordMeterMessages | see below | Override any subset of display strings |
Outputs
| Output | Type | Description |
|--------|------|-------------|
| strengthChange | number | Current 0–100 score on every password change |
| isValid | boolean | true when fully satisfied (both rules + zxcvbn for PasswordStrengthComponent) |
Shared types
import type { PasswordRuleOptions, PasswordMeterMessages, CustomRulesFn } from '@ngx-zen/mat-password-meter';Types:
PasswordRuleOptions,PasswordRuleCheck,FeedbackMode,ZxcvbnResult,PasswordMeterMessages,PasswordStrengthLabels,PasswordRuleLabels,DisabledOptionKey,CustomRulesFn
Constants:DEFAULT_PASSWORD_RULE_OPTIONS,DEFAULT_PASSWORD_METER_MESSAGES
Utilities:evaluateRules,scoreFromChecks
PasswordRuleOptions
All properties optional; omitted keys fall back to defaults. Pass false to disable a rule (e.g. { specialChar: false }).
| Property | Type | Default |
|----------|------|---------|
| min | number | 8 |
| lowercase | boolean | true |
| uppercase | boolean | true |
| number | boolean | true |
| specialChar | boolean | true |
PasswordMeterMessages
All properties optional; omitted keys fall back to defaults. For string keys, pass '' to suppress that message entirely. Not all keys apply to every component.
| Property | Type | Default | Description |
|----------|------|---------|-------------|
| looksGreat | string | 'Looks great!' | Shown when strength is perfect |
| nudge | string | 'Make it harder to guess.' | Shown when zxcvbn score < 4 with no warning or suggestions. Not used by PasswordRulesComponent. |
| disabledNudge | (missingKeys: DisabledOptionKey[]) => string | — | Replaces the auto-generated disabled-options nudge. Not used by PasswordRulesComponent. Receives the keys of disabled composition options whose character classes are missing (e.g. ['uppercase', 'number']). Return '' to suppress. |
| strengthLabels | PasswordStrengthLabels | {} | Override the strength level labels below the bar |
| ruleLabels | PasswordRuleLabels | {} | Override the per-rule checklist labels. Not used by PasswordAnalysisComponent. |
Example — customizing display strings to match your app's tone:
readonly messages: PasswordMeterMessages = {
looksGreat: 'Excellent!',
nudge: 'Try making it harder to guess.',
// Replace the default "Try adding …" nudge, or return '' to suppress
disabledNudge: (keys) => `Consider adding ${keys.join(' or ')} for extra security.`,
strengthLabels: { veryWeak: 'Too simple', veryStrong: 'Excellent' },
ruleLabels: { minLength: (n) => `Use at least ${n} characters` },
};<mat-password-strength [password]="password" [messages]="messages" />| Key | Default |
|-----|---------|
| veryWeak | 'Very Weak' |
| weak | 'Weak' |
| fair | 'Fair' |
| good | 'Good' |
| strong | 'Strong' |
| veryStrong | 'Very Strong' |
| Key | Default |
|-----|---------|
| minLength | `At least ${n} characters` (also accepts (n: number) => string) |
| lowercase | 'At least 1 lowercase letter' |
| uppercase | 'At least 1 uppercase letter' |
| number | 'At least 1 number' |
| specialChar | 'At least 1 special character' |
Configuration
Custom rules
Use the customRules input to add app-specific checks (e.g. "must not contain username"). Custom rules act as gates — they block isValid and appear as failing hints when violated, but they do not affect the strength score. The progress bar color switches to warn while any custom rule fails, even if the strength score is 100%. Only failing custom rules are shown; passing ones are hidden.
import type { CustomRulesFn } from '@ngx-zen/mat-password-meter';
readonly customRules: CustomRulesFn = (password) => [
{ label: 'Must not contain username', passed: !password.includes(this.username) },
{ label: 'Must not match a previous password', passed: !this.previousPasswords.includes(password) },
];<mat-password-strength [password]="password" [customRules]="customRules" />
<mat-password-rules [password]="password" [customRules]="customRules" />
customRulesis not used byPasswordAnalysisComponent— it has no rule phase.
NIST alignment
NIST SP 800-63B recommends against composition rules (mixed case, digits, special characters) and instead favors a longer minimum length. You can opt in to a NIST-aligned configuration with PasswordStrengthComponent:
const NIST_OPTIONS: PasswordRuleOptions = {
min: 15,
lowercase: false,
uppercase: false,
number: false,
specialChar: false,
};<mat-password-strength [password]="password" [options]="NIST_OPTIONS" />With all composition rules disabled, only min is enforced. PasswordStrengthComponent will still evaluate entropy via zxcvbn and may show a contextual nudge (e.g. "→ Try adding uppercase letters…") when the score is low. This also applies to PasswordAnalysisComponent. Customize or suppress the nudge via the disabledNudge callback in messages.
[!WARNING] This configuration is not recommended for
PasswordRulesComponent, which has no zxcvbn phase — it would reduce to a minimum-length check with no quality feedback.
Direct signal access
Public computed signals accessible via viewChild:
| Component | Signals |
|-----------|--------|
| PasswordStrengthComponent | strength, ruleChecks, customRuleChecks, zxcvbnResult, mergedHint, color, strengthLabel |
| PasswordRulesComponent | strength, ruleChecks, customRuleChecks, contextualHint, color, strengthLabel |
| PasswordAnalysisComponent | strength, zxcvbnResult, color, strengthLabel |
readonly meter = viewChild(PasswordStrengthComponent);
protected readonly isValid = computed(() => this.meter()?.strength() === 100);
protected readonly firstFail = computed(() => this.meter()?.ruleChecks().find(r => !r.passed)?.label);Theming
Components adapt to light/dark themes via Angular Material design tokens (--mat-sys-*). Override colors via CSS custom properties:
mat-password-rules,
mat-password-analysis,
mat-password-strength {
/* Progress bar colors */
--pm-weak-color: #e53935;
--pm-medium-color: #fdd835;
--pm-strong-color: #43a047;
--pm-buffer-color: #888888;
/* Text colors */
--pm-rule-pass-color: light-dark(#2e9244, #66bb6a);
--pm-rule-fail-color: light-dark(#d32f2f, #ef5350);
--pm-warning-color: light-dark(#7a6000, #c9a200);
--pm-secondary-text: light-dark(#555, #aaa);
}Acknowledgments
Inspired by angular-material-extensions/password-strength.
NIST alignment guidance suggested by u/JimTheEarthling on Reddit.
