DEV Community

Saurabh Paryani
Saurabh Paryani

Posted on

2

Creating a simple Show/Hide Password feature in Nextjs Forms

This is a simple blog on how you can add a simple eye icon next to the password field of your login/sign up form.
The end result would look something like:

Show Password

What we want:

  1. An eye off icon next to the password field only after the password field has some non-empty value inside
  2. When clicked on eye off, it should reveal password and the icon should change to eye.

All you need for this is:

  1. 2 React Icons (RiEyeFill and RiEyeOffFill) (you can search for other icons on [https://react-icons.github.io/react-icons])
  2. Knowledge of the useState hook in React

So let me take you with what I'm working. I have a form component in Nextjs using the React-Hook-Form and other components by ShadcnUI.

Let's say we're working on the login form (you can follow the same steps for the signup as well)

In the login form, I have 2 form fields.

Form Fields

An email field and a password field.

Step 1: Import the React icons.
import { RiEyeFill, RiEyeOffFill } from "react-icons/ri";

Step 2: Go all the way down to your password field input.
For me, it looks like:

Password Form Field

Try rendering an icon here. In order to render it next to the password, wrap the Input in a div and add a button in the same row using flex.

                  <FormControl>
                    <div className="flex flex-row">
                      <Input
                        placeholder="******"
                        type="password"
                        {...field}
                        disabled={isPending}
                      />
                      <button className="ml-4 text-gray-700">
                        <RiEyeOffFill />
                      </button>
                    </div>
                  </FormControl>
Enter fullscreen mode Exit fullscreen mode

Step 2.1

But what I want is that the icon should be displayed only when there is something inside the password field.
For that, create a state at the top:

const [isPasswordTyping, setIsPasswordTyping] = useState(false);

Inside the Input tag, whenever there is a change in the password field, create an onChange event that sets this isPasswordTyping to true. Or rather, length > 0.

onChange={(e) => {
     field.onChange(e);
     setIsPasswordTyping(e.target.value.length > 0);
  }}
Enter fullscreen mode Exit fullscreen mode

This field is something that Shadcn's React-Hook-Form provides.

Finally render the button only if isPasswordTyping is true.
So now, you will only see the icon rendered if the password has a non empty field inside.

                  <FormControl>
                    <div className="flex flex-row">
                      <Input
                        placeholder="******"
                        type="password"
                        {...field}
                        onChange={(e) => {
                          field.onChange(e);
                          setIsPasswordTyping(e.target.value.length > 0);
                        }}
                        disabled={isPending}
                      />
                      {isPasswordTyping && (
                        <button className="ml-4 text-gray-700">
                          <RiEyeOffFill />
                        </button>
                      )}
                    </div>
                  </FormControl>
Enter fullscreen mode Exit fullscreen mode

Step 3: Toggle Visibility and change icon

We need to render the password as text if a variable "showPassword" is true, and the password as password (******) if "showPassword" is false.

For that create a state,
const [showPassword, setShowPassword] = useState(false);

and in the Input, add the line: type={showPassword ? "text" : "password"}

                      <Input
                        placeholder="******"
                        type={showPassword ? "text" : "password"}
                        {...field}
                        onChange={(e) => {
                          field.onChange(e);
                          setIsPasswordTyping(e.target.value.length > 0);
                        }}
                        disabled={isPending}
                      />
Enter fullscreen mode Exit fullscreen mode

We need to render the icon. if showPassword is true, then we need to render the EyeFill icon, else the EyeOffFill.

<button className="ml-4 text-gray-700">
    {showPassword ? <RiEyeFill /> : <RiEyeOffFill />}
</button>
Enter fullscreen mode Exit fullscreen mode

Finally, we need to add an onClick to this button and toggle the visibility.

const togglePasswordVisibility = () => {
    setShowPassword((prev) => !prev);
 };
Enter fullscreen mode Exit fullscreen mode
<button type="button" onClick={togglePasswordVisibility} className="ml-4 text-gray-700">
    {showPassword ? <RiEyeFill /> : <RiEyeOffFill />}
</button>
Enter fullscreen mode Exit fullscreen mode

And we're done. Here's a live demo:

Demo Gif

Thanks for reading. Let me know if you have any questions!
Happy coding.

Saurabh Paryani

Image of Datadog

The Future of AI, LLMs, and Observability on Google Cloud

Datadog sat down with Google’s Director of AI to discuss the current and future states of AI, ML, and LLMs on Google Cloud. Discover 7 key insights for technical leaders, covering everything from upskilling teams to observability best practices

Learn More

Top comments (0)

Billboard image

The Next Generation Developer Platform

Coherence is the first Platform-as-a-Service you can control. Unlike "black-box" platforms that are opinionated about the infra you can deploy, Coherence is powered by CNC, the open-source IaC framework, which offers limitless customization.

Learn more

👋 Kindness is contagious

Please leave a ❤️ or a friendly comment on this post if you found it helpful!

Okay