Back to Component Explorer

Loading Button

buttons

Interactive button with toggleable loading state spinner and completion animation.

#button#loading#state#spinner
Live Interactive Preview

Component Source Code

Select language in the dropdown
LoadingButton.tsx
1'use client';
2
3import React, { useState } from 'react';
4import { Loader2, Check } from 'lucide-react';
5
6export default function LoadingButton() {
7 const [status, setStatus] = useState<'idle' | 'loading' | 'success'>('idle');
8
9 const handleClick = () => {
10 if (status !== 'idle') return;
11 setStatus('loading');
12 setTimeout(() => {
13 setStatus('success');
14 setTimeout(() => setStatus('idle'), 2000);
15 }, 1500);
16 };
17
18 return (
19 <button
20 onClick={handleClick}
21 disabled={status === 'loading'}
22 className="inline-flex h-11 sm:h-12 min-w-[140px] items-center justify-center rounded-xl bg-slate-900 dark:bg-slate-100 px-5 sm:px-6 text-sm font-semibold text-white dark:text-slate-900 shadow transition-all hover:bg-slate-800 dark:hover:bg-slate-200 active:scale-95 disabled:opacity-80 cursor-pointer"
23 >
24 {status === 'idle' && <span>Submit Form</span>}
25 {status === 'loading' && (
26 <span className="flex items-center gap-2">
27 <Loader2 className="h-4 w-4 animate-spin" />
28 <span>Processing...</span>
29 </span>
30 )}
31 {status === 'success' && (
32 <span className="flex items-center gap-1.5 text-emerald-400 dark:text-emerald-600 font-semibold">
33 <Check className="h-4 w-4" />
34 <span>Success</span>
35 </span>
36 )}
37 </button>
38 );
39}

Installation & Integration Guide

Step 1: Tailwind CSS v4 Setup
Tailwind Docs

If you do not have Tailwind installed yet, run this installation command:

Terminal
npm install tailwindcss @tailwindcss/postcss postcss

Then add the Tailwind directive to your main stylesheet (globals.css):

@import "tailwindcss";

Step 2: Install Icon Dependencies

npm install lucide-react react-icons

Step 3: Add Component File

Create a new file in your project at src/components/buttons/LoadingButton.tsx and paste the copied code from the source viewer above.

Step 4: Usage Example

ExamplePage.tsx
1import LoadingButton from '@/components/buttons/LoadingButton';
2
3export default function ExamplePage() {
4 return (
5 <main className="p-8 flex items-center justify-center min-h-screen">
6 <LoadingButton />
7 </main>
8 );
9}