55 lines
1.8 KiB
TypeScript
55 lines
1.8 KiB
TypeScript
import React, { useState, useEffect } from 'react';
|
|
|
|
export interface LoadingButtonProps {
|
|
className?: string;
|
|
progress: number | null;
|
|
onClick: () => any;
|
|
title?: string;
|
|
}
|
|
|
|
export const LoadingButton: React.FC<LoadingButtonProps> = ({ className = '', onClick, progress, title = "Click me" }) => {
|
|
const [loading, setLoading] = useState(false);
|
|
|
|
useEffect(() => {
|
|
if (progress && progress >= 100) {
|
|
setLoading(false);
|
|
}
|
|
}, [progress])
|
|
|
|
const handleClick = () => {
|
|
setLoading(true);
|
|
onClick();
|
|
};
|
|
|
|
return (
|
|
<div className="relative">
|
|
<button
|
|
className={`relative bg-blue-500 hover:bg-blue-700 w-full text-white font-bold py-2 px-4 rounded-full transition-transform duration-200 transform hover:-translate-y-1 hover:scale-105 ${loading ? "cursor-not-allowed" : ""
|
|
}`}
|
|
onClick={handleClick}
|
|
disabled={loading}
|
|
style={{
|
|
whiteSpace: "nowrap",
|
|
textOverflow: "ellipsis",
|
|
overflow: "hidden", display: 'inline-block', border: '0px solid black'
|
|
}}
|
|
>
|
|
<span className={`text-center z-10 ${loading ? "opacity-50" : ""}`}>
|
|
{loading ? `${progress}%` : `${title}`}
|
|
</span>
|
|
<div
|
|
className={`absolute h-full transition-width duration-500`}
|
|
style={{
|
|
width: `${progress}%`,
|
|
backgroundColor: "blue",
|
|
top: 0,
|
|
left: 0,
|
|
zIndex: "-1"
|
|
}}
|
|
></div>
|
|
</button>
|
|
</div>
|
|
);
|
|
};
|
|
|