{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "animated-button",
  "type": "registry:ui",
  "title": "Animated Button",
  "description": "AnimatedButton is a highly customizable animated button component with shimmer effects, glow, and visual styling options.",
  "author": "Ahdeetai <https://aditya.is-cool.dev>",
  "registryDependencies": [],
  "dependencies": [
    "@radix-ui/react-slot",
    "class-variance-authority",
    "clsx",
    "tailwind-merge"
  ],
  "files": [
    {
      "type": "registry:ui",
      "path": "components/ui/animated-button.tsx",
      "content": "'use client';\n\nimport * as React from 'react';\nimport { Slot } from '@radix-ui/react-slot';\nimport { cva, type VariantProps } from 'class-variance-authority';\nimport { cn } from '@/lib/utils';\n\ninterface CustomCSSProperties extends React.CSSProperties {\n  '--shimmer-color'?: string;\n  '--radius'?: string;\n  '--speed'?: string;\n  '--cut'?: string;\n  '--bg'?: string;\n  '--spread'?: string;\n  '--border-width'?: string;\n  '--border-segment'?: string;\n}\n\nconst buttonVariants = cva(\n  'group relative z-0 bg-white dark:bg-[rgba(0,0,0,1)] flex cursor-pointer items-center justify-center overflow-hidden whitespace-nowrap  transform-gpu transition-all duration-300 ease-in-out active:translate-y-px',\n  {\n    variants: {\n      variant: {\n        default: 'text-cyan-400 border border-cyan-400/20 hover:text-cyan-300',\n        outline:\n          'bg-transparent text-cyan-400 border border-cyan-400 hover:text-cyan-300',\n        ghost: 'bg-transparent text-cyan-400 hover:bg-cyan-950/30',\n        glow: 'text-cyan-400 border border-cyan-400/30 hover:text-cyan-300 hover:shadow-glow',\n      },\n      size: {\n        default: 'h-10 px-6 py-2',\n        sm: 'h-8 px-4 py-1 text-xs',\n        lg: 'h-12 px-8 py-3 text-base',\n        icon: 'h-10 w-10',\n      },\n      glow: {\n        true: 'hover:shadow-[0_0_5px_#03e9f4,0_0_25px_#03e9f4]',\n        false: '',\n      },\n      textEffect: {\n        normal: 'group-hover:tracking-normal',\n        spread: 'group-hover:tracking-wider',\n      },\n      uppercase: {\n        true: '',\n        false: '',\n      },\n      rounded: {\n        default: 'rounded-md',\n        full: 'rounded-full',\n        none: 'rounded-none',\n        custom: 'rounded-[0.95rem]',\n      },\n    },\n    defaultVariants: {\n      variant: 'default',\n      size: 'default',\n      glow: false,\n      textEffect: 'normal',\n      uppercase: true,\n      rounded: 'custom',\n    },\n  },\n);\n\nexport interface AnimatedButtonProps\n  extends\n    React.ButtonHTMLAttributes<HTMLButtonElement>,\n    VariantProps<typeof buttonVariants> {\n  asChild?: boolean;\n  hideAnimations?: boolean;\n  shimmerColor?: string;\n  shimmerSize?: string;\n  borderRadius?: string;\n  shimmerDuration?: string;\n  background?: string;\n  style?: CustomCSSProperties;\n}\n\nconst AnimatedButton = React.forwardRef<HTMLButtonElement, AnimatedButtonProps>(\n  (\n    {\n      className,\n      variant,\n      size,\n      glow,\n      textEffect,\n      uppercase,\n      rounded,\n      asChild = false,\n      hideAnimations = false,\n      shimmerColor = '#03e9f4',\n      shimmerSize = '0.05em',\n      shimmerDuration = '3s',\n      borderRadius = '100px',\n      background = 'rgba(0, 0, 0, 1)',\n      style,\n      children,\n      ...props\n    },\n    ref,\n  ) => {\n    const Comp = asChild ? Slot : 'button';\n\n    const combinedStyle: CustomCSSProperties = {\n      ...style,\n      '--shimmer-color': shimmerColor,\n      '--radius': borderRadius,\n      '--speed': shimmerDuration,\n      '--cut': shimmerSize,\n      '--bg': background,\n      '--spread': '90deg',\n      borderRadius: rounded === 'custom' ? borderRadius : undefined,\n    };\n\n    const buttonStyle = `\n      @keyframes animatedButton-shimmer-slide {\n        to {\n          transform: translate(calc(100cqw - 100%), 0);\n        }\n      }\n      \n      @keyframes animatedButton-spin-around {\n        0% {\n          transform: translateZ(0) rotate(0);\n        }\n        15%, 35% {\n          transform: translateZ(0) rotate(90deg);\n        }\n        65%, 85% {\n          transform: translateZ(0) rotate(270deg);\n        }\n        100% {\n          transform: translateZ(0) rotate(360deg);\n        }\n      }\n      \n      @keyframes animatedButton-spread {\n        0% {\n          letter-spacing: normal;\n          transform: perspective(var(--radius)) rotateY(0deg);\n        }\n        50% {\n          letter-spacing: var(--cut);\n          transform: perspective(var(--radius)) rotateY(var(--spread));\n        }\n        100% {\n          letter-spacing: normal;\n          transform: perspective(var(--radius)) rotateY(0deg);\n        }\n      }\n      \n      .animate-shimmer-slide-scoped {\n        animation: animatedButton-shimmer-slide var(--speed) ease-in-out infinite alternate;\n      }\n      \n      .animate-spin-around-scoped {\n        animation: animatedButton-spin-around calc(var(--speed) * 2) infinite linear;\n      }\n      \n      .has-animate-spread > span {\n        animation: animatedButton-spread calc(var(--speed) * 3) ease-in-out infinite;\n      }\n      \n      .shadow-glow-scoped {\n        box-shadow: 0 0 5px var(--shimmer-color),\n                    0 0 25px var(--shimmer-color),\n                    0 0 50px var(--shimmer-color);\n      }\n\n      /* Mobile optimization scoped to this component */\n      @media (max-width: 768px) {\n        .animated-button-mobile {\n          --radius: 60px;\n          --speed: 2.5s;\n          --cut: 0.03em;\n        }\n      }\n    `;\n\n    return (\n      <Comp\n        className={cn(\n          'animated-button animated-button-mobile',\n          buttonVariants({\n            variant,\n            size,\n            glow,\n            textEffect,\n            uppercase,\n            rounded,\n            className,\n          }),\n          glow && 'shadow-glow-scoped',\n        )}\n        style={combinedStyle}\n        ref={ref}\n        {...props}\n      >\n        <style jsx>{buttonStyle}</style>\n\n        {!hideAnimations && (\n          <div className='absolute inset-0 overflow-visible -z-30 blur-[2px] @container-[size]'>\n            <div className='absolute inset-0 h-[100cqh] animate-shimmer-slide-scoped aspect-[1]'>\n              <div className='absolute -inset-full w-auto rotate-0 animate-spin-around-scoped [background:conic-gradient(from_calc(270deg-(var(--spread)*0.5)),transparent_0,var(--shimmer-color)_var(--spread),transparent_var(--spread))]' />\n            </div>\n          </div>\n        )}\n\n        <div className='absolute size-full rounded-2xl px-4 py-1.5 text-sm font-medium' />\n\n        <div\n          className='absolute -z-20 [background:var(--bg)]'\n          style={{ inset: shimmerSize, borderRadius }}\n        />\n\n        <span\n          className={cn(\n            'relative z-10 transition-all duration-300 flex items-center justify-center',\n            textEffect === 'spread' && 'group-hover:tracking-wider',\n          )}\n        >\n          {children}\n        </span>\n      </Comp>\n    );\n  },\n);\n\nAnimatedButton.displayName = 'AnimatedButton';\n\nexport { AnimatedButton, buttonVariants };\n"
    },
    {
      "type": "registry:lib",
      "path": "lib/utils.ts",
      "content": "import { clsx, type ClassValue } from \"clsx\";\nimport { twMerge } from \"tailwind-merge\";\n\nexport function cn(...inputs: ClassValue[]) {\n  return twMerge(clsx(inputs));\n}"
    }
  ]
}
