JSFiddle - React, Tailwind, and code Playground

by NickU

HTML

<script src="https://code.jquery.com/jquery-3.6.0.js"></script>

<div id="container">
    <button id="toggle_form">Login</button>
    <form id="RegForm" class="form">
        <div id="username-wrapper" class="wrapper">
            <label for="inp_username">Username</label>
            <input type="text" id="reg_username" class="input_field" name="inp_username">
        </div>
        <div id="password-wrapper" class="wrapper">
            <label for="inp_password">Password</label>
            <input type="text" id="reg_password" class="input_field" name="inp_password">
        </div>
        
        <button id="SubmitReg" type="submit" class="SubBtn">Register</button>
    </form>
    
    <form id="LoginForm" class="form">
        <div id="username-wrapper" class="wrapper">
            <label for="inp_username">Username</label>
            <input type="text" id="login_username" class="input_field" name="inp_username">
        </div>
        <div id="password-wrapper" class="wrapper">
            <label for="inp_password">Password</label>
            <input type="text" id="login_password" class="input_field" name="inp_password">
        </div>
        
        <button id="SubmitLogin" type="submit" class="SubBtn">Login</button>
    </form>
</div>

CSS

* { 
    padding: 0;
    margin: 0;
    box-sizing: border-box;
}

.form { 
 display: inline-block;
 border: 1px solid;
 padding: 10px;
 position: absolute;
 width: 100%;
 height: 100%;
 background-color: #f1f1f1;
}

#RegForm {
    top: 0px;
    left:0px;
}


#LoginForm {
    top: 0;
    left:-100%;
    opacity: 0;
}


.input_field { 
    display: block;
    padding: 10px;
    width: 100%;
}

.wrapper { 
    
    text-align: center;
}

.SubBtn { 
    padding: 15px;
    width: 100%;
    font-size: 20px;
    cursor: pointer;
    margin-top: 10px;
    background-color:rgb(10, 157, 248);
    border: none;
    color: white;
}

.wrapper label { 
    display: inline-block;
    padding: 10px;
    font-size: 20px;
}

#container { 
    position: relative;
    width: 300px;
    height: 250px;
    display: inline-block;
    top: 100px;
    left:200px;
}

#toggle_form { 
    position: relative;
    top:-50px;
    left: 130px;
    padding: 5px;
}

JavaScript

class ProgressDisplay {
    constructor() {
        this.container = null;
        this.delayToClose = 0;
        this.closeTimer = null;
        this.stepsData = {}; // Will store step info like { [stepNumber]: { element, retryCount } }
    }

    init(delayToClose = 5000) {
        this.delayToClose = delayToClose;

        // Create container
        this.container = document.createElement('div');
        this.container.style.position = 'fixed';
        this.container.style.top = '10px';
        this.container.style.right = '10px';
        this.container.style.padding = '5px';
        this.container.style.backgroundColor = '#ddd'; // light grey background
        this.container.style.borderRadius = '4px';
        this.container.style.boxShadow = '0 0 5px rgba(0,0,0,0.3)';
        this.container.style.display = 'inline-flex';
        this.container.style.gap = '5px';
        this.container.style.zIndex = '9999';

        document.body.appendChild(this.container);
    }

    showStep(n, status) {
        if (!this.container) {
            console.warn('ProgressDisplay: init() was not called before showStep().');
            return;
        }

        // Cancel any previously set close timer since a new step is shown
        if (this.closeTimer) {
            clearTimeout(this.closeTimer);
            this.closeTimer = null;
        }

        let stepData = this.stepsData[n];

        // If step does not exist, create it
        if (!stepData) {
            const stepEl = document.createElement('div');
            stepEl.style.width = '20px';
            stepEl.style.height = '20px';
            stepEl.style.display = 'flex';
            stepEl.style.alignItems = 'center';
            stepEl.style.justifyContent = 'center';
            stepEl.style.borderRadius = '3px';
            stepEl.style.fontSize = '12px';
            stepEl.style.fontWeight = 'bold';
            stepEl.style.color = '#000';
            stepEl.style.boxShadow = 'inset 0 0 3px...