Components · PasswordInput
PasswordInput
A password field with a reveal toggle and nothing clever. No policy, no strength theatre, and paste is never blocked — a field that refuses paste breaks password managers and passphrases alike.
import { Field, PasswordInput } from "@luc/ui";Examples
Reveal
The toggle is a real button with an accessible name, and it keeps `type=password` semantics for password managers until you ask it not to.
State the rule in the description, not in a red banner.
Autocomplete is `new-password` so the manager offers to generate one.
<Field label="Password" description="State the rule in the description, not in a red banner.">
<PasswordInput autoComplete="current-password" placeholder="••••••••••••" />
</Field>
<Field label="New API secret" description="Autocomplete is new-password, so a manager offers to generate one.">
<PasswordInput autoComplete="new-password" />
</Field>States
The invalid state comes from the field rather than the control, and a disabled field keeps its text readable instead of dimming the whole row.
Default
That password is too short
Invalid
from the field, not the control
Disabled
<PasswordInput aria-label="Password" placeholder="••••••••" />
<Field label="Password" error="That password is too short">
<PasswordInput defaultValue="hunter2" />
</Field>
<PasswordInput disabled aria-label="Disabled password" defaultValue="••••••••" />Usage
import { PasswordInput } from "@luc/ui";<PasswordInput autoComplete="new-password" aria-label="New API secret" />API
Read from the published TypeScript API, so a prop that is not listed here does not exist and a default that is listed is the one the compiler sees.
| Export | Kind | Signature |
|---|---|---|
PasswordInput | 6 documented props | ({ toggleLabels, defaultVisible, className, autoComplete, ...props }: PasswordInputProps) => import("@types/react").JSX.Element |
PasswordInput props
Type: PasswordInputProps
Values the compiler reads from the declaration.
| Prop | Type | Default | Notes |
|---|---|---|---|
defaultVisible? | boolean | undefined | — | Start in the revealed state (rarely what you want). |
inputClassName? | string | undefined | — | Applied to the `<input>` element itself; `className` styles the shell. |
invalid? | boolean | undefined | — | |
leadingIcon? | ReactNode | — | |
size? | ControlSize | undefined | — | |
toggleLabels? | { show: string; hide: string; } | undefined | — | Accessible name for the visibility toggle. Override when the surrounding language is not English; the default is `Show password` / `Hide password`. |
Guidelines
Do
- Reach for it instead of `type="password"` on a plain input: the reveal control and its accessible name come with it.
- Set `autoComplete` to `current-password` or `new-password` so a password manager offers the right thing at the right time.
- State the rule in the `Field` description, where it can be read before typing rather than after a failed submit.
Don't
- Enforce a policy in the component: length rules, breach checks and lockouts belong to the product's security review.
- Block paste or drop: a field that refuses paste breaks password managers and long passphrases alike.
- Let the strength readout be the only feedback, since it says something is wrong without saying what to change.
What LUC does not do
Strength meters, breach checks, complexity rules and lockouts belong to the product and its security review. If a product wants a strength readout, it can render one next to the field — the field itself stays a field. The only thing LUC insists on is that the value is never silently reformatted, truncated or refused.
Accessibility
The reveal control is a real button whose name switches between show and hide and whose pressed state is reported, and the field keeps `type="password"` until the reader asks otherwise — so a password manager sees an ordinary password field. Spell-check is off, and nothing in the component touches paste or copy.
Related