PixelPasswordInput

Password text field with an inline show/hide toggle that swaps the input type between password and text.

  • Inline visibility toggle with localizable labels via toggleLabels
  • Label, hint, and error slots wired through the shared FieldShell
  • Tone, size, and surface variants matched to PixelInput
  • Fits form libraries: a ref on the native <input> (React), v-model (Vue), ngModel or reactive forms (Angular)
  • Toggle button reflects state via aria-pressed for assistive tech
Status
stable
Category
forms
Since
v1.0.0

API

import { PixelPasswordInput } from '@pxlkit/ui-kit';
PropTypeDefaultDescription
labelstring—Floating label rendered above the input shell.
hintstring—Helper text shown below the field. Hidden when error is set.
errorstring—Error message shown below the field; flips visual state to invalid.
tone'green' | 'cyan' | 'gold' | 'red' | 'purple' | 'pink' | 'neutral''neutral'Visual tone for focus ring + border emphasis. Default: 'neutral'.
size'sm' | 'md' | 'lg''md'Field height token. Default: 'md'.
surface'pixel' | 'linear'—Surface variant. Inherits from PxlKitSurfaceProvider when omitted.
toggleLabels[string, string]['Show', 'Hide']Text for the visibility toggle, in [showLabel, hideLabel] form.

Also takes the native attributes and event handlers of <input> (InputHTMLAttributes<HTMLInputElement>), except type.

ref points to <input>.

Accessibility

WCAG target: 2.1 AA

  • textbox
  • button

The visibility toggle is a real <button type="button"> with an aria-label that mirrors the current state, and exposes aria-pressed so screen readers announce whether the password is currently visible. The input sets aria-invalid when an error is present, and its aria-describedby points at the hint/error message while one shows, after any ids you pass.

Keyboard

KeyActionWhen
TabMoves focus into the password field; the visibility toggle is intentionally skipped (tabIndex=-1) so keyboard flow stays on the text field.—
EnterSubmits the enclosing form, matching native password input behavior.—

Usage

import { PixelPasswordInput } from '@pxlkit/ui-kit';

export function Default() {
  return <PixelPasswordInput label="Password" placeholder="Enter password" />;
}

Examples

Default

import { PixelPasswordInput } from '@pxlkit/ui-kit';

export function Default() {
  return <PixelPasswordInput label="Password" placeholder="Enter password" />;
}

With hint

import { PixelPasswordInput } from '@pxlkit/ui-kit';

export function WithHint() {
  return (
    <PixelPasswordInput
      label="Password"
      hint="At least 8 characters, mixing letters and numbers."
      placeholder="Enter password"
    />
  );
}

With error

import { PixelPasswordInput } from '@pxlkit/ui-kit';

export function WithError() {
  return (
    <PixelPasswordInput
      label="Password"
      error="Password is too short."
      defaultValue="abc"
    />
  );
}

Tones

import { PixelPasswordInput } from '@pxlkit/ui-kit';

export function Tones() {
  return (
    <div className="space-y-3">
      <PixelPasswordInput label="Neutral" tone="neutral" placeholder="Password" />
      <PixelPasswordInput label="Green" tone="green" placeholder="Password" />
      <PixelPasswordInput label="Cyan" tone="cyan" placeholder="Password" />
      <PixelPasswordInput label="Gold" tone="gold" placeholder="Password" />
      <PixelPasswordInput label="Red" tone="red" placeholder="Password" />
      <PixelPasswordInput label="Purple" tone="purple" placeholder="Password" />
      <PixelPasswordInput label="Pink" tone="pink" placeholder="Password" />
    </div>
  );
}

Sizes

import { PixelPasswordInput } from '@pxlkit/ui-kit';

export function Sizes() {
  return (
    <div className="space-y-3">
      <PixelPasswordInput label="Small" size="sm" placeholder="Password" />
      <PixelPasswordInput label="Medium" size="md" placeholder="Password" />
      <PixelPasswordInput label="Large" size="lg" placeholder="Password" />
    </div>
  );
}

Surfaces

import { PixelPasswordInput } from '@pxlkit/ui-kit';

export function Surfaces() {
  return (
    <div className="space-y-3">
      <PixelPasswordInput label="Pixel surface" surface="pixel" placeholder="Password" />
      <PixelPasswordInput label="Linear surface" surface="linear" placeholder="Password" />
    </div>
  );
}

Disabled

import { PixelPasswordInput } from '@pxlkit/ui-kit';

export function Disabled() {
  return (
    <PixelPasswordInput
      label="Password"
      disabled
      defaultValue="cannot-edit"
    />
  );
}

Custom toggle labels

import { PixelPasswordInput } from '@pxlkit/ui-kit';

export function CustomToggleLabels() {
  return (
    <PixelPasswordInput
      label="Password"
      toggleLabels={['View', 'Mask']}
      placeholder="Enter password"
    />
  );
}

Controlled

import { useState } from 'react';
import { PixelPasswordInput } from '@pxlkit/ui-kit';

export function Controlled() {
  const [value, setValue] = useState('');
  return (
    <PixelPasswordInput
      label="Password"
      value={value}
      onChange={(e) => setValue(e.target.value)}
      hint={`Length: ${value.length}`}
    />
  );
}

Uncontrolled

import { PixelPasswordInput } from '@pxlkit/ui-kit';

export function Uncontrolled() {
  return (
    <PixelPasswordInput
      label="Password"
      defaultValue="hunter2"
    />
  );
}

Related