36 lines
859 B
TypeScript
36 lines
859 B
TypeScript
import * as React from 'react';
|
|
import { clsx } from 'clsx';
|
|
import { Loader2 } from 'lucide-react';
|
|
|
|
export interface LoadingSpinnerProps {
|
|
size?: 'sm' | 'md' | 'lg';
|
|
label?: string;
|
|
className?: string;
|
|
}
|
|
|
|
export function LoadingSpinner({
|
|
size = 'md',
|
|
label = 'Loading…',
|
|
className,
|
|
}: LoadingSpinnerProps) {
|
|
const sizes: Record<string, string> = {
|
|
sm: 'h-4 w-4',
|
|
md: 'h-6 w-6',
|
|
lg: 'h-8 w-8',
|
|
};
|
|
|
|
return (
|
|
<div
|
|
role="status"
|
|
aria-busy="true"
|
|
aria-label={label}
|
|
className={clsx('flex items-center justify-center gap-2', className)}
|
|
>
|
|
<Loader2 className={clsx(sizes[size], 'animate-spin text-[var(--bl-accent,#5A8CFF)]')} />
|
|
{label && <span className="text-sm text-[var(--bl-text-secondary,#a0a0b0)]">{label}</span>}
|
|
</div>
|
|
);
|
|
}
|
|
|
|
LoadingSpinner.displayName = 'LoadingSpinner';
|