Skip to main content

Overview

Password Toggle Field provides an enhanced password input with a built-in toggle button to switch between hiding and showing the password text. This improves usability by allowing users to verify their input.

Features

  • Toggle visibility of password text
  • Custom icons for show/hide states
  • Full keyboard navigation
  • Works inside forms
  • Can be controlled or uncontrolled
  • Accessible by default with proper ARIA attributes

Installation

npm install @radix-ui/react-password-toggle-field

Anatomy

import * as PasswordField from '@radix-ui/react-password-toggle-field';

export default () => (
  <PasswordField.Root>
    <PasswordField.Input />
    <PasswordField.Toggle>
      <PasswordField.Icon />
    </PasswordField.Toggle>
  </PasswordField.Root>
);

API Reference

Root

Contains all the password field parts.
visible
boolean
The controlled visibility state of the password.
defaultVisible
boolean
default:"false"
The visibility state when initially rendered (uncontrolled).
onVisibleChange
(visible: boolean) => void
Event handler called when the visibility state changes.
disabled
boolean
When true, prevents the user from interacting with the field.
asChild
boolean
default:"false"
Change the default rendered element for the one passed as a child.

Input

The password input element.
name
string
The name of the input. Submitted with its owning form as part of a name/value pair.
value
string
The controlled value of the input.
defaultValue
string
The value when initially rendered (uncontrolled).
onChange
(event: React.ChangeEvent<HTMLInputElement>) => void
Event handler called when the input value changes.
required
boolean
When true, indicates that the user must fill the input before submitting the form.
autoComplete
string
Hint for form autofill feature. Common values: “current-password”, “new-password”.
asChild
boolean
default:"false"
Change the default rendered element for the one passed as a child.

Toggle

The button that toggles password visibility.
asChild
boolean
default:"false"
Change the default rendered element for the one passed as a child.

Icon

Renders the appropriate icon based on visibility state.
forceMount
boolean
Used to force mounting when more control is needed.
asChild
boolean
default:"false"
Change the default rendered element for the one passed as a child.

Slot

A slot for custom content that changes based on visibility state.
asChild
boolean
default:"false"
Change the default rendered element for the one passed as a child.

Example

import * as PasswordField from '@radix-ui/react-password-toggle-field';
import { EyeOpenIcon, EyeClosedIcon } from '@radix-ui/react-icons';
import './styles.css';

export default () => (
  <div style={{ display: 'flex', flexDirection: 'column', gap: 8 }}>
    <label htmlFor="password">Password</label>
    <PasswordField.Root className="PasswordRoot">
      <PasswordField.Input
        className="PasswordInput"
        id="password"
        placeholder="Enter password"
      />
      <PasswordField.Toggle className="PasswordToggle" aria-label="Toggle password visibility">
        <PasswordField.Icon>
          {({ visible }) => (visible ? <EyeClosedIcon /> : <EyeOpenIcon />)}
        </PasswordField.Icon>
      </PasswordField.Toggle>
    </PasswordField.Root>
  </div>
);

Accessibility

The toggle button includes proper ARIA attributes to announce the visibility state to screen readers.

Keyboard Interactions

  • Tab - Moves focus between the input and toggle button.
  • Space/Enter - When toggle is focused, toggles password visibility.

Features

  • Input type automatically switches between “password” and “text”
  • Toggle button is properly labeled for screen readers
  • Visibility state is announced when changed
  • Supports all standard input attributes

Data Attributes

Root
  • [data-visible] - Present when password is visible
  • [data-disabled] - Present when disabled
Toggle
  • [data-visible] - Present when password is visible
  • [data-disabled] - Present when disabled
Icon
  • [data-visible] - Present when password is visible

Build docs developers (and LLMs) love