# PasswordField

> Slug: `password-field` · Category: Form Controls

## When to use

- Entering passwords or any secret a user should be able to reveal/hide.
- Sign-in, sign-up, change-password, and account verification flows.

## When NOT to use

- Plain text — use `TextField`.
- One-time codes / OTP — use `TextField` with `inputMode="numeric"` and appropriate `autoComplete`.

## Variants & decision tree

`PasswordField` wraps `TextField` and fixes `type="password"` plus the trailing visibility-toggle decoration. Toggle visibility by maintaining a `showPassword` boolean and binding `onClick` to flip it; the component swaps to `type="text"` when `showPassword` is true.

## States

Empty, focused, filled (label floats), visible (eye toggled), error, disabled, required.

## Props

Inherits from `TextFieldProps` minus `type`, `fieldType`, `trailingDecoration`, `trailingButtonLabel` (set internally).

| Prop | Type | Default | Description |
|---|---|---|---|
| `id` | `string` | — | Required. |
| `label` | `string` | — | Required. Floating label. |
| `name` | `string` | — | Required for form submission. |
| `value` / `defaultValue` | `string` | — | Controlled / uncontrolled. |
| `onChange` | `ChangeEventHandler` | — | Change handler. |
| `showPassword` | `boolean` | `false` | When true, input becomes `type="text"` and the toggle announces visible. |
| `onClick` | `MouseEventHandler` | — | Wire to flip `showPassword`. |
| `errorMessage` | `string` | — | Inline validation message. |
| `supportingText` | `string` | — | Helper text (e.g., complexity rules). |
| `disabled` | `boolean` | `false` | Disable. |
| `required` | `boolean` | `false` | Required marker. |
| `inverse` | `boolean` | `false` | Dark mode. |

## Usage examples

```tsx
// Default
<PasswordField id="pw" name="password" label="Password" />

// Controlled with visibility toggle
const [pw, setPw] = useState('');
const [show, setShow] = useState(false);
<PasswordField
  id="pw"
  name="password"
  label="Password"
  value={pw}
  onChange={(e) => setPw(e.target.value)}
  showPassword={show}
  onClick={() => setShow((v) => !v)}
  supportingText="At least 8 characters"
/>

// Error
<PasswordField id="pw" name="password" label="Password" errorMessage="Password must be at least 8 characters" />
```

## Composition

Pair with `TextField` for username/email. In sign-up flows, place complexity rules in `supportingText` and surface validation via `errorMessage`. Use `Button type="submit"` to submit.

## Accessibility

`id`, `label`, and `name` are required. The visibility toggle ships with a screen-reader-only span announcing "Password is now visible/hidden" when `showPassword` is defined. Use `autoComplete="current-password"` for sign-in and `"new-password"` for sign-up.

## Do / Don't

- DO maintain `showPassword` state in your component and flip on `onClick`.
- DO set the appropriate `autoComplete` value.
- DON'T disable browser password managers.
- DON'T mask validation errors behind generic "Invalid" copy — be specific.
