PasswordInput
A password field with a button to show what you typed and a hint when Caps Lock is on.
- The eye shows the password; the caret stays where it was, so you can keep typing.
- Show it, then press Sign in: submitting the form hides it again.
- Type with Caps Lock on: a hint appears under the field until it goes off or you leave.
Field marks
- Import
import { PasswordInput } from "cennge-ui";- Size
- 3.7 KB gzip for this import, its dependencies aside
- Pattern
- Native
<input type="password">and a toggle button witharia-pressed - Keyboard
- SpaceEnter
- State
- Value and visibility, each controlled or uncontrolled
- SSR
- Rendered on the server in the Next.js check; hydrates without a warning
- Autofill
current-passwordby default;new-passwordon sign-up- Hidden again
- When its form is submitted or reset
- Tests
- Unit tests; end-to-end in Chromium, Firefox and WebKit, on desktop and phone viewports: password-input
When to use#
Use a PasswordInput wherever a password is typed: sign-in, sign-up, a change of password. Showing the password lets people check a long one before they send it; the caret stays where it was when it switches, and the field goes back to dots as soon as the form is sent.
Set autoComplete="new-password" on sign-up and change-password forms, so password managers offer to generate one; the default, current-password, is for signing in. Give the email or username field in the same form autoComplete="username", so the manager knows which account the password belongs to.
Similar#
- Input is the plain text field; it has no show/hide button and no Caps Lock hint.
- OtpInput is for one-time codes from an authenticator app, an email or a text message.
Sign-up form#
Inside a Form, the browser's own checks (isRequired, minLength) show their message under the field. Press Create account with a short password.
import { Button, Form, Input, PasswordInput, toast } from "cennge-ui";
export default function SignUpForm() {
return (
<Form
className="flex w-full max-w-80 flex-col gap-4"
onSubmit={(event) => {
event.preventDefault();
toast.success("Account created", { description: String(new FormData(event.currentTarget).get("email")) });
}}
>
<Input label="Email" name="email" type="email" autoComplete="username" placeholder="dev@example.com" isRequired />
<PasswordInput
label="Password"
name="password"
autoComplete="new-password"
minLength={12}
isRequired
description="At least 12 characters"
/>
<Button type="submit" color="primary" className="self-start">
Create account
</Button>
</Form>
);
}One switch for both fields#
isVisible and onVisibilityChange control the visibility from outside. Here one Switch and either eye show or hide both fields together.
import { useState } from "react";
import { PasswordInput, Switch } from "cennge-ui";
export default function ChangePassword() {
const [isVisible, setVisible] = useState(false);
const [password, setPassword] = useState("");
const [confirmation, setConfirmation] = useState("");
const isMismatch = confirmation.length > 0 && confirmation !== password;
return (
<div className="flex w-full max-w-80 flex-col gap-4">
<PasswordInput
label="New password"
autoComplete="new-password"
value={password}
onValueChange={setPassword}
isVisible={isVisible}
onVisibilityChange={setVisible}
/>
<PasswordInput
label="Repeat it"
autoComplete="new-password"
value={confirmation}
onValueChange={setConfirmation}
isVisible={isVisible}
onVisibilityChange={setVisible}
isInvalid={isMismatch}
errorMessage="The two passwords differ"
/>
<Switch size="sm" isSelected={isVisible} onValueChange={setVisible}>
Show passwords
</Switch>
</div>
);
}Accessibility#
The eye is a button named "Show password" whatever the state; its aria-pressed says whether the password is shown, and aria-controls points at the field. It is in the Tab order after the field and works with Space and Enter.
The Caps Lock hint joins the field's aria-describedby, before the description, so it is read with the field. A browser only tells the state of Caps Lock in a key event, so the hint appears with the first key pressed in the field, not on focus. Translate the button with toggleLabel and the hint with capsLockWarning, or turn the hint off with capsLockWarning={false}.
Styling#
It shares the Input's box: variant, color, size, radius and startContent; the end of the box belongs to the eye. classNames reaches base, label, inputWrapper, input, toggle, capsLock, description and errorMessage.
Props#
Also takes every attribute of <input>, except size, color, type, value, defaultValue, autoComplete, which mean something else here.