Password input
A password field with a show and hide toggle and a Caps Lock hint, plus a strength meter and a requirements checklist for choosing a new password.
npx prodular-ui add password-inputNew password
Strength and requirements update as people type. The button waits until every rule is met.
"use client"
import * as React from "react"
import { Button } from "@/components/ui/button"import { Field, FieldLabel } from "@/components/ui/field"import { PasswordInput, PasswordRequirements, PasswordStrength, defaultPasswordRequirements } from "@/components/ui/password-input"
export default function PasswordInputNew() { const [password, setPassword] = React.useState("Halcyon2026") const ready = defaultPasswordRequirements.every((r) => r.test(password))
return ( <form className="flex w-full max-w-sm flex-col gap-4" onSubmit={(e) => e.preventDefault()}> <Field> <FieldLabel>New password</FieldLabel> <PasswordInput autoComplete="new-password" value={password} onChange={(e) => setPassword(e.target.value)} /> <PasswordStrength value={password} className="mt-1" /> </Field> <PasswordRequirements value={password} /> <Button type="submit" disabled={!ready} className="self-start"> Update password </Button> </form> )}Sign in
Just the field and its toggle. Errors go in the description, not in the field.
The eye shows what you typed. A Caps Lock hint appears while it is on.
That password does not match maya@halcyonlabs.com.
import { Field, FieldDescription, FieldLabel } from "@/components/ui/field"import { PasswordInput } from "@/components/ui/password-input"
export default function PasswordInputSignIn() { return ( <div className="flex w-full max-w-sm flex-col gap-4"> <Field> <FieldLabel>Password</FieldLabel> <PasswordInput defaultValue="relay-finance-ops" /> <FieldDescription>The eye shows what you typed. A Caps Lock hint appears while it is on.</FieldDescription> </Field> <Field invalid> <FieldLabel>Password</FieldLabel> <PasswordInput defaultValue="wrongpassword" aria-invalid /> <FieldDescription className="text-destructive-subtle-foreground">That password does not match maya@halcyonlabs.com.</FieldDescription> </Field> </div> )}Anatomy
<Field> <FieldLabel>New password</FieldLabel> <PasswordInput autoComplete="new-password" value={pw} onChange={(e) => setPw(e.target.value)} /> <PasswordStrength value={pw} /></Field><PasswordRequirements value={pw} />Guidance
Use it when
- Every password field. The toggle cuts typos, the Caps Lock hint cuts failed sign ins.
- PasswordStrength and PasswordRequirements together when people set a new password.
Avoid
- Strength or requirements on a sign in form. They only make sense when choosing a password.
- Treating scorePassword as a security check. It is a hint; enforce rules on the server.
Rules for AI agents
Published in llms-full.txt, the registry and the MCP server, so coding agents follow them when they build with this component.
- Set autoComplete="new-password" on sign up and change password forms, keep the default current-password on sign in.
- Pass requirements that match the backend's real rules, and disable submit until they are all met.
- Do not add a second confirm password field; the visibility toggle replaces it.
- Label the field with Field and FieldLabel. Put server errors in FieldDescription and set aria-invalid on the input.
API
PasswordInput
| Prop | Type | Default | Description |
|---|---|---|---|
| defaultVisible | boolean | false | Start with the password shown. |
| autoComplete | string | "current-password" | Use new-password when people choose one. |
| ...props | Input props | value, onChange, name, size and the rest pass to the input. |
PasswordStrength
| Prop | Type | Default | Description |
|---|---|---|---|
| value | string | The password to score. | |
| score | 0 | 1 | 2 | 3 | 4 | Your own estimate, for example from zxcvbn. Overrides the built-in score. |
PasswordRequirements
| Prop | Type | Default | Description |
|---|---|---|---|
| value / requirements | string / { id, label, test }[] | Rules to tick off. Defaults to length, case, number and symbol. |
Installation
The Prodular UI CLI adds the source to components/ui with everything it depends on. In a project that already uses shadcn/ui, the shadcn CLI installs it from the Prodular registry too. See Installation for the first setup.
npx prodular-ui add password-input# or, with the registry in components.jsonnpx shadcn@latest add @prodular/password-input