{
  "slug": "animated-button",
  "name": "Animated Button",
  "description": "Multi-variant interactive button with shimmering effects and micro-interactions.",
  "summary": "A call-to-action button with four visual styles (primary, secondary, outline and shimmer). Uses a cubic-bezier timing curve, scale-[0.96] compression on press, a shimmer overlay layer, and an arrow icon that shifts on hover.",
  "category": "buttons",
  "tags": [
    "button",
    "shimmer",
    "interaction",
    "animation",
    "cta",
    "micro-interactions"
  ],
  "dependencies": [
    "clsx",
    "tailwind-merge",
    "@radix-ui/react-icons"
  ],
  "version": "1.0.0",
  "createdDate": "2026-09-10",
  "updatedDate": "2026-09-10",
  "interactive": true,
  "supportsColor": true,
  "highlights": [
    "Four production-ready visual variants tuned for dark-mode interfaces",
    "Shimmer overlay layer for the shimmer variant (requires a shimmer keyframe in your global CSS to animate)",
    "Tactile cubic-bezier timing curve (cubic-bezier(0.16, 1, 0.3, 1)) for snappy feedback",
    "Forwarded ref support with full HTML button attribute inheritance",
    "Automatic hover translation on accessory directional icons with group-hover"
  ],
  "anatomy": [
    "<button> (Interactive container with overflow containment)",
    "<span> (Shimmer overlay layer, animate-[shimmer_2s_infinite])",
    "<span> (Content Shell housing label and optional icon)",
    "<ArrowRightIcon> (Directional icon with hover translate-x animation)"
  ],
  "physics": {
    "engine": "CSS Hardware-Accelerated Transforms",
    "description": "High-frequency micro-interactions utilizing CSS cubic-bezier timing curves and scale compression on click.",
    "parameters": [
      {
        "label": "Timing Curve",
        "value": "cubic-bezier(0.16, 1, 0.3, 1)"
      },
      {
        "label": "Active Compression",
        "value": "scale-[0.96] (4% scale down)"
      },
      {
        "label": "Shimmer",
        "value": "animate-[shimmer_2s_infinite] (needs a shimmer keyframe in global CSS)"
      },
      {
        "label": "Transition Duration",
        "value": "200ms"
      },
      {
        "label": "Icon Translation",
        "value": "+4px translateX on hover"
      },
      {
        "label": "Rendering Layer",
        "value": "GPU composited transform"
      }
    ]
  },
  "accessibility": {
    "role": "button",
    "aria": "Inherits native HTMLButtonElement attributes including aria-disabled, aria-label, and aria-pressed.",
    "reducedMotion": "No reduced-motion handling. The press scale and hover icon shift always run.",
    "keyboard": [
      {
        "key": "Tab",
        "description": "Focus the button (browser default focus outline)."
      },
      {
        "key": "Enter / Space",
        "description": "Trigger button onClick event with active compression effect."
      }
    ]
  },
  "guidelines": {
    "recommended": [
      "Primary conversion CTAs on landing page heroes and product announcements",
      "Form submission actions in checkout, modal, and onboarding flows",
      "Interactive navigation links requiring elevated visual priority"
    ],
    "bestPractices": [
      "Limit the shimmer variant to 1 instance per viewport to preserve visual hierarchy",
      "Use outline or secondary variants for auxiliary actions like Cancel or Dismiss",
      "Always provide descriptive text children or an aria-label for icon-only usage"
    ]
  },
  "props": [
    {
      "name": "variant",
      "type": "\"primary\" | \"secondary\" | \"outline\" | \"shimmer\"",
      "defaultValue": "\"primary\"",
      "description": "Visual style variant of the button: high-contrast white primary, dark secondary, bordered outline, or luminous shimmer."
    },
    {
      "name": "showArrow",
      "type": "boolean",
      "defaultValue": "false",
      "description": "Display an animated arrow icon on hover with smooth translateX translation."
    },
    {
      "name": "disabled",
      "type": "boolean",
      "defaultValue": "false",
      "description": "Disables pointer interactions, suppresses hover transforms, and lowers opacity."
    },
    {
      "name": "type",
      "type": "\"button\" | \"submit\" | \"reset\"",
      "defaultValue": "\"button\"",
      "description": "Native HTML button behavior for forms and dialogs."
    },
    {
      "name": "className",
      "type": "string",
      "defaultValue": "undefined",
      "description": "Additional CSS classes to override dimensions, paddings, or font weights."
    },
    {
      "name": "children",
      "type": "React.ReactNode",
      "required": true,
      "defaultValue": "undefined",
      "description": "Content label, icons, or badges rendered inside the button."
    },
    {
      "name": "onClick",
      "type": "(event: React.MouseEvent<HTMLButtonElement>) => void",
      "defaultValue": "undefined",
      "description": "Click event handler callback invoked on button press."
    }
  ],
  "usage": "import { AnimatedButton } from \"@/components/ui/animated-button\";\n\nexport function AnimatedButtonDemo() {\n  return (\n    <AnimatedButton variant=\"primary\" showArrow>\n      Get started\n    </AnimatedButton>\n  );\n}",
  "files": [
    {
      "name": "animated-button.tsx",
      "path": "registry/ui/animated-button.tsx",
      "code": "\"use client\";\n\nimport React from \"react\";\nimport { cn } from \"@/lib/utils\";\nimport { ArrowRightIcon } from \"@radix-ui/react-icons\";\n\nexport interface AnimatedButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {\n  variant?: \"primary\" | \"secondary\" | \"outline\" | \"shimmer\";\n  showArrow?: boolean;\n}\n\nexport const AnimatedButton = React.forwardRef<\n  HTMLButtonElement,\n  AnimatedButtonProps\n>(\n  (\n    { className, children, variant = \"primary\", showArrow = false, ...props },\n    ref,\n  ) => {\n    return (\n      <button\n        ref={ref}\n        className={cn(\n          \"group relative inline-flex items-center justify-center gap-2 rounded-lg px-5 py-2.5 text-xs font-medium tracking-wide transition-all duration-200 cursor-pointer select-none overflow-hidden ease-[cubic-bezier(0.16,1,0.3,1)]\",\n          variant === \"primary\" &&\n            \"bg-zinc-900 text-white hover:bg-zinc-800 dark:bg-white dark:text-black dark:font-medium dark:hover:bg-zinc-200 active:scale-[0.96] shadow-sm\",\n          variant === \"secondary\" &&\n            \"bg-zinc-100 border border-zinc-200 text-zinc-900 hover:bg-zinc-200 dark:bg-zinc-900 dark:border-white/15 dark:text-zinc-100 dark:hover:bg-zinc-800 dark:hover:border-white/30 active:scale-[0.96]\",\n          variant === \"outline\" &&\n            \"border border-zinc-300 text-zinc-700 hover:border-zinc-500 hover:bg-zinc-100 hover:text-zinc-900 dark:border-white/20 dark:text-zinc-300 dark:hover:border-white/50 dark:hover:bg-white/5 dark:hover:text-white active:scale-[0.96]\",\n          variant === \"shimmer\" &&\n            \"border border-zinc-300 bg-white text-zinc-900 hover:border-zinc-500 dark:border-white/20 dark:bg-black dark:text-zinc-100 dark:hover:border-white/50 active:scale-[0.96]\",\n          className,\n        )}\n        {...props}\n      >\n        {variant === \"shimmer\" && (\n          <span className=\"absolute inset-0 -translate-x-full animate-[shimmer_2s_infinite] bg-[linear-gradient(90deg,transparent,rgba(0,0,0,0.08),transparent)] dark:bg-[linear-gradient(90deg,transparent,rgba(255,255,255,0.15),transparent)] pointer-events-none\" />\n        )}\n        <span className=\"relative z-10 flex items-center gap-2\">\n          {children}\n          {showArrow && (\n            <ArrowRightIcon className=\"h-3.5 w-3.5 transition-transform duration-200 ease-[cubic-bezier(0.16,1,0.3,1)] group-hover:translate-x-1\" />\n          )}\n        </span>\n      </button>\n    );\n  },\n);\n\nAnimatedButton.displayName = \"AnimatedButton\";\n",
      "content": "\"use client\";\n\nimport React from \"react\";\nimport { cn } from \"@/lib/utils\";\nimport { ArrowRightIcon } from \"@radix-ui/react-icons\";\n\nexport interface AnimatedButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {\n  variant?: \"primary\" | \"secondary\" | \"outline\" | \"shimmer\";\n  showArrow?: boolean;\n}\n\nexport const AnimatedButton = React.forwardRef<\n  HTMLButtonElement,\n  AnimatedButtonProps\n>(\n  (\n    { className, children, variant = \"primary\", showArrow = false, ...props },\n    ref,\n  ) => {\n    return (\n      <button\n        ref={ref}\n        className={cn(\n          \"group relative inline-flex items-center justify-center gap-2 rounded-lg px-5 py-2.5 text-xs font-medium tracking-wide transition-all duration-200 cursor-pointer select-none overflow-hidden ease-[cubic-bezier(0.16,1,0.3,1)]\",\n          variant === \"primary\" &&\n            \"bg-zinc-900 text-white hover:bg-zinc-800 dark:bg-white dark:text-black dark:font-medium dark:hover:bg-zinc-200 active:scale-[0.96] shadow-sm\",\n          variant === \"secondary\" &&\n            \"bg-zinc-100 border border-zinc-200 text-zinc-900 hover:bg-zinc-200 dark:bg-zinc-900 dark:border-white/15 dark:text-zinc-100 dark:hover:bg-zinc-800 dark:hover:border-white/30 active:scale-[0.96]\",\n          variant === \"outline\" &&\n            \"border border-zinc-300 text-zinc-700 hover:border-zinc-500 hover:bg-zinc-100 hover:text-zinc-900 dark:border-white/20 dark:text-zinc-300 dark:hover:border-white/50 dark:hover:bg-white/5 dark:hover:text-white active:scale-[0.96]\",\n          variant === \"shimmer\" &&\n            \"border border-zinc-300 bg-white text-zinc-900 hover:border-zinc-500 dark:border-white/20 dark:bg-black dark:text-zinc-100 dark:hover:border-white/50 active:scale-[0.96]\",\n          className,\n        )}\n        {...props}\n      >\n        {variant === \"shimmer\" && (\n          <span className=\"absolute inset-0 -translate-x-full animate-[shimmer_2s_infinite] bg-[linear-gradient(90deg,transparent,rgba(0,0,0,0.08),transparent)] dark:bg-[linear-gradient(90deg,transparent,rgba(255,255,255,0.15),transparent)] pointer-events-none\" />\n        )}\n        <span className=\"relative z-10 flex items-center gap-2\">\n          {children}\n          {showArrow && (\n            <ArrowRightIcon className=\"h-3.5 w-3.5 transition-transform duration-200 ease-[cubic-bezier(0.16,1,0.3,1)] group-hover:translate-x-1\" />\n          )}\n        </span>\n      </button>\n    );\n  },\n);\n\nAnimatedButton.displayName = \"AnimatedButton\";\n",
      "type": "registry:ui",
      "target": "@ui/animated-button.tsx"
    }
  ],
  "type": "registry:ui",
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "title": "Animated Button"
}
