{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "stars",
  "type": "registry:component",
  "title": "Stars",
  "author": "Toby Belhome",
  "description": "A minimalist animated stars background component for React. It creates a smooth and subtle starfield animation behind your content, perfect for landing pages, portfolios, or any section that needs a cosmic touch.",
  "dependencies": [],
  "registryDependencies": [
    "button",
    "http://localhost:3000/r/stars.json"
  ],
  "files": [
    {
      "path": "examples/motion/backgrounds/stars/01/page.tsx",
      "content": "import { Button } from \"@/components/ui/button\";\nimport { StarsBackground } from \"./stars\";\n\nexport default function StarsBackgroundExample() {\n  return (\n    <StarsBackground className=\"flex aspect-16/9 items-center justify-center\">\n      <div className=\"z-10 space-y-4 text-center lg:space-y-6\">\n        <h4 className=\"text-2xl font-semibold text-black/80 lg:text-3xl dark:text-white/80\">\n          Bundui Components\n        </h4>\n        <Button>Discover Excellence</Button>\n      </div>\n    </StarsBackground>\n  );\n}\n",
      "type": "registry:component",
      "target": "components/stars/stars-example.tsx"
    },
    {
      "path": "examples/motion/backgrounds/stars/01/stars.tsx",
      "content": "\"use client\";\n\nimport * as React from \"react\";\nimport {\n  type HTMLMotionProps,\n  motion,\n  type SpringOptions,\n  type Transition,\n  useMotionValue,\n  useSpring\n} from \"motion/react\";\n\nimport { cn } from \"@/lib/utils\";\n\nconst lightModeStyles = {\n  \"--star-color-dark\": \"#fff\",\n  \"--star-color-light\": \"#000\",\n  \"--bg-color-start-dark\": \"#262626\",\n  \"--bg-color-end-dark\": \"#000\",\n  \"--bg-color-start-light\": \"#ccc\",\n  \"--bg-color-end-light\": \"#fff\"\n};\n\nconst getStarColor = (isLight: boolean) => {\n  return isLight ? lightModeStyles[\"--star-color-light\"] : lightModeStyles[\"--star-color-dark\"];\n};\n\ntype StarLayerProps = HTMLMotionProps<\"div\"> & {\n  count: number;\n  size: number;\n  transition: Transition;\n  isLight: boolean;\n};\n\nfunction generateStars(count: number, starColor: string) {\n  const shadows: string[] = [];\n  for (let i = 0; i < count; i++) {\n    const x = Math.floor(Math.random() * 4000) - 2000;\n    const y = Math.floor(Math.random() * 4000) - 2000;\n    shadows.push(`${x}px ${y}px ${starColor}`);\n  }\n  return shadows.join(\", \");\n}\n\nfunction StarLayer({\n  count = 1000,\n  size = 1,\n  transition = { repeat: Infinity, duration: 50, ease: \"linear\" },\n  isLight,\n  className,\n  ...props\n}: StarLayerProps) {\n  const [boxShadow, setBoxShadow] = React.useState<string>(\"\");\n  const starColor = getStarColor(isLight);\n\n  React.useEffect(() => {\n    setBoxShadow(generateStars(count, starColor));\n  }, [count, starColor]);\n\n  return (\n    <motion.div\n      data-slot=\"star-layer\"\n      animate={{ y: [0, -2000] }}\n      transition={transition}\n      className={cn(\"absolute top-0 left-0 h-[2000px] w-full\", className)}\n      {...props}>\n      <div\n        className=\"absolute rounded-full bg-transparent\"\n        style={{\n          width: `${size}px`,\n          height: `${size}px`,\n          boxShadow: boxShadow\n        }}\n      />\n      <div\n        className=\"absolute top-[2000px] rounded-full bg-transparent\"\n        style={{\n          width: `${size}px`,\n          height: `${size}px`,\n          boxShadow: boxShadow\n        }}\n      />\n    </motion.div>\n  );\n}\n\ntype StarsBackgroundProps = React.ComponentProps<\"div\"> & {\n  factor?: number;\n  speed?: number;\n  transition?: SpringOptions;\n};\n\nexport function StarsBackground({\n  children,\n  className,\n  factor = 0.05,\n  speed = 50,\n  transition = { stiffness: 50, damping: 20 },\n  ...props\n}: StarsBackgroundProps) {\n  const offsetX = useMotionValue(1);\n  const offsetY = useMotionValue(1);\n\n  const springX = useSpring(offsetX, transition);\n  const springY = useSpring(offsetY, transition);\n\n  const handleMouseMove = React.useCallback(\n    (e: React.MouseEvent<HTMLDivElement, MouseEvent>) => {\n      const centerX = window.innerWidth / 2;\n      const centerY = window.innerHeight / 2;\n      const newOffsetX = -(e.clientX - centerX) * factor;\n      const newOffsetY = -(e.clientY - centerY) * factor;\n      offsetX.set(newOffsetX);\n      offsetY.set(newOffsetY);\n    },\n    [offsetX, offsetY, factor]\n  );\n\n  const [isLight, setIsLight] = React.useState(false);\n\n  React.useEffect(() => {\n    const checkLightMode = () => {\n      const isLightMode =\n        document.documentElement.classList.contains(\"light\") ||\n        document.documentElement.getAttribute(\"data-theme\") === \"light\";\n      setIsLight(isLightMode);\n    };\n\n    checkLightMode();\n\n    const observer = new MutationObserver(checkLightMode);\n    observer.observe(document.documentElement, {\n      attributes: true,\n      attributeFilter: [\"class\", \"data-theme\"]\n    });\n\n    return () => observer.disconnect();\n  }, []);\n\n  const bgColorStart = isLight\n    ? lightModeStyles[\"--bg-color-start-light\"]\n    : lightModeStyles[\"--bg-color-start-dark\"];\n  const bgColorEnd = isLight\n    ? lightModeStyles[\"--bg-color-end-light\"]\n    : lightModeStyles[\"--bg-color-end-dark\"];\n  const backgroundStyle = `radial-gradient(ellipse_at_bottom, ${bgColorStart} 0%, ${bgColorEnd} 100%)`;\n\n  return (\n    <div\n      data-slot=\"stars-background\"\n      className={cn(\"relative size-full overflow-hidden\", className)}\n      style={{\n        background: backgroundStyle\n      }}\n      onMouseMove={handleMouseMove}\n      {...props}>\n      <motion.div style={{ x: springX, y: springY }}>\n        <StarLayer\n          count={1000}\n          size={1}\n          transition={{ repeat: Infinity, duration: speed, ease: \"linear\" }}\n          isLight={isLight}\n        />\n        <StarLayer\n          count={400}\n          size={2}\n          transition={{\n            repeat: Infinity,\n            duration: speed * 2,\n            ease: \"linear\"\n          }}\n          isLight={isLight}\n        />\n        <StarLayer\n          count={200}\n          size={3}\n          transition={{\n            repeat: Infinity,\n            duration: speed * 3,\n            ease: \"linear\"\n          }}\n          isLight={isLight}\n        />\n      </motion.div>\n      {children}\n    </div>\n  );\n}\n",
      "type": "registry:component",
      "target": "components/stars/stars.tsx"
    }
  ],
  "meta": {
    "isPro": false
  }
}