Skip to content
Nizivo UI

PasswordInput

A native password input in Input's box, with a toggle that shows the password. The toggle keeps one name, "Show password", and says whether the password shows through its pressed state; a submit hides the password again.

Tier: client

Import

import { PasswordInput } from '@nizivo/react/password-input';

// Once per app (Getting started), after
// @nizivo/tokens/tokens.css and @nizivo/react/css/base.css and @nizivo/react/css/input.css
import '@nizivo/react/css/password-input.css';

Static or interactive

Client. It always ships its client leaf, which reads its Field through FieldScope, so a page with a PasswordInput also loads FieldScope. The server HTML is a native password input that works before hydration; the toggle works once the page has hydrated. How to choose.

In a client app (a Vite or React Router single-page app, or a 'use client' file) it is an ordinary React component: event handlers, refs and state work as usual. In a client app.

The toggle

The toggle is a button with a constant name, "Show password" (labels.toggle), and aria-pressed: a screen reader hears "Show password, toggle button, pressed" while the password shows. Its mark is the internal eye glyph while the password is hidden and eye-off while it shows; showIcon and hideIcon replace them. onVisibleChange(visible, details) reports each change, with details.reason 'toggle' or 'submit'.

Hidden again on submit

When its form submits, the password turns back into a password field before the form's handler or action runs, so the plain text is not left on screen and a password manager sees a password field.

Autocomplete

autoComplete is current-password by default, for signing in. Pass new-password where the user chooses one, so a password manager offers to generate it. Spell check and autocapitalisation are off.

Examples

Basic

Signing in: the toggle shows the password, and a submit hides it again.

import type { JSX } from 'react';
import { Field } from '@nizivo/react/field';
import { PasswordInput } from '@nizivo/react/password-input';

export function PasswordInputExample(): JSX.Element {
  return (
    <form style={{ maxInlineSize: 320 }}>
      <Field name="password" label="Password" required>
        <PasswordInput />
      </Field>
    </form>
  );
}

New

Choosing a password: new-password, so a password manager offers to generate one.

At least 12 characters.
import type { JSX } from 'react';
import { Field } from '@nizivo/react/field';
import { PasswordInput } from '@nizivo/react/password-input';

export function PasswordInputNewExample(): JSX.Element {
  return (
    <form style={{ maxInlineSize: 320 }}>
      <Field
        name="new-password"
        label="New password"
        description="At least 12 characters."
        required
        messages={{
          valueMissing: 'Enter a new password.',
          tooShort: 'Use at least 12 characters.',
        }}
      >
        <PasswordInput autoComplete="new-password" minLength={12} />
      </Field>
    </form>
  );
}

States

An error from the server, sizes, and disabled.

That password is not right. Try again or reset it.
import type { JSX } from 'react';
import { Field } from '@nizivo/react/field';
import { PasswordInput } from '@nizivo/react/password-input';

export function PasswordInputStatesExample(): JSX.Element {
  return (
    <div style={{ display: 'grid', gap: 16, maxInlineSize: 320 }}>
      <Field label="Password" error="That password is not right. Try again or reset it.">
        <PasswordInput defaultValue="hunter2" />
      </Field>
      <PasswordInput size="sm" aria-label="Small" />
      <PasswordInput size="lg" aria-label="Large" />
      <Field label="Password" disabled>
        <PasswordInput defaultValue="hunter2" />
      </Field>
    </div>
  );
}

Props

Client component Renders data-slot="password-input" with the class nz-password-input. Props: PasswordInputProps. Source: src/password-input/password-input.client.tsx.

NameTypeDefaultDescription
autoCompleteComponentPropsWithRef<"input">["autoComplete"]'current-password'

'current-password' to sign in, 'new-password' to choose one (a password manager then offers to generate one).

defaultVisiblebooleanfalse

The password shows as text when the input first renders.

hideIconReactNode–

The toggle's mark while the password shows. Defaults to the internal eye-off glyph.

invalidboolean–

An error message is presented for this input. Inside a Field, the Field sets it.

labelsPartial<PasswordInputLabels>–

Overrides the toggle's name, for example labels={{ toggle: 'Passwort anzeigen' }}.

onVisibleChange(visible: boolean, details: ChangeDetails<PasswordInputVisibleReason>) => void–

Called when the password is shown or hidden: by the toggle, or hidden by a submit.

renderRenderProp<PasswordInputState>–

Composition of the root, the bordered box. className and style go on the root too; every other prop, ref included, goes on the <input>.

showIconReactNode–

The toggle's mark while the password is hidden. Defaults to the internal eye glyph.

sizeControlSize
"sm""md""lg"
'md'

32 / 40 / 48 px, as Input.

  • Also takes every attribute of <input> except children, prefix, size, type; autoComplete is redeclared above. (Omit<ComponentPropsWithRef<"input">, "type" | "size" | "prefix" | "children">)

render takes an element, or, in client code, a function of the props and this state (PasswordInputState):

NameTypeDefaultDescription
disabledrequiredboolean–
invalidrequiredboolean–

An error message is presented (the Field's, or the invalid prop).

readOnlyrequiredboolean–
sizerequiredControlSize
"sm""md""lg"
–
visiblerequiredboolean–

The password shows as text.

Other exports

PasswordInputLabels type

import type { PasswordInputLabels } from '@nizivo/react/password-input'

PasswordInput's own strings (§16.4): serialisable, English defaults.

NameTypeDefaultDescription
togglerequiredstring'Show password'

The toggle's name, the same in both states: aria-pressed says whether the password shows.

PasswordInputProps type

import type { PasswordInputProps } from '@nizivo/react/password-input'

The props of PasswordInput, listed above.

PasswordInputState type

import type { PasswordInputState } from '@nizivo/react/password-input'

The render state of PasswordInput, listed above.

PasswordInputVisibleReason type

import type { PasswordInputVisibleReason } from '@nizivo/react/password-input'

'toggle': the toggle was pressed. 'submit': the form submitted, which hides the password.

type PasswordInputVisibleReason = "toggle" | "submit"

Data attributes and slots

Style parts by class (.nz-<slot>) and state by data attribute. Attribute meanings come from contracts/vocabulary.json.

SlotRendered byData attributes
password-input
.nz-password-input
PasswordInput
root (takes render); interactive, focus: within
  • data-disabled (present or absent) ← disabled
    Mirrors the disabled attribute
  • data-invalid (present or absent) ← invalid
    An error message is currently presented (not "fails constraints"); always the Field's own state, never the engine's
  • data-readonly (present or absent)
    Mirrors the readonly attribute
  • data-size: "sm""md""lg" ← size
    The size prop; values in each component manifest
password-input-control
.nz-password-input-control
PasswordInput
inner element (CSS only)
none
password-input-icon
.nz-password-input-icon
PasswordInput
inner element (CSS only)
none
password-input-toggle
.nz-password-input-toggle
PasswordInput
inner element (CSS only); interactive, focus: self
none

CSS hooks

Set a hook on the component's class or any ancestor to restyle it without specificity games; leave it unset for the default shown.

HookDefaultRead as
--nz-password-input-toggle-fg--nz-icon-secondary
  • color on .nz-password-input-toggle

Layers: nz.components. Classes: .nz-password-input, .nz-password-input-icon, .nz-password-input-toggle.

Tokens this stylesheet reads (11)

--nz-bg-hover, --nz-bg-pressed, --nz-duration-fast, --nz-easing-standard, --nz-icon-primary, --nz-icon-secondary, --nz-radius-sm, --nz-size-icon-sm, --nz-space-1, --nz-space-6, --nz-text-disabled

Accessibility

These parts are interactive. Each gets the focus outline and touch-action rule from @nizivo/react/css/base.css (the nz.base layer), so the floor survives a restyle:

  • password-input: draws the outline when the field inside it has focus.
  • password-input-toggle: draws the focus outline itself on keyboard focus.

Keyboard

KeysAction
TabMoves focus to the input, then to the toggle. The box draws the focus outline while the input has focus, the toggle its own while it does.
Space, EnterOn the toggle, shows or hides the password.
EnterIn the input, submits its form. The password is hidden again on submit.

Source: a native <input> and <button type="button" aria-pressed> (password-input.client.tsx). The browser lane (test/browser/password-input.spec.tsx) checks the toggle by pointer and keyboard, the focus outlines, the revert on submit and inline validation in a Field.

Figma

Node ids from design/component-map.json, which nz gen writes from component.json. The links open the Nizivo Figma library, which may ask you to sign in.

  • Canonical: none
  • Ghost masters: none

On this page