Password Strength

A password strength indicator component that shows password requirements and validates them in real-time. Displays a progress bar with visual feedback and a checklist of requirements.

Basic Usage

import { PasswordStrength } from '@/components'

const [password, setPassword] = useState('')

<PasswordStrength password={password} />

Must contain at least;

At least 1 symbol
At least 1 uppercase
At least 1 number
At least 8 characters

States

The component has four visual states based on how many requirements are met:

  • Idle - Empty password, gray progress bar
  • Weak - 1-2 requirements met, orange/warning progress bar
  • Medium - 3 requirements met, orange/warning progress bar
  • Strong - All requirements met, green/success progress bar

Idle (empty)

Must contain at least;

At least 1 symbol
At least 1 uppercase
At least 1 number
At least 8 characters

Weak (1-2 requirements)

Must contain at least;

At least 1 symbol
At least 1 uppercase
At least 1 number
At least 8 characters

Medium (3 requirements)

Must contain at least;

At least 1 symbol
At least 1 uppercase
At least 1 number
At least 8 characters

Strong (all requirements)

Must contain at least;

At least 1 symbol
At least 1 uppercase
At least 1 number
At least 8 characters

Error State

Use the error prop to show an error state (e.g., when the password doesn't match confirmation).

<PasswordStrength password={password} error />

Error state

Must contain at least;

At least 1 symbol
At least 1 uppercase
At least 1 number
At least 8 characters

Progress Bar Only

Hide the requirements list and show only the progress bar with showRequirements={false}.

<PasswordStrength password={password} showRequirements={false} />

Progress bar only (no requirements list)

Custom Requirements

Pass custom requirements to validate different password rules.

const customRequirements = [
  {
    id: 'length',
    label: 'At least 12 characters',
    validator: (pwd) => pwd.length >= 12,
  },
  {
    id: 'uppercase',
    label: 'At least 2 uppercase letters',
    validator: (pwd) => (pwd.match(/[A-Z]/g) || []).length >= 2,
  },
  {
    id: 'number',
    label: 'At least 2 numbers',
    validator: (pwd) => (pwd.match(/[0-9]/g) || []).length >= 2,
  },
  {
    id: 'special',
    label: 'At least 1 special character (!@#$%)',
    validator: (pwd) => /[!@#$%]/.test(pwd),
  },
]

<PasswordStrength
  password={password}
  requirements={customRequirements}
  title="Strict password requirements:"
/>

Strict password requirements:

At least 12 characters
At least 2 uppercase letters
At least 2 numbers
At least 1 special character (!@#$%)

With Input Component

Combine with the Input component for a complete password field experience.

Must contain at least;

At least 1 symbol
At least 1 uppercase
At least 1 number
At least 8 characters
const [password, setPassword] = useState('')
const [showPassword, setShowPassword] = useState(false)

const passedCount = defaultRequirements.filter((req) => req.validator(password)).length
const isComplete = passedCount === defaultRequirements.length

<Input.Root size="md" required error={password.length > 0 && !isComplete}>
  <Input.Label>
    Password
    <Input.RequiredIndicator />
  </Input.Label>
  <Input.Field>
    <Input.LeftSlot><Lock /></Input.LeftSlot>
    <Input.NativeInput
      type={showPassword ? 'text' : 'password'}
      placeholder="Enter password..."
      value={password}
      onChange={(e) => setPassword(e.target.value)}
    />
    <Input.RightSlot>
      <button onClick={() => setShowPassword(!showPassword)}>
        {showPassword ? <EyeClosed /> : <Eye />}
      </button>
    </Input.RightSlot>
  </Input.Field>
</Input.Root>
<PasswordStrength password={password} />

All States Overview

Idle

Must contain at least;

At least 1 symbol
At least 1 uppercase
At least 1 number
At least 8 characters

Half (3/4)

Must contain at least;

At least 1 symbol
At least 1 uppercase
At least 1 number
At least 8 characters

Complete

Must contain at least;

At least 1 symbol
At least 1 uppercase
At least 1 number
At least 8 characters

Error

Must contain at least;

At least 1 symbol
At least 1 uppercase
At least 1 number
At least 8 characters

Default Requirements

The component includes these default requirements:

RequirementValidator
At least 1 symbolContains `!@#$%^&*()_+-=[];':"\
At least 1 uppercaseContains A-Z
At least 1 numberContains 0-9
At least 8 charactersLength >= 8

You can import and modify the default requirements:

import { defaultRequirements } from '@/components'

// Use as-is or modify
const myRequirements = [
  ...defaultRequirements,
  {
    id: 'noSpaces',
    label: 'No spaces allowed',
    validator: (pwd) => !pwd.includes(' '),
  },
]

Accessibility

  • Container has role="group" with aria-label="Password strength indicator"
  • Progress bar has role="progressbar" with aria-valuenow, aria-valuemin, aria-valuemax
  • Visual states are communicated through both color and icons

API Reference

PasswordStrength Props

PropTypeDefaultDescription
passwordstringrequiredThe password to validate
requirementsPasswordRequirement[]defaultRequirementsArray of requirements to validate
showRequirementsbooleantrueWhether to show the requirements list
titlestring'Must contain at least;'Title text above requirements
errorbooleanfalseForce error state display

PasswordRequirement Type

interface PasswordRequirement {
  id: string           // Unique identifier
  label: string        // Display text
  validator: (password: string) => boolean  // Validation function
}

PasswordStrengthLevel Type

type PasswordStrengthLevel = 'idle' | 'weak' | 'medium' | 'strong' | 'error'