Password Input
A password field with a button that shows or hides the password.
A zui-input with an icon button at the end. Press the button to show the password as plain text. Press it again to hide it. The button uses aria-pressed, so screen readers announce the state.
Usage
<div class="zui-field">
<label class="zui-label" for="password">Password</label>
<div class="zui-password-input">
<input class="zui-input" type="password" id="password" autocomplete="current-password" />
<button
type="button"
class="zui-button zui-button-variant-ghost zui-button-size-sm zui-button-icon zui-password-input-toggle"
aria-label="Show password"
aria-pressed="false"
data-zui-password-toggle
>
<i class="ph ph-eye zui-password-input-show" aria-hidden="true"></i>
<i class="ph ph-eye-slash zui-password-input-hide" aria-hidden="true"></i>
</button>
</div>
</div>
<script>
document.addEventListener('click', (event) => {
const button = event.target.closest('[data-zui-password-toggle]')
if (!button) return
const input = button.closest('.zui-password-input').querySelector('input')
const show = input.type === 'password'
input.type = show ? 'text' : 'password'
button.setAttribute('aria-pressed', String(show))
})
</script>import { Field, Label, PasswordInput } from '@mrmartineau/zui/react'
<Field>
<Label htmlFor="password">Password</Label>
<PasswordInput id="password" autoComplete="current-password" />
</Field>---
import { Field, Label, PasswordInput } from '@mrmartineau/zui/astro'
---
<Field>
<Label for="password">Password</Label>
<PasswordInput id="password" autocomplete="current-password" />
</Field>import { Field, Label, PasswordInput } from '@mrmartineau/zui/solid'
<Field>
<Label for="password">Password</Label>
<PasswordInput id="password" autocomplete="current-password" />
</Field><script lang="ts">
import { Field, Label, PasswordInput } from '@mrmartineau/zui/svelte'
let password = $state('')
</script>
<Field>
<Label for="password">Password</Label>
<PasswordInput id="password" autocomplete="current-password" bind:value={password} />
</Field><template>
<Field>
<Label for="password">Password</Label>
<PasswordInput id="password" autocomplete="current-password" />
</Field>
</template>
<script setup>
import { Field, Label, PasswordInput } from '@mrmartineau/zui/vue'
</script>The Astro, React, Solid, Svelte and Vue components handle the toggle for you. You only need the script above with plain HTML. Add it once per page.
Disabled
The toggle button is disabled when the input is disabled.
<div class="zui-password-input">
<input class="zui-input" type="password" value="secret" disabled />
<button type="button" class="zui-button zui-button-variant-ghost zui-button-size-sm zui-button-icon zui-password-input-toggle" aria-label="Show password" aria-pressed="false" disabled data-zui-password-toggle>
<i class="ph ph-eye zui-password-input-show" aria-hidden="true"></i>
<i class="ph ph-eye-slash zui-password-input-hide" aria-hidden="true"></i>
</button>
</div><PasswordInput value="secret" disabled /><PasswordInput value="secret" disabled /><PasswordInput value="secret" disabled /><PasswordInput value="secret" disabled /><PasswordInput value="secret" disabled />Props
All <input> attributes go to the input, except type. The class prop goes on the wrapper.
| Prop | Default | Description |
|---|---|---|
shape |
default |
Input shape: default, hard, soft, squircle. Same as Input |
toggleLabel |
Show password |
Accessible name of the toggle button. Change it for other languages |
CSS classes
| Class | Description |
|---|---|
zui-password-input |
Wrapper. Holds the input and the toggle button |
zui-password-input-toggle |
The toggle button. Use with the ghost, small, icon zui-button classes |
zui-password-input-show |
Icon shown when the password is hidden |
zui-password-input-hide |
Icon shown when the password is visible |
CSS custom properties
The input uses the Input custom properties.
| Property | Default | Description |
|---|---|---|
--zui-password-input-icon-size |
var(--step--1) |
Size of the eye icon |