Skip to content

Password Input

Authentication UISince 0.3.0
import { PasswordInput } from '@absoluteui/components/password-input';
import '@absoluteui/components/password-input/style.css';

Using Angular? See Password Input for Angular.

A password field built on a native password <input>. It provides:

  • label, help text, required indicator, and localized validation (length, pattern, custom);
  • a show/hide toggle button (aria-pressed, constant name “Show password”);
  • autocomplete for password managers: current-password (default) or new-password;
  • an optional Caps Lock warning;
  • a clipboard policy (paste is allowed by default);
  • the FormControl contract.

The value never appears in events, messages, or announcements. This is an input, not an authentication provider: AbsoluteUI does not handle credentials, hashing, policy, or sessions.

  • Sign-in, sign-up, and change-password forms.
  • Any secret the user types and may want to check visually (show/hide).
  • One-time codes and PINs: use OTP Input.
  • Non-secret text: use Text Input.
  • As a replacement for server-side password policy or authentication.
import { PasswordInput } from '@absoluteui/components/password-input';
const host = document.querySelector<HTMLElement>('#password');
if (host) PasswordInput.create(host, { label: 'Password', name: 'password', required: true });
import { PasswordInput } from '@absoluteui/components/password-input';
import { PasswordStrengthMeter } from '@absoluteui/components/password-strength-meter';
const inputHost = document.querySelector<HTMLElement>('#new-password');
const meterHost = document.querySelector<HTMLElement>('#strength');
if (inputHost && meterHost) {
const password = PasswordInput.create(inputHost, { label: 'New password', name: 'newPassword', autocomplete: 'new-password', required: true, minLength: 12 });
const meter = PasswordStrengthMeter.create(meterHost, { input: password });
password.update({ describedBy: [meter.describedById] });
}
import { PasswordInput } from '@absoluteui/components/password-input';
import '@absoluteui/components/password-input/style.css';
const host = document.querySelector<HTMLElement>('#new-password');
if (host) {
PasswordInput.create(host, {
label: 'New password',
name: 'newPassword',
autocomplete: 'new-password',
minLength: 12,
description: 'Use 12 or more characters.',
});
}
import { PasswordInput } from '@absoluteui/components/password-input';
const host = document.createElement('div');
document.body.append(host);
PasswordInput.create(host, { label: 'Password', name: 'password', required: true });
<div class="aui-field aui-password-input [--invalid] [--disabled]">
<label class="aui-field__label" for="I">Password<span aria-hidden="true">*</span></label>
<div class="aui-password-input__control">
<input id="I" class="aui-password-input__input" type="password" autocomplete="current-password"
spellcheck="false" autocapitalize="none" aria-describedby="D E C M">
<button type="button" class="aui-password-input__reveal" aria-label="Show password" aria-pressed="false" aria-controls="I">
<svg aria-hidden="true"/>
</button>
</div>
<div class="aui-field__description" id="D">help text</div>
<div class="aui-password-input__caps" id="C" hidden><svg aria-hidden="true"/><span>Caps Lock is on.</span></div>
<div class="aui-field__error" id="E">...</div>
</div>
(M = ids passed in describedBy, e.g. a Password Strength Meter)
PasswordInput.create(host: HTMLElement, options: PasswordInputOptions): PasswordInput

Global configuration key: passwordInput (see Configuration).

Option Type Default Description
label string Visible label (required accessible name). Required.
hideLabel boolean false Visually hide the label.
value string "" Initial value; reset() restores it.
name string Form field name.
description string Help text, referenced by aria-describedby.
required boolean false Value is required.
disabled boolean false Disabled.
readOnly boolean false Read-only.
minLength number Minimum length (code points).
maxLength number Maximum length; validated, not truncated.
pattern string HTML pattern semantics (anchored, v flag).
autocomplete 'current-password' | 'new-password' | 'off' "current-password" Password-manager hint. Use new-password on sign-up and change-password forms.
revealable boolean true Show the show/hide toggle.
clipboard 'allow' | 'block-copy' | 'block-all' "allow" Clipboard policy.
describedBy readonly string[] Extra element ids for aria-describedby (e.g. a strength meter).
validate (value: string) => string | null Consumer validation; the message must not contain the value.
icons Partial<{ error: IconRef; reveal: IconRef; conceal: IconRef; capsLock: IconRef }> Icon slot overrides.
validationTiming 'blur' | 'input' | 'submit' "blur" When validation messages first appear; afterwards they update live. Globally configurable.
capsLockWarning boolean true Show a warning while Caps Lock is on and the field has focus. Globally configurable.
locale string "en-US" Message locale. Globally configurable. Inherited from common configuration.
Property Type Description
host HTMLElement Host element.
input HTMLInputElement The native input.
value string Current value.
validity FieldValidity Current validity.
revealed boolean Password shown as text.
name string | null Form field name.
label string Accessible label (used by the error summary).
disabled boolean Whether the control is disabled.
dirty boolean Value differs from the initial value.
touched boolean Focus has left the control at least once.
options Readonly<PasswordInputOptions> Current options.
Method Description
getFormValue(): string The value.
setValue(value: string): void Set the value (no events).
setRevealed(revealed: boolean): void Show or mask the password.
update(options: Partial<PasswordInputOptions>): void Merge and apply options.
reportValidity(): boolean Show messages now (marks the control submitted) and return validity.
setCustomError(message: string | null): void External error (server, cross-field rule); null clears it.
focus(): void Move focus to the primary focusable element.
reset(): void Restore the initial value and clear dirty/touched/submitted state.
destroy(): void Remove rendering, registration, listeners, and the configuration subscription.
Event Detail Bubbles Cancelable Description
aui-input { validity: FieldValidity } Yes No User edited the value (the value is not in the detail).
aui-change { validity: FieldValidity } Yes No User committed the value (native change).
aui-caps-lock { on: boolean } No No The Caps Lock warning appeared or disappeared.

All rules live in the aui.components cascade layer, so application styles override them without specificity battles.

Class Purpose
aui-password-input Host (also aui-field).
aui-password-input--invalid | --disabled State modifiers.
aui-password-input__control Control boundary.
aui-password-input__input Native input.
aui-password-input__reveal Show/hide toggle.
aui-password-input__caps Caps Lock warning.
Slot Default icon
error alert-circle
reveal eye
conceal eye-off
capsLock alert-triangle

Tokens this stylesheet reads (verified in CI). Override them in a theme or with the Theme Designer.

--aui-border-width | --aui-color-border | --aui-color-border-strong | --aui-color-disabled-bg | --aui-color-error-fg | --aui-color-focus-ring | --aui-color-hover | --aui-color-surface | --aui-color-surface-sunken | --aui-color-text | --aui-color-text-disabled | --aui-color-text-muted | --aui-color-warning-fg | --aui-control-height-md | --aui-control-padding-x | --aui-duration-fast | --aui-easing-standard | --aui-focus-ring-offset | --aui-focus-ring-width | --aui-font-family-sans | --aui-font-size-md | --aui-font-size-sm | --aui-font-weight-medium | --aui-icon-size-sm | --aui-line-height-normal | --aui-line-height-tight | --aui-radius-md | --aui-space-1

type PasswordAutocomplete = 'current-password' | 'new-password' | 'off';
type PasswordClipboardPolicy = 'allow' | 'block-copy' | 'block-all';
interface PasswordInputConfig { validationTiming: ValidationTiming; capsLockWarning: boolean }
interface PasswordInputOptions extends Partial<PasswordInputConfig> {
label: string; hideLabel?: boolean; value?: string; name?: string; description?: string;
required?: boolean; disabled?: boolean; readOnly?: boolean; minLength?: number; maxLength?: number; pattern?: string;
autocomplete?: PasswordAutocomplete; revealable?: boolean; clipboard?: PasswordClipboardPolicy;
describedBy?: readonly string[]; validate?: (value: string) => string | null; locale?: string; icons?: Partial<PasswordInputIcons>;
}
interface PasswordInputValueDetail { validity: FieldValidity }
interface PasswordInputCapsLockDetail { on: boolean }

Pattern: Native password <input> with <label for>, plus a toggle button (aria-pressed).

Key Context Action
Tab / Shift+Tab Any Moves to the input, then the toggle.
Enter / Space Toggle focused Shows or hides the password; focus stays on the toggle.
All editing keys Input focused Native text editing.
Element Role
input none: password inputs have no ARIA role (exposed as a protected text field)
toggle button (native), toggle via aria-pressed
icons none (aria-hidden=true)
Attribute Element Value
aria-describedby input Help text, visible error, Caps Lock warning (while shown), then describedBy ids
aria-invalid input “true” only while an error message is shown
aria-pressed toggle “true” while the password is shown; the name stays “Show password”
aria-controls toggle Input id

The control boundary shows the focus indicator; the toggle has its own :focus-visible outline.

Criterion Level Note
1.3.1 Info and Relationships A
1.3.5 Identify Input Purpose AA
1.4.3 Contrast (Minimum) AA
1.4.11 Non-text Contrast AA
2.1.1 Keyboard A
2.4.7 Focus Visible AA
3.3.1 Error Identification A
3.3.2 Labels or Instructions A
3.3.8 Accessible Authentication (Minimum) AA
4.1.2 Name, Role, Value A
4.1.3 Status Messages AA

Automated test results: Accessibility and compliance.

  • WCAG 3.3.8 (Accessible Authentication): paste and password managers are allowed by default.
  • Visibility changes are announced (Password shown / Password hidden); Caps Lock on is announced once per change.
  • The toggle keeps a constant name with aria-pressed; changing the name as well would be read as a contradiction.
  • Manual screen-reader verification (NVDA, JAWS, VoiceOver) is pending.

default, focus-visible, filled, revealed, caps lock on, disabled, read-only, required, invalid.

From Trigger To
masked toggle (click, Enter, Space) or setRevealed(true) revealed (type="text", aria-pressed="true", announced “Password shown”)
revealed toggle, setRevealed(false), or reset() masked (announced “Password hidden” when toggled)
any key or mouse event with Caps Lock on warning shown, described, announced once
warning Caps Lock off or blur warning hidden
  • WCAG 3.3.8 Accessible Authentication: paste and password managers work by default; do not block paste.
  • Visibility changes and Caps Lock are announced politely.
  • Manual screen-reader verification is pending.

Full width of its container; the toggle stays a square at the inline end.

Logical properties: the toggle sits at the inline end in both directions.

Control surface, border, focus, and error tokens as Text Input; Caps Lock warning in color-warning-fg with an icon. Forced-colors mode: Highlight outline on focus.

configureAbsoluteUI({ components: { passwordInput: { capsLockWarning: false, validationTiming: 'submit' } } });

Instance options override global and theme defaults. All options are dynamic.

icons.reveal (default eye), icons.conceal (eye-off), icons.capsLock (alert-triangle), icons.error (alert-circle).

  • The value never appears in events, validation messages, or announcements; the component never logs.
  • spellcheck is off (spelling services may send text off-device), autocapitalize is none.
  • The clipboard policy is a deterrent, not a security boundary; blocking paste harms security (it discourages password managers).
  • Edge’s built-in reveal control is hidden (::-ms-reveal) to avoid a second toggle.
  • Revealing is the user’s choice and shows the password on screen.
  • AbsoluteUI is not an authentication provider: transport the value over HTTPS, and let the server hash and enforce policy.

The value lives only in the native input (for native form submission when name is set) and is returned by getFormValue(). No persistence, logging, network access, or telemetry.

Same structure as Text Input. Budget: PasswordInput.create < 1 ms per instance (1,000 instances, e2e performance suite).

One value per field; tested with 1,000 fields on a page.

  • Caps Lock state is known only after a key or mouse event in the field.
  • Revealed passwords are masked again by reset() and whenever revealable becomes false.
  • Removing the focused toggle (update({ revealable: false })) is safe (regression covered).
  • maxLength is validated, not truncated, so long pasted values are reported instead of silently cut.
Code Category Cause
PASSWORD_INPUT_OPTIONS configuration Missing label, invalid lengths, autocomplete, clipboard policy, or describedBy ids.
FIELD_PATTERN configuration Invalid pattern.
CFG_INVALID_VALUE / CFG_UNKNOWN_OPTION configuration Invalid or unknown configuration.
  • Caps Lock detection depends on getModifierState.
  • Manual screen-reader verification is pending.
  • HTML in the label, help text, or messages.
  • Remembering passwords (password managers do this).