ComponentsButton Loading
Button Loading
ButtonLoading.tsx
export function ButtonLoading() {
return (
<button
disabled
className="mx-auto flex items-center gap-2 rounded-xl bg-white px-4 py-2 text-sm font-semibold text-black duration-300 disabled:cursor-not-allowed disabled:opacity-70"
>
<Spinner />
<TextShine />
</button>
);
}
function Spinner() {
const bars = Array(12).fill(0);
return (
<div className="h-[18px] w-[18px]">
<div className="relative left-1/2 top-1/2 h-[inherit] w-[inherit]">
{bars.map((_, i) => (
<div
key={`spinner-bar-${i}`}
aria-label={`spinner-bar-${i + 1}`}
className={`absolute -left-[10%] -top-[3.9%] h-[8%] w-[24%] animate-spinner rounded-md bg-black bar:nth-child(${
i + 1
})`}
style={{
animationDelay: `-${1.3 - i * 0.1}s`,
transform: `rotate(${30 * i}deg) translate(146%)`,
}}
/>
))}
</div>
</div>
);
}
function TextShine() {
return (
<span className="inline-flex animate-shine bg-[linear-gradient(110deg,#000,45%,#a3a3a3,55%,#000)] bg-[length:200%_100%] bg-clip-text text-transparent">
Loading...
</span>
);
}
tailwind.config.ts
{
"animation": {
"spinner": "spinner 1.2s linear infinite",
"shine": "shine 2s linear infinite"
},
"keyframes": {
"spinner": {
"0%": {
"opacity": "1"
},
"100%": {
"opacity": "0.15"
}
},
"shine": {
"from": {
"backgroundPosition": "0 0"
},
"to": {
"backgroundPosition": "-200% 0"
}
}
}
}