# Spinner Variants ## Purpose `spinnerVariants` is the cva config that powers the `` chassis component. It exposes a `size` axis (`sm` / `default` / `lg`) using Tailwind's `size-*` shorthand so the rendered diameter changes in lockstep with width and height. The base classes establish the circular shape, the transparent top-edge that creates the "spinning arc" illusion, and the `motion-safe:animate-spin` gating that disables the rotation for users with `prefers-reduced-motion: reduce`. The variants module sits in its own file so an ejected source copy under `npx shadcn@latest add @suaveplan/spinner` keeps the cva config separate from the component logic, matching the upstream shadcn convention and easing per-project customisation without touching the JSX. ## Features - Single `size` axis with three rungs (`sm` 16px, `default` 20px, `lg` 32px) using Tailwind `size-*`. - Border thickness scales with size — 2px for `sm`/`default`, 3px for `lg` — keeping the arc visually proportional. - `motion-safe:animate-spin` + `motion-reduce:animate-none` so reduced-motion users see a static circle. - Border colour inherits via `border-current` so consumers can recolour the spinner with a single `text-*` utility. ## Usage: Basic Example ```tsx import { spinnerVariants } from "@suaveplan/react-ui"; const small = spinnerVariants({ size: "sm" }); const large = spinnerVariants({ size: "lg" }); ``` ## Usage: Advanced Example ```tsx import { cva } from "class-variance-authority"; import { spinnerVariants } from "@suaveplan/react-ui"; const customSpinner = cva( [spinnerVariants({ size: "default" }), "text-emerald-500"].join(" ") ); ``` ## API Reference ### `spinnerVariants(opts?)` | Option | Type | Default | Description | |---|---|---|---| | `size` | `"sm" \| "default" \| "lg"` | `"default"` | Diameter — uses Tailwind `size-*` to set width and height together. | Returns the merged class string. ## Implementation Notes - The `border-t-transparent` rule is what creates the "missing arc" illusion that reads as motion when the element rotates. Without it the spinner would be a solid ring with no visual rotation. - `text-foreground/60` is applied at the cva level so the spinner renders with a subtle muted colour by default. Consumers override with any `text-*` utility (`text-primary`, `text-emerald-500`, etc.). - The spinner deliberately does not register `display`-related classes — `inline-block` is hard-coded so the spinner sits inline with adjacent text inside a Button without being affected by the Button's `flex` context.