{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "sparkles-text",
  "title": "Sparkles Text",
  "author": "Ballmac <https://ui.ballmac.com>",
  "description": "Text with four-point stars that twinkle around it in theme colors, re-rolling position each time, with an optional gradient fill.",
  "dependencies": [
    "motion@^12"
  ],
  "registryDependencies": [
    "utils"
  ],
  "files": [
    {
      "path": "registry/ballmac/components/sparkles-text.tsx",
      "content": "// Ballmac UI: Sparkles Text. https://ui.ballmac.com/components/sparkles-text\n\"use client\"\n\nimport * as React from \"react\"\nimport { motion, useReducedMotion } from \"motion/react\"\n\nimport { cn } from \"@/lib/utils\"\n\nconst TONES = [\"var(--chart-1)\", \"var(--chart-2)\", \"var(--chart-3)\", \"var(--chart-4)\", \"var(--chart-5)\"]\n\ntype Spark = { id: number; x: number; y: number; size: number; tone: string; duration: number; delay: number }\n\nfunction makeSpark(id: number): Spark {\n  return {\n    id,\n    x: Math.random() * 110 - 5,\n    y: Math.random() * 120 - 10,\n    size: 12 + Math.random() * 14,\n    tone: TONES[Math.floor(Math.random() * TONES.length)]!,\n    duration: 1.4 + Math.random() * 1.2,\n    delay: Math.random() * 1.2,\n  }\n}\n\nfunction Star({ spark, onDone }: { spark: Spark; onDone: (id: number) => void }) {\n  return (\n    <motion.svg\n      aria-hidden=\"true\"\n      viewBox=\"0 0 24 24\"\n      className=\"pointer-events-none absolute\"\n      style={{ left: `${spark.x}%`, top: `${spark.y}%`, width: spark.size, height: spark.size, marginLeft: -spark.size / 2, marginTop: -spark.size / 2, color: spark.tone }}\n      initial={{ scale: 0, rotate: 0, opacity: 0 }}\n      animate={{ scale: [0, 1, 0], rotate: [0, 90, 180], opacity: [0, 1, 0] }}\n      transition={{ duration: spark.duration, delay: spark.delay, ease: \"easeInOut\" }}\n      onAnimationComplete={() => onDone(spark.id)}\n    >\n      <path d=\"M12 0c.6 6.4 5 11.4 12 12-7 .6-11.4 5.6-12 12-.6-6.4-5-11.4-12-12 7-.6 11.4-5.6 12-12Z\" fill=\"currentColor\" />\n    </motion.svg>\n  )\n}\n\ntype SparklesTextProps = Omit<React.ComponentProps<\"span\">, \"children\"> & {\n  /** The text to decorate. */\n  children: React.ReactNode\n  /** How many sparkles twinkle at once. */\n  count?: number\n  /** Show a soft gradient fill on the text itself. */\n  gradient?: boolean\n}\n\nfunction SparklesText({ children, count = 8, gradient = false, className, ...props }: SparklesTextProps) {\n  const reduce = useReducedMotion()\n  const [sparks, setSparks] = React.useState<Spark[]>([])\n  const next = React.useRef(0)\n\n  // Random positions can only be picked after mount, or the server and browser would disagree.\n  React.useEffect(() => {\n    if (reduce) return setSparks([])\n    setSparks(Array.from({ length: count }, () => makeSpark(next.current++)))\n  }, [count, reduce])\n\n  const replace = React.useCallback((id: number) => {\n    setSparks((all) => all.map((s) => (s.id === id ? makeSpark(next.current++) : s)))\n  }, [])\n\n  return (\n    <span data-slot=\"sparkles-text\" className={cn(\"relative inline-block\", className)} {...props}>\n      <span\n        className={cn(gradient && \"bg-[linear-gradient(90deg,var(--foreground),color-mix(in_oklab,var(--chart-4)_60%,var(--foreground)),var(--foreground))] bg-clip-text text-transparent\")}\n      >\n        {children}\n      </span>\n      {sparks.map((s) => (\n        <Star key={s.id} spark={s} onDone={replace} />\n      ))}\n    </span>\n  )\n}\n\nexport { SparklesText, type SparklesTextProps }\n",
      "type": "registry:ui",
      "target": "@components/ballmac/sparkles-text.tsx"
    }
  ],
  "meta": {
    "schema": 1,
    "tier": "free",
    "tags": [
      "text",
      "sparkle",
      "stars",
      "twinkle",
      "marketing"
    ],
    "version": "1.0.0",
    "updated": "2026-10-01",
    "ai": {
      "summary": "<SparklesText count gradient>Text</SparklesText>. Sparkles are decorative and positioned after mount, so the server markup stays identical.",
      "whenToUse": [
        "One standout word in a marketing headline",
        "Celebratory states such as a new plan or achievement"
      ],
      "whenNotToUse": [
        "Dense UI",
        "More than one or two per screen"
      ],
      "composesWith": [
        "gradient-text",
        "confetti",
        "shimmer-text"
      ],
      "a11y": [
        {
          "keys": "Screen readers",
          "action": "Sparkles are aria-hidden and pointer-events-none; the text is untouched"
        },
        {
          "keys": "Reduced motion",
          "action": "No sparkles are drawn"
        }
      ],
      "customization": [
        "count",
        "gradient",
        "className for size and weight"
      ]
    },
    "examples": [
      "sparkles-text-demo",
      "sparkles-text-gradient"
    ],
    "url": "https://ui.ballmac.com/components/sparkles-text"
  },
  "categories": [
    "text"
  ],
  "type": "registry:ui"
}