For the complete documentation index, see llms.txt. Markdown variants are available by appending .md to documentation URLs. Homepage markdown is available at /llms.md/content.md. An agent skill is available at /.well-known/agent-skills/site-skill.md.

Spinner

The Spinner component from this design system, built on Base UI.

Installation

$ pnpm dlx shadcn@latest add @cobalt/spinner

Source

import { cn } from "cn";
import * as React from "react";

const sizes = {
  xs: [12, 1.5],
  default: [16, 2],
  lg: [24, 2.5],
} as const;

function Spinner({
  className,
  size = "default",
  track = true,
  ...props
}: React.ComponentProps<"svg"> & {
  size?: keyof typeof sizes;
  track?: boolean;
}) {
  const [box, line] = sizes[size];
  const radius = (box - line) / 2;
  const circumference = 2 * Math.PI * radius;
  return (
    <svg
      data-slot="spinner"
      role="status"
      aria-label="Loading"
      viewBox={`0 0 ${box} ${box}`}
      width={box}
      height={box}
      className={cn("shrink-0 overflow-visible text-primary", className)}
      {...props}
    >
      {track && (
        <circle
          cx={box / 2}
          cy={box / 2}
          r={radius}
          fill="none"
          stroke="currentColor"
          strokeWidth={line}
          opacity={0.15}
        />
      )}
      <g className="origin-center animate-spin [animation-duration:900ms] motion-reduce:animate-none">
        {[
          [4, 1.6, 0.32, 110, 22],
          [2, 0.6, 0.6, 200, 9],
          [1, 0, 1, 290, 0],
        ].map(([width, blur, opacity, arc, lag]) => (
          <circle
            key={arc}
            cx={box / 2}
            cy={box / 2}
            r={radius}
            fill="none"
            stroke="currentColor"
            strokeWidth={line * width}
            opacity={opacity}
            strokeDasharray={`${(circumference * arc) / 360} ${circumference}`}
            transform={`rotate(${270 - lag - arc} ${box / 2} ${box / 2})`}
            style={{ filter: blur ? `blur(${line * blur}px)` : undefined }}
          />
        ))}
        <circle cx={box / 2} cy={line / 2} r={line / 2} fill="currentColor" />
      </g>
    </svg>
  );
}

export { Spinner };