Close Menu

    Subscribe to Updates

    Get the latest creative news from FooBar about art, design and business.

    What's Hot

    How to create Animated No Chill Login form using HTML CSS and JS

    22 May 2025

    How to make Social media icons hover effect using HTML & CSS

    14 May 2025

    How to make Awesome Radar Animation using HTML & CSS

    8 May 2025
    Facebook X (Twitter) Instagram YouTube Telegram Threads
    Coding StellaCoding Stella
    • Home
    • Blog
    • HTML & CSS
      • Login Form
    • JavaScript
    • Hire us!
    Coding StellaCoding Stella
    Home - JavaScript - How to create Animated File Upload Modal using JavaScript
    JavaScript

    How to create Animated File Upload Modal using JavaScript

    Coding StellaBy Coding Stella23 April 2025No Comments10 Mins Read
    Share Facebook Twitter Pinterest LinkedIn Tumblr Reddit Email WhatsApp Copy Link

    Let’s create an Animated File Upload Modal using HTML, CSS, and JavaScript. This project will allow users to upload files through a sleek and animated modal popup, adding style and interactivity to your web forms.

    We’ll use:

    • HTML to structure the modal and file upload input.
    • CSS to design a smooth, responsive, and animated modal.
    • JavaScript to open/close the modal and handle file input interactions.

    This is a great mini-project for practicing modal logic, animations, and basic file input handling. Perfect for portfolios, dashboards, or any site needing a modern file upload feature. Let’s build it and give our UI a polished feel! 📁✨

    HTML :

    This HTML creates a file upload popup modal with:

    • Close button
    • Upload, progress, error, and success states
    • File preview and progress bar
    • Mobile-friendly and animated UI

    It links to external CSS and JavaScript for full functionality.

    <!DOCTYPE html>
    <html lang="en" >
    <head>
      <meta charset="UTF-8">
      <title>Animated Upload Modal | @coding.stella</title>
      <meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover"><link rel='stylesheet' href='https://fonts.googleapis.com/css2?family=Nunito:wght@400;500;700&amp;display=swap'><link rel="stylesheet" href="./style.css">
    
    </head>
    <body>
    
    <div id="upload" class="modal" data-state="0" data-ready="false">
    	<div class="modal__header">
    		<button class="modal__close-button" type="button">
    			<svg class="modal__close-icon" viewBox="0 0 16 16" width="16px" height="16px" aria-hidden="true">
    				<g fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round">
    					<polyline points="1,1 15,15" />
    					<polyline points="15,1 1,15" />
    				</g>
    			</svg>
    			<span class="modal__sr">Close</span>
    		</button>
    	</div>
    	<div class="modal__body">
    		<div class="modal__col">
    			<!-- up -->
    			<svg class="modal__icon modal__icon--blue" viewBox="0 0 24 24" width="24px" height="24px" aria-hidden="true">
    				<g fill="none" stroke="hsl(223,90%,50%)" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
    					<circle class="modal__icon-sdo69" cx="12" cy="12" r="11" stroke-dasharray="69.12 69.12" />
    					<polyline class="modal__icon-sdo14" points="7 12 12 7 17 12" stroke-dasharray="14.2 14.2" />
    					<line class="modal__icon-sdo10" x1="12" y1="7" x2="12" y2="17" stroke-dasharray="10 10" />
    				</g>
    			</svg>
    			<!-- error -->
    			<svg class="modal__icon modal__icon--red" viewBox="0 0 24 24" width="24px" height="24px" aria-hidden="true" display="none">
    				<g fill="none" stroke="hsl(3,90%,50%)" stroke-width="2" stroke-linecap="round">
    					<circle class="modal__icon-sdo69" cx="12" cy="12" r="11" stroke-dasharray="69.12 69.12" />
    					<line class="modal__icon-sdo14" x1="7" y1="7" x2="17" y2="17" stroke-dasharray="14.2 14.2" />
    					<line class="modal__icon-sdo14" x1="17" y1="7" x2="7" y2="17" stroke-dasharray="14.2 14.2" />
    				</g>
    			</svg>
    			<!-- check -->
    			<svg class="modal__icon modal__icon--green" viewBox="0 0 24 24" width="24px" height="24px" aria-hidden="true" display="none">
    				<g fill="none" stroke="hsl(138,90%,50%)" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
    					<circle class="modal__icon-sdo69" cx="12" cy="12" r="11" stroke-dasharray="69.12 69.12" />
    					<polyline class="modal__icon-sdo14" points="7 12.5 10 15.5 17 8.5" stroke-dasharray="14.2 14.2" />
    				</g>
    			</svg>
    		</div>
    		<div class="modal__col">
    			<div class="modal__content">
    				<h2 class="modal__title">Upload a File</h2>
    				<p class="modal__message">Select a file to upload from your computer or device.</p>
    				<div class="modal__actions">
    					<button class="modal__button modal__button--upload" type="button" data-action="file">Choose File</button>
    					<input id="file" type="file" hidden>
    				</div>
    				<div class="modal__actions" hidden>
    					<svg class="modal__file-icon" viewBox="0 0 24 24" width="24px" height="24px" aria-hidden="true">
    						<g fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
    							<polygon points="4 1 12 1 20 8 20 23 4 23" />
    							<polyline points="12 1 12 8 20 8" />
    						</g>
    					</svg>
    					<div class="modal__file" data-file></div>
    					<button class="modal__close-button" type="button" data-action="fileReset">
    						<svg class="modal__close-icon" viewBox="0 0 16 16" width="16px" height="16px" aria-hidden="true">
    							<g fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round">
    								<polyline points="4,4 12,12" />
    								<polyline points="12,4 4,12" />
    							</g>
    						</svg>
    						<span class="modal__sr">Remove</span>
    					</button>
    					<button class="modal__button" type="button" data-action="upload">Upload</button>
    				</div>
    			</div>
    			<div class="modal__content" hidden>
    				<h2 class="modal__title">Uploading…</h2>
    				<p class="modal__message">Just give us a moment to process your file.</p>
    				<div class="modal__actions">
    					<div class="modal__progress">
    						<div class="modal__progress-value" data-progress-value>0%</div>
    						<div class="modal__progress-bar">
    							<div class="modal__progress-fill" data-progress-fill></div>
    						</div>
    					</div>
    					<button class="modal__button" type="button" data-action="cancel">Cancel</button>
    				</div>
    			</div>
    			<div class="modal__content" hidden>
    				<h2 class="modal__title">Oops!</h2>
    				<p class="modal__message">Your file could not be uploaded due to an error. Try uploading it again?</p>
    				<div class="modal__actions modal__actions--center">
    					<button class="modal__button" type="button" data-action="upload">Retry</button>
    					<button class="modal__button" type="button" data-action="cancel">Cancel</button>
    				</div>
    			</div>
    			<div class="modal__content" hidden>
    				<h2 class="modal__title">Upload Successful!</h2>
    				<p class="modal__message">Your file has been uploaded. You can copy the link to your clipboard.</p>
    				<div class="modal__actions modal__actions--center">
    					<button class="modal__button" type="button" data-action="copy">Copy Link</button>
    					<button class="modal__button" type="button" data-action="cancel">Done</button>
    				</div>
    			</div>
    		</div>
    	</div>
    </div>
    
      <script  src="./script.js"></script>
    
    </body>
    </html>
    

    CSS :

    This CSS styles a responsive modal popup with:

    • Smooth animations and transitions
    • Light and dark mode support
    • Upload button and progress bar
    • States like loading, error, success
    • Neat layout for both mobile and desktop

    It uses variables (--hue) to control colors and has clean design using flexbox and media queries.

    * {
    	border: 0;
    	box-sizing: border-box;
    	margin: 0;
    	padding: 0;
    }
    :root {
    	--hue: 223;
    	--bg: hsl(var(--hue),10%,85%);
    	--fg: hsl(var(--hue),10%,5%);
    	--trans-dur: 0.3s;
    	font-size: calc(16px + (20 - 16) * (100vw - 320px) / (2560 - 320));
    }
    body,
    button {
    	font: 1em/1.5 Nunito, Helvetica, sans-serif;
    }
    body {
    	background-color: var(--bg);
    	color: var(--fg);
    	height: 100vh;
    	display: grid;
    	place-items: center;
    	transition:
    		background-color var(--trans-dur),
    		color var(--trans-dur);
    }
    .modal {
    	background-color: hsl(var(--hue),10%,95%);
    	border-radius: 1em;
    	box-shadow: 0 0.75em 1em hsla(var(--hue),10%,5%,0.3);
    	color: hsl(var(--hue),10%,5%);
    	width: calc(100% - 3em);
    	max-width: 34.5em;
    	overflow: hidden;
    	position: relative;
    	transition:	background-color var(--trans-dur), color var(--trans-dur);
    }
    
    .modal:before {
    	background-color: hsl(223,90%,60%);
    	border-radius: 50%;
    	content: "";
    	filter: blur(60px);
    	opacity: 0.15;
    	position: absolute;
    	top: -8em;
    	right: -15em;
    	width: 25em;
    	height: 25em;
    	z-index: 0;
    	transition: background-color var(--trans-dur);
    }
    .modal__actions {
    	animation-delay: 0.2s;
    	display: flex;
    	align-items: center;
    	flex-wrap: wrap;
    }
    .modal__body,
    .modal__header {
    	position: relative;
    	z-index: 1;
    }
    .modal__body {
    	display: flex;
    	flex-direction: column;
    	padding: 0 2em 1.875em 1.875em;
    }
    .modal__button,
    .modal__close-button {
    	color: currentColor;
    	cursor: pointer;
    	-webkit-tap-highlight-color: transparent;
    }
    .modal__button {
    	background-color: hsla(var(--hue),10%,50%,0.2);
    	border-radius: 0.25rem;
    	font-size: 0.75em;
    	padding: 0.5rem 2rem;
    	transition:
    		background-color var(--trans-dur),
    		border-color var(--trans-dur),
    		opacity var(--trans-dur);
    	width: 100%;
    }
    .modal__button + .modal__button {
    	margin-top: 0.75em;
    }
    .modal__button:disabled {
    	opacity: 0.5;
    }
    .modal__button:focus,
    .modal__close-button:focus {
    	outline: transparent;
    }
    .modal__button:hover,
    .modal__button:focus-visible {
    	background-color: hsla(var(--hue),10%,60%,0.2);
    }
    .modal__button--upload {
    	background-color: transparent;
    	border: 0.125rem dashed hsla(var(--hue),10%,50%,0.4);
    	flex: 1;
    	padding: 0.375rem 2rem;
    }
    .modal__col + .modal__col {
    	flex: 1;
    	margin-top: 1.875em;
    }
    .modal__close-button,
    .modal__message,
    .modal__progress-value {
    	color: hsl(var(--hue),10%,30%);
    	transition: color var(--trans-dur);
    }
    .modal__close-button {
    	background-color: transparent;
    	display: flex;
    	width: 1.5em;
    	height: 1.5em;
    	transition: color var(--trans-dur);
    }
    .modal__close-button:hover,
    .modal__close-button:focus-visible {
    	color: hsl(var(--hue),10%,40%);
    }
    .modal__close-icon {
    	display: block;
    	margin: auto;
    	pointer-events: none;
    	width: 50%;
    	height: auto;
    }
    .modal__content > * {
    	/* don’t use shorthand syntax, or actions delay will be overridden */
    	animation-name: fadeSlideIn;
    	animation-duration: 0.5s;
    	animation-timing-function: ease-in-out;
    	animation-fill-mode: forwards;
    	opacity: 0;
    }
    .modal__file {
    	flex: 1;
    	font-size: 0.75em;
    	font-weight: 700;
    	margin-right: 0.25rem;
    	overflow: hidden;
    	text-overflow: ellipsis;
    	white-space: nowrap;
    }
    .modal__file ~ .modal__button {
    	margin-top: 1.5em;
    }
    .modal__file-icon {
    	color: hsl(var(--hue),10%,50%);
    	display: block;
    	margin-right: 0.75em;
    	width: 1.5em;
    	height: 1.5em;
    	transition: color var(--trans-dur);
    }
    .modal__header {
    	display: flex;
    	justify-content: flex-end;
    	align-items: center;
    	height: 2.5em;
    	padding: 0.5em;
    }
    .modal__icon {
    	display: block;
    	margin: auto;
    	width: 2.25em;
    	height: 2.25em;
    }
    .modal__icon--blue g {
    	stroke: hsl(223,90%,50%);
    }
    .modal__icon--red g {
    	stroke: hsl(3,90%,50%);
    }
    .modal__icon--green g {
    	stroke: hsl(138,90%,40%);
    }
    .modal__icon circle,
    .modal__icon line,
    .modal__icon polyline {
    	animation: sdo 0.25s ease-in-out forwards;
    	transition: stroke var(--trans-dur);
    }
    .modal__icon :nth-child(2) {
    	animation-delay: 0.25s;
    }
    .modal__icon :nth-child(3) {
    	animation-delay: 0.5s;
    }
    .modal__icon-sdo10 {
    	stroke-dashoffset: 10;
    }
    .modal__icon-sdo14 {
    	stroke-dashoffset: 14.2;
    }
    .modal__icon-sdo69 {
    	stroke-dashoffset: 69.12;
    	transform: rotate(-90deg);
    	transform-origin: 12px 12px;
    }
    .modal__message {
    	animation-delay: 0.1s;
    	font-size: 1em;
    	margin-bottom: 1.5em;
    	min-height: 3em;
    }
    .modal__progress {
    	flex: 1;
    }
    .modal__progress + .modal__button {
    	margin-top: 1.75em;
    }
    .modal__progress-bar {
    	background-image: linear-gradient(90deg,hsl(var(--hue),90%,50%),hsl(var(--hue),90%,70%));
    	border-radius: 0.2em;
    	overflow: hidden;
    	width: 100%;
    	height: 0.4em;
    	transform: translate3d(0,0,0);
    }
    .modal__progress-fill {
    	background-color: hsl(var(--hue),10%,90%);
    	width: inherit;
    	height: inherit;
    	transition: transform 0.1s ease-in-out;
    }
    .modal__progress-value {
    	font-size: 0.75em;
    	font-weight: 700;
    	line-height: 1.333;
    	text-align: right;
    }
    .modal__sr {
    	overflow: hidden;
    	position: absolute;
    	width: 1px;
    	height: 1px;
    }
    .modal__title {
    	font-size: 1.25em;
    	font-weight: 500;
    	line-height: 1.2;
    	margin-bottom: 1.5rem;
    	text-align: center;
    }
    /* state change */
    [data-state="2"]:before {
    	background-color: hsl(3,90%,60%);
    }
    [data-state="3"]:before {
    	background-color: hsl(138,90%,60%);
    }
    .modal__icon + .modal__icon,
    [data-state="1"] .modal__icon:first-child,
    [data-state="2"] .modal__icon:first-child,
    [data-state="3"] .modal__icon:first-child,
    .modal__content + .modal__content,
    [data-state="1"] .modal__content:first-child,
    [data-state="2"] .modal__content:first-child,
    [data-state="3"] .modal__content:first-child {
    	display: none;
    }
    [data-state="1"] .modal__icon:first-child,
    [data-state="2"] .modal__icon:nth-child(2),
    [data-state="3"] .modal__icon:nth-child(3),
    [data-state="1"] .modal__content:nth-child(2),
    [data-state="2"] .modal__content:nth-child(3),
    [data-state="3"] .modal__content:nth-child(4) {
    	display: block;
    }
    [data-ready="false"] .modal__content:first-child .modal__actions:nth-of-type(2),
    [data-ready="true"] .modal__content:first-child .modal__actions:first-of-type {
    	display: none;
    }
    [data-ready="true"] .modal__content:first-child .modal__actions:nth-of-type(2) {
    	display: flex;
    }
    
    /* Dark theme */
    @media (prefers-color-scheme: dark) {
    	:root {
    		--bg: hsl(var(--hue),10%,35%);
    		--fg: hsl(var(--hue),10%,95%);
    	}
    	.modal {
    		background-color: hsl(var(--hue),10%,10%);
    		color: hsl(var(--hue),10%,95%);
    	}
    	.modal__close-button,
    	.modal__message,
    	.modal__progress-value {
    		color: hsl(var(--hue),10%,70%);
    	}
    	.modal__close-button:hover,
    	.modal__close-button:focus-visible {
    		color: hsl(var(--hue),10%,80%);
    	}
    	.modal__file-icon {
    		color: hsl(var(--hue),10%,60%);
    	}
    	.modal__icon--blue g {
    		stroke: hsl(223,90%,60%);
    	}
    	.modal__icon--red g {
    		stroke: hsl(3,90%,60%);
    	}
    	.modal__icon--green g {
    		stroke: hsl(138,90%,60%);
    	}
    	.modal__progress-fill {
    		background-color: hsl(var(--hue),10%,20%);
    	}
    }
    
    /* Animations */
    @keyframes fadeSlideIn {
    	from { opacity: 0; transform: translateY(33%); }
    	to { opacity: 1; transform: translateY(0); }
    }
    @keyframes sdo {
    	to { stroke-dashoffset: 0; }
    }
    
    /* Beyond mobile */
    @media (min-width: 768px) {
    	.modal__actions--center {
    		justify-content: center;
    		margin-left: -4.125em;
    	}
    	.modal__body {
    		flex-direction: row;
    		align-items: center;
    	}
    	.modal__button {
    		width: auto;
    	}
    	.modal__button + .modal__button {
    		margin-top: 0;
    		margin-left: 1.5rem;
    	}
    	.modal__file ~ .modal__button {
    		margin-top: 0;
    	}
    	.modal__file ~ .modal__close-button {
    		margin-right: 1.5rem;
    	}
    	.modal__progress {
    		margin-right: 2em;
    	}
    	.modal__progress + .modal__button {
    		margin-top: 0;
    	}
    	.modal__col + .modal__col {
    		margin-top: 0;
    		margin-left: 1.875em;
    	}
    	.modal__title {
    		text-align: left;
    	}
    }

    JavaScript:

    This code sets up an upload modal that lets users select and upload a file, shows progress, handles success/failure, and allows copying the uploaded file’s name. When the page loads, it initializes the UploadModal class on a DOM element. The class handles clicking actions (upload, cancel, copy), updates UI states, reads the selected file, shows progress through a loop, and simulates success or failure using a random number generator.

    window.addEventListener("DOMContentLoaded",() => {
    	const upload = new UploadModal("#upload");
    });
    
    class UploadModal {
        filename = "";
        isCopying = false;
        isUploading = false;
        progress = 0;
        progressTimeout = null;
        state = 0;
    
        constructor(el) {
            this.el = document.querySelector(el);
            this.el?.addEventListener("click",this.action.bind(this));
            this.el?.querySelector("#file")?.addEventListener("change",this.fileHandle.bind(this));
        }
        action(e) {
            this[e.target?.getAttribute("data-action")]?.();
            this.stateDisplay();
        }
        cancel() {
            this.isUploading = false;
            this.progress = 0;
            this.progressTimeout = null;
            this.state = 0;
            this.stateDisplay();
            this.progressDisplay();
            this.fileReset();
        }
        async copy() {
            const copyButton = this.el?.querySelector("[data-action='copy']");
    
            if (!this.isCopying && copyButton) {
                // disable
                this.isCopying = true;
                copyButton.style.width = `${copyButton.offsetWidth}px`;
                copyButton.disabled = true;
                copyButton.textContent = "Copied!";
                navigator.clipboard.writeText(this.filename);
                await new Promise(res => setTimeout(res, 1000));
                // reenable
                this.isCopying = false;
                copyButton.removeAttribute("style");
                copyButton.disabled = false;
                copyButton.textContent = "Copy Link";
            }
        }
        fail() {
            this.isUploading = false;
            this.progress = 0;
            this.progressTimeout = null;
            this.state = 2;
            this.stateDisplay();
        }
        file() {
            this.el?.querySelector("#file").click();
        }
        fileDisplay(name = "") {
            // update the name
            this.filename = name;
    
            const fileValue = this.el?.querySelector("[data-file]");
            if (fileValue) fileValue.textContent = this.filename;
    
            // show the file
            this.el?.setAttribute("data-ready", this.filename ? "true" : "false");
        }
        fileHandle(e) {
            return new Promise(() => {
                const { target } = e;
                if (target?.files.length) {
                    let reader = new FileReader();
                    reader.onload = e2 => {
                        this.fileDisplay(target.files[0].name);
                    };
                    reader.readAsDataURL(target.files[0]);
                }
            });
        }
        fileReset() {
            const fileField = this.el?.querySelector("#file");
            if (fileField) fileField.value = null;
    
            this.fileDisplay();
        }
        progressDisplay() {
            const progressValue = this.el?.querySelector("[data-progress-value]");
            const progressFill = this.el?.querySelector("[data-progress-fill]");
            const progressTimes100 = Math.floor(this.progress * 100);
    
            if (progressValue) progressValue.textContent = `${progressTimes100}%`;
            if (progressFill) progressFill.style.transform = `translateX(${progressTimes100}%)`;
        }
        async progressLoop() {
            this.progressDisplay();
    
            if (this.isUploading) {
                if (this.progress === 0) {
                    await new Promise(res => setTimeout(res, 1000));
                    // fail randomly
                    if (!this.isUploading) {
                        return;
                    } else if (Utils.randomInt(0,2) === 0) {
                        this.fail();
                        return;
                    }
                }
                // …or continue with progress
                if (this.progress < 1) {
                    this.progress += 0.01;
                    this.progressTimeout = setTimeout(this.progressLoop.bind(this), 50);
                } else if (this.progress >= 1) {
                    this.progressTimeout = setTimeout(() => {
                        if (this.isUploading) {
                            this.success();
                            this.stateDisplay();
                            this.progressTimeout = null;
                        }
                    }, 250);
                }
            }
        }
        stateDisplay() {
            this.el?.setAttribute("data-state", `${this.state}`);
        }
        success() {
            this.isUploading = false;
            this.state = 3;
            this.stateDisplay();
        }
        upload() {
            if (!this.isUploading) {
                this.isUploading = true;
                this.progress = 0;
                this.state = 1;
                this.progressLoop();
            }
        }
    }
    
    class Utils {
        static randomInt(min = 0,max = 2**32) {
            const percent = crypto.getRandomValues(new Uint32Array(1))[0] / 2**32;
            const relativeValue = (max - min) * percent;
    
            return Math.round(min + relativeValue);
        }
    }

    In conclusion, the Animated File Upload Modal built with HTML, CSS, and JavaScript adds a clean, interactive way to handle file uploads. It improves user experience with stylish transitions and functional design.

    If your project has problems, don’t worry. Just click to download the source code and face your coding challenges with excitement. Have fun coding!

    hide and show password JavaScript password
    Share. Copy Link Twitter Facebook LinkedIn Email WhatsApp
    Previous ArticleHow to make Cool Loading Animation using HTML & CSS
    Next Article How to create 3D Animated Bee website using HTML CSS and JS
    Coding Stella
    • Website

    Related Posts

    JavaScript

    How to create Animated No Chill Login form using HTML CSS and JS

    22 May 2025
    JavaScript

    How to create Cross Road Game using HTML CSS and JS

    2 May 2025
    JavaScript

    How to create 3D Animated Bee website using HTML CSS and JS

    28 April 2025
    Add A Comment
    Leave A Reply Cancel Reply

    Trending Post

    Master Frontend in 100 Days Ebook

    2 March 202419K Views

    How to make Modern Login Form using HTML & CSS | Glassmorphism

    11 January 202416K Views

    How to make I love you Animation in HTML CSS & JavaScript

    14 February 202414K Views

    How to make Valentine’s Day Card using HTML & CSS

    13 February 202412K Views
    Follow Us
    • Instagram
    • Facebook
    • YouTube
    • Twitter
    ads
    Featured Post

    How to make Glowing Animated Login Form using HTML & CSS

    25 February 2025

    How to make Smooth Parallax Scrolling Cards using HTML CSS & JavaScript

    14 May 2024

    How to Make a Personal Portfolio Website Using HTML CSS & JavaScript

    9 December 2023

    How to create Password Validator using HTML CSS & JavaScript

    30 October 2024
    Latest Post

    How to create Animated No Chill Login form using HTML CSS and JS

    22 May 2025

    How to make Social media icons hover effect using HTML & CSS

    14 May 2025

    How to make Awesome Radar Animation using HTML & CSS

    8 May 2025

    How to create Cross Road Game using HTML CSS and JS

    2 May 2025
    Facebook X (Twitter) Instagram YouTube
    • About Us
    • Privacy Policy
    • Return and Refund Policy
    • Terms and Conditions
    • Contact Us
    • Buy me a coffee
    © 2025 Coding Stella. Made with 💙 by @coding.stella

    Type above and press Enter to search. Press Esc to cancel.

    Ad Blocker Enabled!
    Ad Blocker Enabled!
    Looks like you're using an ad blocker. We rely on advertising to help fund our site.
    Okay! I understood