Password
Password is an enhanced input for password entry with strength metering, mask toggling, and controlled or uncontrolled usage.
Usage#
import { Password } from '@primereact/ui/password';<Password />Examples#
Toggle Mask#
Adding a toggle icon to show or hide the password, allowing users to verify their input.
'use client';
import { Eye } from '@primeicons/react/eye';
import { EyeSlash } from '@primeicons/react/eye-slash';
import { PasswordMaskChangeEvent } from '@primereact/types/shared/password';
import { IconField } from '@primereact/ui/iconfield';
import { Password } from '@primereact/ui/password';
import * as React from 'react';
export default function ToggleMaskDemo() {
const [mask, setMask] = React.useState(true);
return (
<div className="flex justify-center">
<IconField.Root>
<Password mask={mask} onMaskChange={(e: PasswordMaskChangeEvent) => setMask(e.value)} />
<IconField.Icon>{mask ? <Eye onClick={() => setMask(false)} /> : <EyeSlash onClick={() => setMask(true)} />}</IconField.Icon>
</IconField.Root>
</div>
);
}
Requirements#
Display a checklist of password requirements that update in real-time as the user types, providing clear feedback on which criteria have been met.
- At least 12 characters
- Contains uppercase letter
- Contains lowercase letter
- Contains number
- Contains special character
'use client';
import { PasswordValueChangeEvent } from '@primereact/types/shared/password';
import { Password } from '@primereact/ui/password';
import * as React from 'react';
const requirements = [
{
id: 'minLength',
label: 'At least 12 characters',
test: (value: string) => value.length >= 12
},
{
id: 'uppercase',
label: 'Contains uppercase letter',
test: (value: string) => /[A-Z]/.test(value)
},
{
id: 'lowercase',
label: 'Contains lowercase letter',
test: (value: string) => /[a-z]/.test(value)
},
{
id: 'number',
label: 'Contains number',
test: (value: string) => /[0-9]/.test(value)
},
{
id: 'symbol',
label: 'Contains special character',
test: (value: string) => /[^a-zA-Z0-9]/.test(value)
}
];
export default function RequirementsDemo() {
const [value, setValue] = React.useState('');
return (
<div className="flex justify-center">
<div className="flex flex-col gap-2 w-64">
<Password value={value} onValueChange={(e: PasswordValueChangeEvent) => setValue(e.value)} placeholder="Enter password" />
<ul className="flex flex-col gap-2 list-none ms-1 my-1">
{requirements.map((req) => {
const met = req.test(value);
return (
<li key={req.id} className="flex items-center gap-2 text-sm">
<i className={met ? 'pi pi-check-circle text-green-500' : 'pi pi-circle text-surface-400'} />
<span className={met ? 'text-green-700 dark:text-green-400 line-through' : 'text-surface-700 dark:text-surface-300'}>
{req.label}
</span>
</li>
);
})}
</ul>
</div>
</div>
);
}
Strength Meter#
Visualize the overall password strength with an animated progress bar and a severity-based label that adapts as the password improves.
'use client';
import { PasswordValueChangeEvent } from '@primereact/types/shared/password';
import { Password } from '@primereact/ui/password';
import { ProgressBar } from '@primereact/ui/progressbar';
import { Tag } from '@primereact/ui/tag';
import * as React from 'react';
type StrengthLevel = 'weak' | 'medium' | 'strong' | 'very-strong';
interface StrengthInfo {
label: string;
percent: number;
color: string;
severity: 'danger' | 'warn' | 'info' | 'success';
}
const strengthMap: Record<StrengthLevel, StrengthInfo> = {
weak: { label: 'Weak', percent: 25, color: 'var(--p-red-400)', severity: 'danger' },
medium: { label: 'Medium', percent: 50, color: 'var(--p-amber-400)', severity: 'warn' },
strong: { label: 'Strong', percent: 75, color: 'var(--p-blue-400)', severity: 'info' },
'very-strong': { label: 'Very Strong', percent: 100, color: 'var(--p-emerald-400)', severity: 'success' }
};
function getStrength(value: string): StrengthLevel | null {
if (!value) return null;
let score = 0;
if (value.length >= 8) score++;
if (value.length >= 12) score++;
if (/[A-Z]/.test(value) && /[a-z]/.test(value)) score++;
if (/[0-9]/.test(value)) score++;
if (/[^a-zA-Z0-9]/.test(value)) score++;
if (score <= 1) return 'weak';
else if (score <= 2) return 'medium';
else if (score <= 3) return 'strong';
else return 'very-strong';
}
export default function StrengthDemo() {
const [value, setValue] = React.useState('');
const level = getStrength(value);
const info = level ? strengthMap[level] : null;
return (
<div className="flex justify-center">
<div className="flex flex-col gap-2 w-64">
<Password value={value} onValueChange={(e: PasswordValueChangeEvent) => setValue(e.value)} placeholder="Enter password" />
{info && (
<div className="flex flex-col gap-2">
<ProgressBar.Root value={info.percent}>
<ProgressBar.Track style={{ height: '6px' }}>
<ProgressBar.Indicator style={{ backgroundColor: info.color }} />
</ProgressBar.Track>
</ProgressBar.Root>
<div className="flex justify-end">
<Tag severity={info.severity}>{info.label}</Tag>
</div>
</div>
)}
</div>
</div>
);
}
Popover#
Combine a visibility toggle, strength meter, and requirements checklist into a fully custom password creation with Popover component.
'use client';
import { Eye } from '@primeicons/react/eye';
import { EyeSlash } from '@primeicons/react/eye-slash';
import { PasswordMaskChangeEvent, PasswordValueChangeEvent } from '@primereact/types/shared/password';
import { IconField } from '@primereact/ui/iconfield';
import { Password } from '@primereact/ui/password';
import { Popover } from '@primereact/ui/popover';
import { ProgressBar } from '@primereact/ui/progressbar';
import { Tag } from '@primereact/ui/tag';
import * as React from 'react';
const rules = [
{ id: 'length', label: 'At least 12 characters long', test: (v: string) => v.length >= 12, weight: 20 },
{ id: 'uppercase', label: 'Contains uppercase letter', test: (v: string) => /[A-Z]/.test(v), weight: 20 },
{ id: 'lowercase', label: 'Contains lowercase letter', test: (v: string) => /[a-z]/.test(v), weight: 20 },
{ id: 'number', label: 'Contains number', test: (v: string) => /[0-9]/.test(v), weight: 20 },
{ id: 'special', label: 'Contains special character (!@#$...)', test: (v: string) => /[^a-zA-Z0-9]/.test(v), weight: 20 }
];
function getScore(value: string) {
if (!value) return 0;
return rules.reduce((acc, rule) => acc + (rule.test(value) ? rule.weight : 0), 0);
}
function getSeverity(score: number) {
if (score <= 20) return 'danger';
if (score <= 40) return 'warn';
if (score <= 60) return 'info';
return 'success';
}
function getLabel(score: number): string {
if (score === 0) return '';
if (score <= 20) return 'Too Weak';
if (score <= 40) return 'Weak';
if (score <= 60) return 'Fair';
if (score <= 80) return 'Strong';
return 'Very Strong';
}
export default function PopoverDemo() {
const [value, setValue] = React.useState('');
const [mask, setMask] = React.useState(true);
const [open, setOpen] = React.useState(false);
const score = getScore(value);
const severity = getSeverity(score);
const label = getLabel(score);
return (
<div className="flex justify-center">
<Popover.Root open={open}>
<Popover.Trigger as="div" className="w-72">
<IconField.Root>
<Password
mask={mask}
onMaskChange={(e: PasswordMaskChangeEvent) => setMask(e.value)}
value={value}
placeholder="Create a password"
fluid
onValueChange={(e: PasswordValueChangeEvent) => setValue(e.value)}
onFocus={() => setOpen(true)}
onBlur={() => setOpen(false)}
/>
<IconField.Icon>
{mask ? (
<Eye className="cursor-pointer" onClick={() => setMask(false)} />
) : (
<EyeSlash className="cursor-pointer" onClick={() => setMask(true)} />
)}
</IconField.Icon>
</IconField.Root>
</Popover.Trigger>
<Popover.Portal>
<Popover.Positioner sideOffset={12} side="bottom" align="start">
<Popover.Content className="w-72">
<div className="flex flex-col gap-3">
<div className="flex items-center justify-between">
<div className="flex items-center gap-2">
<i className="pi pi-shield" style={{ fontSize: '1.25rem' }} />
<span className="font-semibold text-sm">Password Strength</span>
</div>
{label && <Tag severity={severity}>{label}</Tag>}
</div>
<ProgressBar.Root value={score}>
<ProgressBar.Track style={{ height: '6px' }}>
<ProgressBar.Indicator
className={
score <= 20
? 'bg-red-400'
: score <= 40
? 'bg-amber-400'
: score <= 60
? 'bg-blue-400'
: 'bg-green-400'
}
/>
</ProgressBar.Track>
</ProgressBar.Root>
<ul className="flex flex-col gap-2 list-none m-0 p-0">
{rules.map((rule) => {
const met = rule.test(value);
return (
<li key={rule.id} className="flex items-center gap-2 text-xs">
<i className={met ? 'pi pi-check text-green-500' : 'pi pi-times text-red-400'} />
<span
className={
met ? 'text-surface-500 dark:text-surface-400' : 'text-surface-700 dark:text-surface-200'
}
>
{rule.label}
</span>
</li>
);
})}
</ul>
</div>
<Popover.Arrow />
</Popover.Content>
</Popover.Positioner>
</Popover.Portal>
</Popover.Root>
</div>
);
}
Float Label#
FloatLabel visually integrates a label with its form element. Visit FloatLabel documentation for more information.
'use client';
import { PasswordValueChangeEvent, usePasswordProps } from '@primereact/types/shared/password';
import { FloatLabel } from '@primereact/ui/floatlabel';
import { Label } from '@primereact/ui/label';
import { Password } from '@primereact/ui/password';
import * as React from 'react';
export default function FloatLabelDemo() {
const [value, setValue] = React.useState<usePasswordProps['value']>('');
const [value2, setValue2] = React.useState<usePasswordProps['value']>('');
const [value3, setValue3] = React.useState<usePasswordProps['value']>('');
return (
<div className="flex flex-wrap justify-center items-end gap-4">
<FloatLabel>
<Password value={value} onValueChange={(e: PasswordValueChangeEvent) => setValue(e.value as string)} />
<Label htmlFor="over_label">Over Label</Label>
</FloatLabel>
<FloatLabel variant="in">
<Password value={value2} onValueChange={(e: PasswordValueChangeEvent) => setValue2(e.value as string)} />
<Label htmlFor="in_label">In Label</Label>
</FloatLabel>
<FloatLabel variant="on">
<Password value={value3} onValueChange={(e: PasswordValueChangeEvent) => setValue3(e.value as string)} />
<Label htmlFor="on_label">On Label</Label>
</FloatLabel>
</div>
);
}
Ifta Label#
IftaLabel is used to create infield top aligned labels. Visit IftaLabel documentation for more information.
import { IftaLabel } from '@primereact/ui/iftalabel';
import { Label } from '@primereact/ui/label';
import { Password } from '@primereact/ui/password';
export default function IftaLabelDemo() {
return (
<div className="flex justify-center">
<IftaLabel>
<Password id="new-password" variant="filled" />
<Label htmlFor="new-password" className="mb-2">
Password
</Label>
</IftaLabel>
</div>
);
}
Clear Icon#
When Password.ClearIcon component is used, a clear icon is added to reset the Password input.
'use client';
import { Times } from '@primeicons/react/times';
import { PasswordValueChangeEvent, usePasswordProps } from '@primereact/types/shared/password';
import { IconField } from '@primereact/ui/iconfield';
import { Password } from '@primereact/ui/password';
import * as React from 'react';
export default function BasicDemo() {
const [value, setValue] = React.useState<usePasswordProps['value']>('');
return (
<div className="flex justify-center">
<IconField.Root>
<Password className="w-56" value={value} onValueChange={(e: PasswordValueChangeEvent) => setValue(e.value)} />
<IconField.Icon>{value !== '' && <Times onClick={() => setValue('')} />}</IconField.Icon>
</IconField.Root>
</div>
);
}
Sizes#
Password provides small and large sizes as alternatives to the base.
import { Password } from '@primereact/ui/password';
export default function SizesDemo() {
return (
<div className="flex flex-col items-center gap-4">
<Password size="small" placeholder="Small" />
<Password placeholder="Normal" />
<Password size="large" placeholder="Large" />
</div>
);
}
Fluid#
The fluid prop makes the component take up the full width of its container when set to true.
import { Password } from '@primereact/ui/password';
export default function FluidDemo() {
return (
<div>
<Password fluid />
</div>
);
}
Filled#
Specify the filled property to display the component with a higher visual emphasis than the default outlined style.
import { Password } from '@primereact/ui/password';
export default function FilledDemo() {
return (
<div className="flex justify-center">
<Password variant="filled" />
</div>
);
}
Disabled#
Use the disabled property to disable a password input.
import { Password } from '@primereact/ui/password';
export default function DisabledDemo() {
return (
<div className="flex justify-center">
<Password disabled placeholder="Disabled" />
</div>
);
}
Invalid#
Specify the invalid property to display the component with a red border.
'use client';
import { PasswordValueChangeEvent, usePasswordProps } from '@primereact/types/shared/password';
import { Password } from '@primereact/ui/password';
import * as React from 'react';
export default function InvalidDemo() {
const [value1, setValue1] = React.useState<usePasswordProps['value']>('');
const [value2, setValue2] = React.useState<usePasswordProps['value']>('');
return (
<div className="flex flex-wrap justify-center gap-4">
<Password
value={value1}
invalid={!value1}
onValueChange={(e: PasswordValueChangeEvent) => setValue1(e.value as string)}
placeholder="Password"
/>
<Password
value={value2}
invalid={!value2}
variant="filled"
onValueChange={(e: PasswordValueChangeEvent) => setValue2(e.value as string)}
placeholder="Password"
/>
</div>
);
}
Accessibility#
Screen Reader#
Value to describe the component can either be provided via label tag combined with id prop or using aria-labelledby, aria-label props. Screen reader is notified about the changes to the strength of the password using a section that has aria-live while typing.
Keyboard Support#
| Key | Function |
|---|---|
tab | Moves focus to the input. |