{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "shiny-button",
  "title": "Shiny Button",
  "author": "Ballmac <https://ui.ballmac.com>",
  "description": "A button with a diagonal band of light that sweeps across on hover and focus, or on a timer to draw the eye, built on the Ballmac button.",
  "dependencies": [
    "motion@^12"
  ],
  "registryDependencies": [
    "utils",
    "https://ui.ballmac.com/r/button.json"
  ],
  "files": [
    {
      "path": "registry/ballmac/components/shiny-button.tsx",
      "content": "// Ballmac UI: Shiny Button. https://ui.ballmac.com/components/shiny-button\n\"use client\"\n\nimport * as React from \"react\"\nimport { motion, useReducedMotion } from \"motion/react\"\n\nimport { Button, type ButtonProps } from \"@/components/ballmac/button\"\nimport { cn } from \"@/lib/utils\"\n\ntype ShinyButtonProps = Omit<ButtonProps, \"asChild\"> & {\n  /** \"hover\" sweeps the shine on hover and keyboard focus. \"loop\" sweeps it again every few seconds to draw the eye. */\n  shine?: \"hover\" | \"loop\"\n  /** Seconds between sweeps when `shine` is \"loop\". */\n  interval?: number\n}\n\nfunction ShinyButton({ shine = \"hover\", interval = 3.5, className, children, ...props }: ShinyButtonProps) {\n  const reduce = useReducedMotion()\n  return (\n    <Button\n      data-slot=\"shiny-button\"\n      className={cn(\"group/shiny overflow-hidden\", className)}\n      {...props}\n    >\n      {children}\n      {!reduce && (\n        <span aria-hidden=\"true\" className=\"pointer-events-none absolute inset-0 overflow-hidden rounded-[inherit]\">\n          {shine === \"loop\" ? (\n            <motion.span\n              className=\"absolute inset-y-0 -start-1/3 w-1/3 -skew-x-[20deg] bg-gradient-to-r from-transparent via-white/40 to-transparent dark:via-black/20\"\n              animate={{ x: [\"0%\", \"450%\"] }}\n              transition={{ duration: 0.9, ease: \"easeInOut\", repeat: Infinity, repeatDelay: interval }}\n            />\n          ) : (\n            <span className=\"absolute inset-y-0 -start-1/3 w-1/3 -skew-x-[20deg] bg-gradient-to-r from-transparent via-white/40 to-transparent transition-transform duration-700 ease-out group-hover/shiny:translate-x-[450%] group-focus-visible/shiny:translate-x-[450%] rtl:skew-x-[20deg] rtl:group-hover/shiny:-translate-x-[450%] rtl:group-focus-visible/shiny:-translate-x-[450%] dark:via-black/20\" />\n          )}\n        </span>\n      )}\n    </Button>\n  )\n}\n\nexport { ShinyButton, type ShinyButtonProps }\n",
      "type": "registry:ui",
      "target": "@components/ballmac/shiny-button.tsx"
    }
  ],
  "meta": {
    "schema": 1,
    "tier": "free",
    "tags": [
      "button",
      "shine",
      "hover",
      "cta",
      "motion"
    ],
    "version": "1.0.0",
    "updated": "2026-10-01",
    "ai": {
      "summary": "<ShinyButton shine='hover|loop' interval>Label</ShinyButton>. Accepts every Button prop. No shine under reduced motion.",
      "whenToUse": [
        "Primary calls to action that deserve a little life",
        "Pricing and signup buttons"
      ],
      "whenNotToUse": [
        "Dense toolbars",
        "Destructive actions"
      ],
      "composesWith": [
        "button",
        "rainbow-button",
        "magnetic-button"
      ],
      "a11y": [
        {
          "keys": "Enter / Space",
          "action": "Activates like any button"
        },
        {
          "keys": "Reduced motion",
          "action": "No shine is drawn"
        }
      ],
      "customization": [
        "shine",
        "interval",
        "all Button props"
      ]
    },
    "examples": [
      "shiny-button-demo",
      "shiny-button-variants"
    ],
    "url": "https://ui.ballmac.com/components/shiny-button"
  },
  "categories": [
    "motion"
  ],
  "type": "registry:ui"
}