One Time Password component — an optical illusion?
Tags: react, otp, 2fa
Published: 2022-08-31 14:31:02

Recently I have been building the login/register section of a web site where, at some point, I had to implement an **OTP** component to confirm the account creation: a component similar to the one in the screenshot above.

The first thing I thought when I saw the UI design was: “Ok, I need to create an array of `<input/>` elements and then add one or two hundreds of JS lines to handle the internal state, allow the user to enter/edit the code and to handle values pasted from the clip-board.

But then this question came to me mind: **why?**

Why do we have to implement such a design and more importantly: **what problem are we trying to solve here?**

Why do we need to have 6 input boxes and write all the logic to make them behave as if they were just a single input box?

Functionally speaking all we need to do is to allow the user to type in a 6 character string, yet most (if not all) the implementations of this component I saw on **NPM** are all basically following the same pattern: an array of input boxes and a lot of **JS** to make them work together seamlessly.

It feels wrong, there’s something I am not getting.

----------

After spending some time with these questions in my head I came up with the following explanation: **it is an optical illusion!**

----------

The origin of that design pattern probably dates back to the times where forms were printed on paper and people had to fill them manually, with a pen in their hand:

![](https://cdn-images-1.medium.com/max/800/1*ySoMcFckWiYGOBx7sUuy8g.png)

Having basically no control over the form filling process (we didn’t have client-side validation at that time) we came up with graphical solutions that would help the user to provide the data in a way that was as clear and correct as possible, i.e. in the screenshot above we have:

-   boxes to separate each character
-   pre-formatted date fields to clarify the date format

In the example above it is clear that “DATE OF BIRTH” has been broken down to 8 boxes to suggest the user that we need the date to be in the **dd/mm/yyyy** format rather than **dd/mm/yy.**

It is just a graphical treatment meant to help the user to fill the form in correctly.

These days we have electronic forms and those things give us full control over the filling process. We no longer need to split the information into its atomic parts to help the user to provide the correct data… and even if we decide to do so we can do it just at the graphical level.

The **OTP component** is (or should) be just that. From a graphical perspective it looks like a bunch of input-boxes but from a technical perspective it should be implemented as just one.

Building it as an array of inputs doesn’t solve any issue: on the contrary it requires a lot of effort to make it work and to maintain.

It is my candidate to the “Worst spent 200 lines of JS” award of the year!

----------

To get confirmation that the **OTP** can be a simple text box I looked around and saw that these two big guys have implemented it exactly as a simple input element:

![](https://cdn-images-1.medium.com/max/800/1*An0yTIpAvOw4dprkksjXHg.png)

![](https://cdn-images-1.medium.com/max/800/1*yMSjCl7H_vEUJyBOKNyS9w.png)

----------

### Let’s implement it anyway

So, in case we desperately need to implement a design like the one we saw at the beginning of this article, we can try adding some **CSS** and a few lines of **Js.**


Quick interaction example: https://youtu.be/iHdUOPLdRCM

A live demo is [available in here](https://codesandbox.io/s/onetimepassword-f0y0uk?file=/src/App.tsx)


In essence, we need to use a **monospaced** font in our component as this way each character has the same width. This allows us to create and position some `<span/>`in the background to give the illusion of multiple input-boxes.

The code is fairly simple and should be easily customisable by anyone familiar with CSS and JS.

### Final words

I had to write this down and share it with someone: is the **OTP** an optical illusion or am I hallucinating 🤔 ???

Your feedback would be highly appreciated!