Password input

A password field with a show/hide toggle and, for new passwords, a strength word, Meter, and hint. For other text, use an Input.

Installation

bun add @harmo-ui/css @harmo-ui/react

Usage

import { PasswordInput } from "@harmo-ui/react";

<PasswordInput
  label="New password"
  showPasswordLabel="Show password"
  hidePasswordLabel="Hide password"
  autoComplete="new-password"
  strength={(password) =>
    password.length < 8
      ? { level: 1, word: "Too weak", status: "error" }
      : { level: 3, word: "Strong", status: "success" }
  }
  strengthLabel="Password strength"
/>

Examples

This site is using your theme

Current password

An Input with a show/hide toggle at its end, which appears once something is typed. The toggle's name stays "Show password", with aria-pressed saying whether the password shows; its Tooltip names the next click.

<PasswordInput
  label="Password"
  showPasswordLabel="Show password"
  hidePasswordLabel="Hide password"
  autoComplete="current-password"
/>

New password

Adds a strength word, a Meter, and a hint, which appear as you type. The app supplies the rule and the wording; here, under 10 characters is too weak, and upper case, lower case, digits, and symbols together are strong.

const strength = (password: string): PasswordStrength => {
  if (password.length < 10) {
    return {
      level: 1,
      word: "Too weak",
      hint: "Passwords need to be at least 10 characters. Include multiple words and phrases to make it more secure.",
      status: "error",
    };
  }
  const kinds = [/[A-Z]/, /[a-z]/, /\d/, /[!@#$%^&*(),.?":{}|<>]/];
  return kinds.every((kind) => kind.test(password))
    ? { level: 3, word: "Strong", status: "success" }
    : {
        level: 2,
        word: "Medium",
        hint: "Include multiple words and phrases to make it more secure.",
      };
};

return (
  <PasswordInput
    label="New password"
    showPasswordLabel="Show password"
    hidePasswordLabel="Hide password"
    autoComplete="new-password"
    strength={strength}
    strengthLabel="Password strength"
  />
);

Disabled

A disabled field keeps its toggle if it has a value, disabled with it.

<PasswordInput
  label="API secret, managed by your administrator"
  showPasswordLabel="Show password"
  hidePasswordLabel="Hide password"
  defaultValue="example-api-secret"
  disabled
/>

Disabling

Disabling the input disables its toggle too. Type a password, then clear the checkbox, which turns the field off, as an app's settings might.

const [protecting, setProtecting] = useState(true);
return (
  <>
    <Field orientation="horizontal" label="Protect the export with a password">
      <Checkbox
        name="export-protect"
        checked={protecting}
        onChange={(event) => setProtecting(event.target.checked)}
      />
    </Field>
    <PasswordInput
      label="Export password"
      showPasswordLabel="Show password"
      hidePasswordLabel="Hide password"
      autoComplete="new-password"
      disabled={!protecting}
    />
  </>
);

API reference

React

<PasswordInput> renders the whole field: the Field, the input, the toggle with its tooltip, and, with strength, the meter, word, and hint. Other props are the <input>'s attributes, such as autoComplete.

PropEffect
label, optional, description, errorAs for a Field
showPasswordLabel, hidePasswordLabelRequired: the toggle's name, such as "Show password", and its tooltip while the password shows, such as "Hide password"
strengthRates the password as it's typed: a function from the password to { level, word, hint, status }. level fills 1 to 3 segments, word shows next to the label, and hint and status are optional; an error status also marks the input invalid
strengthLabelRequired with strength: the meter's name, such as "Password strength"

HTML

A <div class="hpassword"> holding an <input class="hinput" type="password"> and the toggle. Load password.css, input.css, field.css, and tooltip.css; meter.css for the strength.

HookEffect
aria-pressed="true" on the toggleThe crossed eye shows (the password is visible)
hidden on .hpassword-toggleHides the toggle
hidden on .hpassword-detailsCollapses the meter and hint
disabled on the input and the toggleDisabled, as for Input; the toggle is a separate button, so disable both together
(no data-status) on the word and hint--harmo-color-text-tertiary
data-status="success" on the word and hint--harmo-color-success
data-status="warning" on the word and hint--harmo-color-warning
data-status="error" on the word and hint--harmo-color-danger

It needs a script for the toggle, revealing and resetting the details, and the strength. The strength rule and wording belong to the app. See Password input's full contract.

Accessibility

  • The toggle's name stays "Show password" and aria-pressed reports whether the password shows, so its name doesn't change under the user. The tooltip is only the visual label: it carries aria-hidden="true" and no id, an exception to Tooltip's usual contract, so screen readers don't hear the name twice.
  • The input's aria-describedby points at the word and hint, read on focus.
  • The word is a polite live region, so "Too weak", "Medium", and "Strong" are announced as they change, once per level rather than per keystroke.