Spinner

PreviousNext

A customizable spinner component

Docs
pureuiui

Preview

Loading preview…
registry/pure-ui/ui/spinner/index.tsx
"use client";

import { SVGProps } from "react";
import { tv, type VariantProps } from "tailwind-variants";
import { cn } from "@/lib/classes";

interface SpinnerPrimitiveProps extends SVGProps<SVGSVGElement> {}

function SpinnerPrimitive({ className, ...props }: SpinnerPrimitiveProps) {
  return (
    <svg
      xmlns="http://www.w3.org/2000/svg"
      viewBox="0 0 24 24"
      className={cn("size-full", className)}
      {...props}
    >
      <path
        fill="currentColor"
        d="M12,1A11,11,0,1,0,23,12,11,11,0,0,0,12,1Zm0,19a8,8,0,1,1,8-8A8,8,0,0,1,12,20Z"
        opacity=".25"
      />
      <path
        fill="currentColor"
        d="M10.14,1.16a11,11,0,0,0-9,8.92A1.59,1.59,0,0,0,2.46,12,1.52,1.52,0,0,0,4.11,10.7a8,8,0,0,1,6.66-6.61A1.42,1.42,0,0,0,12,2.69h0A1.57,1.57,0,0,0,10.14,1.16Z"
      >
        <animateTransform
          attributeName="transform"
          dur="7s"
          repeatCount="indefinite"
          type="rotate"
          values="0 12 12;360 12 12"
        />
      </path>
    </svg>
  );
}

const spinnerVariants = tv({
  base: `pointer-events-none relative size-6 inline-block animate-spin animation-duration-[0.75s] text-current`,
  variants: {
    size: {
      sm: `size-4`,
      md: `size-6`,
      lg: `size-8`,
      xl: `size-10`,
    },
  },
  defaultVariants: {
    size: `md`,
  },
});

interface SpinnerRootProps
  extends Omit<React.ComponentProps<"svg">, "display" | "opacity" | "color">,
    VariantProps<typeof spinnerVariants> {}

function Spinner({ size = "md", ...props }: SpinnerRootProps) {
  return (
    <span
      data-slot="spinner"
      className={cn(
        "in-data-[slot='toast-content']:size-5!",
        spinnerVariants({
          size,
        })
      )}
    >
      <SpinnerPrimitive
        aria-hidden
        aria-label="Loading"
        role="presentation"
        {...props}
      />
    </span>
  );
}

export { Spinner };

Installation

npx shadcn@latest add @pureui/spinner

Usage

import { Spinner } from "@/components/ui/spinner"
<Spinner />