Password Visibility Toggle

Create a password input field with a toggle button that shows or hides the password.

Solution

Explanation

The HTML Structure

A label, an input and a button.

The label is linked to the input via htmlFor. Don't be tempted to only add the label as a placeholder as this has accessibility issues. When you start typing the placeholder goes and so does the instruction.

The input type is set initially to password. This is how you get the effect of hiding the typed values with asterix.

Note that the id attribute links the input to the label. The name attribute is the key for the password value if it were hooked up to be sent in a form.

How to toggle the hidden password

You may be tempted to use display: none; and have more than one element but you can simply toggle the input type from password to text. This ensures a smoother experience.

Code

import { useState } from "react";
import styles from "./Solution.module.css";

const Solution = () => {
  const [pwd, setPwd] = useState("");
  const [visible, toggleVisible] = useState(false);

  const toggleVisibility = (): void => {
    toggleVisible((prevVisible) => !prevVisible);
  };

  const handleInput = (event: React.ChangeEvent<HTMLInputElement>): void => {
    setPwd(event.target.value);
  };

  return (
    <>
      <label className={styles.label} htmlFor="password">
        Enter Password
      </label>
      <input
        className={styles.input}
        onChange={handleInput}
        value={pwd}
        type={visible ? "text" : "password"}
        id="password"
        name="pwd"
      />{" "}
      <button className={styles.button} onClick={toggleVisibility}>
        {visible ? "Hide Password" : "Show Password"}
      </button>
    </>
  );
};

export default Solution;

Styling

.label {
  display: block;
  margin-bottom: 10px;
}

.input,
.button {
  padding: 5px;
  border-radius: 5px;
  border: 2px solid black;
  cursor: pointer;
}

Links