# react.form.password-field
A password input with a Show/Hide button, following the GOV.UK Design
System's password input, and, when you give it a password policy, a checklist
of that policy's rules under the input, ticked as the person types. The rules
and the check come from `auth.password-policy`, which runs in all three
languages, so the checklist in the browser and the server that decides can
never disagree.
```tsx
"use client";
import { PasswordField } from "#fune/react.form.password-field@^1";
import { passwordPolicy } from "#fune/auth.password-policy@^1";
const policy = passwordPolicy("nist-800-63b-4-single-factor");
// Signing in
<PasswordField id="password" label="Password" error={errors.password} />
// Choosing one
<PasswordField id="new-password" name="password" label="Create a password"
policy={policy} email={account.email} personName={account.name}
value={password} onChange={setPassword} />
// and on the server: checkPassword(password, email, name, policy).valid
```
## What it renders
- The input is `type="password"` with `spellCheck={false}` and
`autoCapitalize="none"`, so a phone neither corrects nor capitalises it,
and `autoComplete` `current-password` (signing in) or `new-password`
(choosing one, the default when a `policy` is given), which is what lets a
password manager fill or generate it.
- The **Show** button is `type="button"` (it never submits the form), has
`aria-controls` naming the input and an `aria-label` of "Show password" or
"Hide password", and reads "Show" or "Hide". It is rendered `hidden` until
the component has mounted, as GOV.UK hides it until its script runs, so a
page without JavaScript never shows a button that does nothing. It is
disabled with the field.
- A visually hidden `aria-live="polite"` status beside the input says "Your
password is visible" or "Your password is hidden" after each press. It
starts empty, so nothing is announced on page load.
- The password is hidden again when its form is submitted, and when the page
comes back from the back-forward cache, so it is never left on screen.
- With a **policy**, a list follows the input, one item per rule the policy
has: "At least 15 characters", "No more than 128 characters", "At least 3
of: lower-case letters, capital letters, digits, symbols" (only when the
policy counts classes), "Not a commonly used password" (only with the
blocklist), "Does not include your email address" and "Does not include
your name" (only when personal words are refused). Each starts with a
visually hidden "Done:" or "Not yet:", so the state is heard as well as
seen. The list is in the input's `aria-describedby` (after the hint and the
error) but is not a live region: announcing it on every key would drown the
person typing. **email** and **personName** feed the last two rules; the
input's submitted name is `name`, so the person's name has its own prop.
An empty password shows only the minimum length as not yet met: the other
rules are not broken by nothing.
`passwordChecklist(policy, check)` is the list as data, for a page that draws
its own, and is what the component renders. It only turns `checkPassword`'s
failure codes into rules; a failure the policy has no rule for is not listed.
`onChange` is called with the password, not the event, and `onBlur` with
nothing when the input loses focus, to mark the field touched.
Ids: the input is `id` (React's `useId()` when left out), the hint
`<id>-hint`, the error `<id>-error`, the checklist `<id>-checklist`. It is a
client component (state for the toggle and the checklist), so its file starts
with `"use client"`. Errors are those of `react.form.form-field` (an id with a
space) and `checkPassword` (a nonsense policy).
Classes: those of `react.form.form-field`, plus `fune-password-field` on the
wrapper, `fune-input` (and `fune-input--error`), `fune-input-wrapper`,
`fune-password-field__wrapper`, `fune-password-field__input`,
`fune-password-field__status`, `fune-password-field__toggle`,
`fune-password-checklist`, `fune-password-checklist__item` (and
`fune-password-checklist__item--met`, `fune-password-checklist__item--unmet`).
Sources: GOV.UK Design System, "Password input"
https://design-system.service.gov.uk/components/password-input/ and its
script, for the button and status wording
https://github.com/alphagov/govuk-frontend/tree/main/packages/govuk-frontend/src/govuk/components/password-input;
HTML autofill tokens `current-password` and `new-password`
https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#autofill;
NIST SP 800-63B-4 section 3.1.1.2 (via `auth.password-policy`)
https://pages.nist.gov/800-63-4/sp800-63b.html.
## Notices
Portions derived from GOV.UK Frontend (https://github.com/alphagov/govuk-frontend), Copyright (c) 2017 Crown Copyright (Government Digital Service), under the MIT License; the full notice is in NOTICE.
1.0.1 adds its attribution notices (NOTICE). The code and the tests are unchanged.