Loader
Animated spinner used internally by Button when loading. Can also be used standalone.
<Loader size="xs" />
<Loader size="sm" />
<Loader size="md" />
<Loader size="lg" />
<Loader size="xl" /><Loader color="root" />
<Loader color="primary" />
<Loader color="secondary" />import { Loader } from "@/ui";
<Loader />src/ui/Loader.tsx
import { cn } from "@/utils";
interface LoaderProps {
size?: "xs" | "sm" | "md" | "lg" | "xl";
color?: "root" | "primary" | "secondary";
className?: string;
"aria-label"?: string;
}
const sizeClass = {
xs: "size-3",
sm: "size-3.5",
md: "size-4",
lg: "size-5",
xl: "size-6",
} as const;
const colorClass = {
root: "text-root-contrast",
primary: "text-primary",
secondary: "text-secondary",
} as const;
export function Loader({
size = "md",
color = "root",
className,
"aria-label": ariaLabel = "Loading",
}: LoaderProps) {
return (
<svg
className={cn(
"shrink-0 animate-spin",
sizeClass[size],
colorClass[color],
className,
)}
viewBox="0 0 24 24"
fill="none"
role="status"
aria-label={ariaLabel}
>
<circle
className="opacity-25"
cx="12"
cy="12"
r="10"
stroke="currentColor"
strokeWidth="4"
/>
<path
className="opacity-75"
fill="currentColor"
d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4z"
/>
</svg>
);
}