npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@xsolla/xui-input-password

v0.209.1

Published

A cross-platform React password input component with visibility toggle, validation checkmark, and clear functionality. <!-- BEGIN:xui-mcp-instructions:input-password --> A specialised text input for password entry. Extends the standard input with password

Readme

Input Password

A cross-platform React password input component with visibility toggle, validation checkmark, and clear functionality.

A specialised text input for password entry. Extends the standard input with password-specific controls: a show/hide visibility toggle, an optional clear button, an optional check icon for password confirmation fields, and a right icons block that groups these controls. Always renders with type="password" semantics (masked by default) unless the user explicitly toggles visibility.

When to use

For any field where the user must enter a password — login, registration, account settings, password reset

For password confirmation fields (e.g. "Confirm new password") — use alongside the primary password field

When the form requires the user to create a new password and strength feedback is shown nearby

When not to use

  • For non-sensitive text fields — use the standard Input component
  • For PINs or short numeric codes — use a dedicated PIN input or a numeric Input with inputmode="numeric"
  • When the input must always remain masked with no reveal option (e.g. a hardware security key PIN) — handle with a custom component that omits the visibility toggle

Content guidelines

Placeholder text — use Password or a format hint like At least 8 characters for create-password fields. Do not use verbose instructions as placeholder — they disappear when the user starts typing.

Field labels — always provide a visible label: "Password", "Current password", "New password", "Confirm new password". Do not rely on placeholder alone. Error messages — be specific:

  • "Password is required"
  • "Password must be at least 8 characters"
  • "Password must contain at least one number and one special character"
  • "Passwords do not match" (on the confirm field)
  • "Incorrect password" (on the login form after a failed attempt)
  • Visibility toggle label — the toggle icon button must have an accessible label that reflects the current state: aria-label="Show password" when masked, aria-label="Hide password" when revealed.
  • Avoid password rules in error messages only — communicate password requirements upfront (e.g. in a helper text or a requirements list below the field) so users know the rules before they make a mistake.

Behaviour guidelines (from industry practice)

Default masking — the field must always render in masked state (Visibility=False) on mount, even if a value is pre-filled. Never initialise with Visibility=True.

Visibility toggle — clicking the eye icon toggles between masked and plain text. The toggle must work with mouse, touch, and keyboard (Enter/Space when the icon has focus). After toggling, focus must remain in the input field, not on the icon button.

Remove button — show the remove button only when the field has a value (Filled=True). Hide it in the empty state. Clicking removes the value and returns focus to the input.

Check icon right — update in real time as the user types in either password field. Show when values match, hide when they diverge. Do not show the check icon if either field is empty.

Autocomplete — use autocomplete="current-password" for login/current-password fields and autocomplete="new-password" for create-password/confirm-password fields. This allows password managers to fill and save credentials correctly and satisfies WCAG 1.3.5.

Password managers — do not block paste (onpaste prevention) in password fields. Password managers and users rely on paste. Blocking paste is a security anti-pattern and degrades usability significantly.

Validation timing — validate on blur (when the user leaves the field) or on form submit. Do not validate every keystroke. For "Confirm password" fields, re-validate when either field changes.

Error state — switch to State=Error with a specific error message on blur or submit:

  • If the password does not meet requirements, show which requirement failed
  • If passwords do not match, show the error on the confirm field (not the primary)
  • Strength indicator — password strength feedback (e.g. a progress bar or label) lives outside the InputPassword component. Place it between the primary and confirm password fields.
  • Caps Lock warning — optionally surface a Caps Lock indicator when the user has Caps Lock active in a masked field. Show it as a helper text below the field or a tooltip on the visibility icon.
  • Disabled state — use State=Disable for fields that cannot be edited in the current context (e.g. a federated account where the password is managed externally). Always show a reason nearby.

Accessibility

The field must use type="password" in masked state and type="text" in revealed state. Never use type="text" permanently for a password field.

Provide a visible label via or aria-labelledby. Do not use placeholder as the only label.

Use autocomplete="current-password" or autocomplete="new-password" as appropriate — required for WCAG 1.3.5 (Identify Input Purpose).

The visibility toggle icon button must have a dynamic aria-label reflecting current state: "Show password" or "Hide password". It must also have aria-pressed (or aria-expanded) set appropriately, or use aria-label alone to communicate the current action.

When the field transitions to Visibility=True, announce the change to screen readers using aria-live="polite" on a visually hidden region (e.g. "Password is now visible").

The remove button (✕) must have aria-label="Clear password".

The check icon (✓) is status feedback — it must be wrapped in an aria-live="polite" region that announces "Passwords match" when it appears and "Passwords do not match" when it disappears.

When State=Error, the error message must be associated via aria-describedby so screen readers announce it when the field receives focus.

When State=Disable, the field must have aria-disabled="true".

The visibility toggle must be keyboard-operable: Tab to focus, Enter/Space to activate.

Installation

npm install @xsolla/xui-input-password

Demo

Basic Password Input

import * as React from "react";
import { InputPassword } from "@xsolla/xui-input-password";

export default function BasicPassword() {
  const [password, setPassword] = React.useState("");

  return (
    <InputPassword
      value={password}
      onChange={(e) => setPassword(e.target.value)}
      placeholder="Enter password"
    />
  );
}

With Visibility Toggle

import * as React from "react";
import { InputPassword } from "@xsolla/xui-input-password";

export default function VisibilityToggle() {
  const [password, setPassword] = React.useState("");

  return (
    <InputPassword
      value={password}
      onChange={(e) => setPassword(e.target.value)}
      extraSee={true}
      placeholder="Enter password"
    />
  );
}

With Validation

import * as React from "react";
import { InputPassword } from "@xsolla/xui-input-password";

export default function PasswordValidation() {
  const [password, setPassword] = React.useState("");

  return (
    <InputPassword
      value={password}
      onChange={(e) => setPassword(e.target.value)}
      extraSee={true}
      extraCheckup={(pass) => pass.length >= 8}
      label="Password"
      helperText="At least 8 characters"
      placeholder="Enter password"
    />
  );
}

With Error State

import * as React from "react";
import { InputPassword } from "@xsolla/xui-input-password";

export default function PasswordError() {
  const [password, setPassword] = React.useState("");

  return (
    <InputPassword
      value={password}
      onChange={(e) => setPassword(e.target.value)}
      extraSee={true}
      error={password.length > 0 && password.length < 8}
      errorMessage="Password must be at least 8 characters"
      label="Password"
      placeholder="Enter password"
    />
  );
}

Anatomy

import { InputPassword } from "@xsolla/xui-input-password";

<InputPassword
  value={password} // Controlled value
  onChange={handleChange} // Change handler (event)
  onChangeText={handleText} // Change handler (string)
  extraSee={true} // Show visibility toggle
  extraClear={true} // Show clear button
  extraCheckup={validateFn} // Validation function
  label="Label" // Label above input
  helperText="Help text" // Helper text below
  error={boolean} // Error state
  errorMessage="Error" // Error message
  size="md" // Size variant
  disabled={false} // Disabled state
/>;

Examples

Full Featured Password

import * as React from "react";
import { InputPassword } from "@xsolla/xui-input-password";

export default function FullPassword() {
  const [password, setPassword] = React.useState("");
  const [error, setError] = React.useState("");

  const validatePassword = (pass: string) => {
    if (pass.length < 8) return false;
    if (!/[A-Z]/.test(pass)) return false;
    if (!/[0-9]/.test(pass)) return false;
    return true;
  };

  const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {
    const value = e.target.value;
    setPassword(value);
    if (value && !validatePassword(value)) {
      setError("Password must be 8+ chars with uppercase and number");
    } else {
      setError("");
    }
  };

  return (
    <InputPassword
      value={password}
      onChange={handleChange}
      extraSee={true}
      extraClear={true}
      extraCheckup={validatePassword}
      onRemove={() => setPassword("")}
      label="Password"
      helperText="8+ characters, uppercase, and number required"
      error={!!error}
      errorMessage={error}
      placeholder="Create a strong password"
    />
  );
}

Password Sizes

import * as React from "react";
import { InputPassword } from "@xsolla/xui-input-password";

export default function PasswordSizes() {
  return (
    <div style={{ display: "flex", flexDirection: "column", gap: 16 }}>
      <InputPassword size="xs" placeholder="Extra Small" extraSee />
      <InputPassword size="sm" placeholder="Small" extraSee />
      <InputPassword size="md" placeholder="Medium" extraSee />
      <InputPassword size="lg" placeholder="Large" extraSee />
      <InputPassword size="xl" placeholder="Extra Large" extraSee />
    </div>
  );
}

API Reference

InputPassword

InputPassword Props:

| Prop | Type | Default | Description | | :------------- | :------------------------------------- | :------ | :------------------------------------------------------------------------------------------------------------ | | testID | string | — | Test ID for testing frameworks. On web this renders as data-testid; on React Native it renders as testID. | | value | string | - | Controlled input value. | | onChange | (e: ChangeEvent) => void | - | Change event handler. | | onChangeText | (text: string) => void | - | Text change handler. | | extraSee | boolean | false | Show visibility toggle button. | | extraClear | boolean | false | Show clear button. | | extraCheckup | (pass: string) => boolean | - | Validation function. | | initialVisible | boolean | false | Initial password visibility. | | size | "xl" \| "lg" \| "md" \| "sm" \| "xs" | "md" | Component size. | | label | string | - | Label above input. | | helperText | string | - | Helper text below input. | | error | boolean | false | Error state. | | errorMessage | string | - | Error message. | | disabled | boolean | false | Disabled state. | | placeholder | string | - | Placeholder text. | | name | string | - | Input name attribute. | | onRemove | () => void | - | Clear button handler. | | aria-label | string | - | Accessible label. | | testID | string | - | Test identifier. |

Behavior

  • Visibility Toggle: The eye icon reflects the current state of the password:
    • Open eye = Password is currently visible (type="text")
    • Closed eye = Password is currently hidden (type="password")
    • This follows modern design system conventions (Material, Apple, Atlassian, Polaris)
  • Checkmark appears when extraCheckup returns true
  • Clear button appears when input has value and extraClear is true
  • Error state shows red border and error message

Accessibility

  • Uses type="password" or type="text" based on visibility
  • Visibility toggle button has appropriate aria-label:
    • "Show password" when password is hidden
    • "Hide password" when password is visible
  • Toggle button uses aria-pressed to indicate current state
  • Error messages linked via aria-describedby for screen reader context
  • Labels properly linked via aria-labelledby when provided
  • Error messages use role="alert" for immediate announcement