{"$schema":"https://ui.shadcn.com/schema/registry-item.json","author":"Eduardo Calvo <edu@smoothui.dev>","css":{},"dependencies":["motion"],"description":"Accessible loading Spinner for SmoothUI with Motion and reduced-motion support.","devDependencies":[],"files":[{"content":"\"use client\";\n\nimport { cn } from \"@/lib/utils\";\nimport { motion, useReducedMotion } from \"motion/react\";\nimport { type ComponentProps, useCallback, useRef } from \"react\";\nimport {\n  EASE_LINEAR,\n  LOOP_CLASS,\n  LOOP_REPEAT_DELAY,\n  loopTransition,\n  useLoopInView,\n} from \"@/components/smoothui/lib/animation\";\n\nexport type SpinnerSize = \"sm\" | \"md\" | \"lg\";\n\nexport interface SpinnerProps extends Omit<ComponentProps<\"span\">, \"children\"> {\n  /** Accessible name when no visible label is shown */\n  \"aria-label\"?: string;\n  /** Visual size */\n  size?: SpinnerSize;\n}\n\nconst SIZE_CLASS: Record<SpinnerSize, string> = {\n  lg: \"size-6 border-2\",\n  md: \"size-4 border-2\",\n  sm: \"size-3 border-[1.5px]\",\n};\n\n/**\n * SmoothUI Spinner — indeterminate loading indicator. SmoothUI-owned.\n */\nexport default function Spinner({\n  \"aria-label\": ariaLabel = \"Loading\",\n  className,\n  ref,\n  size = \"md\",\n  ...props\n}: SpinnerProps) {\n  const shouldReduceMotion = useReducedMotion();\n  const hostRef = useRef<HTMLSpanElement>(null);\n  const inView = useLoopInView(hostRef);\n  const setRef = useCallback(\n    (node: HTMLSpanElement | null) => {\n      hostRef.current = node;\n      if (typeof ref === \"function\") {\n        ref(node);\n      } else if (ref) {\n        ref.current = node;\n      }\n    },\n    [ref]\n  );\n  const spinning = !shouldReduceMotion && inView;\n\n  return (\n    <span\n      aria-label={ariaLabel}\n      className={cn(\"inline-flex shrink-0 text-foreground\", className)}\n      data-slot=\"spinner\"\n      ref={setRef}\n      role=\"status\"\n      {...props}\n    >\n      <motion.span\n        animate={spinning ? { rotate: 360 } : undefined}\n        aria-hidden\n        className={cn(\n          \"inline-block rounded-full border-current border-r-transparent\",\n          spinning && LOOP_CLASS,\n          SIZE_CLASS[size]\n        )}\n        transition={\n          spinning\n            ? loopTransition(\n                { duration: 0.7, ease: EASE_LINEAR },\n                LOOP_REPEAT_DELAY.spin\n              )\n            : { duration: 0 }\n        }\n      />\n    </span>\n  );\n}\n","path":"index.tsx","target":"components/smoothui/spinner/index.tsx","type":"registry:ui"}],"name":"spinner","registryDependencies":["https://smoothui.dev/r/lib.json"],"title":"Spinner","type":"registry:ui"}