PrimitiveAvailable

Password Input

A masked password field with an independent, keyboard-accessible visibility toggle. Uses Input borders, focus and validation, and Phosphor Eye/EyeSlash icons.

Loading example…

Installation

Add the component and its dependencies from the registry running on your computer.

terminal
npx shadcn@latest add https://brutallab.facilito.dev/r/password-input.json

Usage

Import the component into your project and keep the source code under your control.

tsx
'use client';

import { PasswordInput } from '@/components/ui/password-input';
import { Label } from '@/components/ui/label';

export default function Demo() {
  return (
    <div className="grid w-full max-w-md gap-6">
      <div className="grid gap-2">
        <Label htmlFor="password-demo">Password</Label>
        <PasswordInput id="password-demo" autoComplete="new-password" placeholder="Enter a password" />
      </div>
      <div className="grid gap-2">
        <Label htmlFor="password-error">Invalid password</Label>
        <PasswordInput id="password-error" aria-invalid="true" aria-describedby="password-error-message" defaultValue="short" autoComplete="new-password" />
        <p id="password-error-message" className="bl-type-small text-destructive">Use at least 10 characters.</p>
      </div>
      <div className="grid gap-2">
        <Label htmlFor="password-disabled">Disabled</Label>
        <PasswordInput id="password-disabled" disabled defaultValue="not-editable" />
      </div>
    </div>
  );
}

States & interaction

Appearance, behavior and keyboard checks.

  • Masked initially. Eye reveals the password; EyeSlash masks it without changing the typed value. Each field has independent state.
  • The ghost button changes surface and border on hover. Tab shows focus; Enter and Space toggle visibility without submitting the form.
  • Invalid uses the Input error border and an associated message. Disabled disables both the field and the button.
  • Test the example with Tab and Shift+Tab. Focus must stay visible in both themes.

API Reference

BrutalLab-specific properties. Native attributes are supported as well.

PropTypeDefaultDescription
en / esenLanguage of the visibility button label.
stringShow password / Hide passwordOverride accessible names and tooltips; distinguish current and new passwords in the same form.
string—Styles the wrapper. className styles the input; reserve room for the trailing button.
ComponentProps<'input'> except type—Supports ref, id, value, onChange, disabled, required, autoComplete, aria-invalid and aria-describedby. Visibility never changes the value.

Accessibility

Rules that should remain intact when adapting the component to a product.

Place a visible label before the component and associate it through htmlFor and id. Do not wrap the input and button inside a label.

Tab reaches the input and visibility button; Enter or Space on the button toggles visibility without submitting the form. The accessible name and tooltip describe the next action.

Masked by default. Each field has its own state. Disabled also disables the visibility button. Read-only fields remain revealable.

Show errors through aria-invalid and an associated message. Only the consuming application validates passwords.