{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "icon-button",
  "type": "registry:ui",
  "title": "Icon Button",
  "description": "An icon button that displays particles when clicked.",
  "dependencies": [
    "motion"
  ],
  "files": [
    {
      "path": "registry/buttons/icon/index.tsx",
      "content": "'use client';\n\nimport * as React from 'react';\nimport {\n  motion,\n  AnimatePresence,\n  type HTMLMotionProps,\n  type Transition,\n} from 'motion/react';\n\nimport { cn } from '@/lib/utils';\n\nconst sizes = {\n  default: 'size-8 [&_svg]:size-5',\n  sm: 'size-6 [&_svg]:size-4',\n  md: 'size-10 [&_svg]:size-6',\n  lg: 'size-12 [&_svg]:size-7',\n};\n\ntype IconButtonProps = Omit<HTMLMotionProps<'button'>, 'color'> & {\n  icon: React.ElementType;\n  active?: boolean;\n  className?: string;\n  animate?: boolean;\n  size?: keyof typeof sizes;\n  color?: [number, number, number];\n  transition?: Transition;\n};\n\nfunction IconButton({\n  icon: Icon,\n  className,\n  active = false,\n  animate = true,\n  size = 'default',\n  color = [59, 130, 246],\n  transition = { type: 'spring', stiffness: 300, damping: 15 },\n  ...props\n}: IconButtonProps) {\n  return (\n    <motion.button\n      data-slot=\"icon-button\"\n      className={cn(\n        `group/icon-button cursor-pointer relative inline-flex size-10 shrink-0 rounded-full hover:bg-[var(--icon-button-color)]/10 active:bg-[var(--icon-button-color)]/20 text-[var(--icon-button-color)]`,\n        sizes[size],\n        className,\n      )}\n      whileHover={{ scale: 1.05 }}\n      whileTap={{ scale: 0.95 }}\n      style={\n        {\n          '--icon-button-color': `rgb(${color[0]}, ${color[1]}, ${color[2]})`,\n        } as React.CSSProperties\n      }\n      {...props}\n    >\n      <motion.div\n        className=\"absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 stroke-muted-foreground group-hover/icon-button:stroke-[var(--icon-button-color)]\"\n        aria-hidden=\"true\"\n      >\n        <Icon\n          className={\n            active ? 'fill-[var(--icon-button-color)]' : 'fill-transparent'\n          }\n        />\n      </motion.div>\n\n      <AnimatePresence mode=\"wait\">\n        {active && (\n          <motion.div\n            className=\"absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 text-[var(--icon-button-color)] fill-[var(--icon-button-color)]\"\n            aria-hidden=\"true\"\n            initial={{ opacity: 0, scale: 0 }}\n            animate={{ opacity: 1, scale: 1 }}\n            exit={{ opacity: 0, scale: 0 }}\n            transition={transition}\n          >\n            <Icon />\n          </motion.div>\n        )}\n      </AnimatePresence>\n\n      <AnimatePresence>\n        {animate && active && (\n          <>\n            <motion.div\n              className=\"absolute inset-0 z-10 rounded-full \"\n              style={{\n                background: `radial-gradient(circle, rgba(${color[0]}, ${color[1]}, ${color[2]}, 0.4) 0%, rgba(${color[0]}, ${color[1]}, ${color[2]}, 0) 70%)`,\n              }}\n              initial={{ scale: 1.2, opacity: 0 }}\n              animate={{ scale: [1.2, 1.8, 1.2], opacity: [0, 0.3, 0] }}\n              transition={{ duration: 1.2, ease: 'easeInOut' }}\n            />\n            <motion.div\n              className=\"absolute inset-0 z-10 rounded-full\"\n              style={{\n                boxShadow: `0 0 10px 2px rgba(${color[0]}, ${color[1]}, ${color[2]}, 0.6)`,\n              }}\n              initial={{ scale: 1, opacity: 0 }}\n              animate={{ scale: [1, 1.5], opacity: [0.8, 0] }}\n              transition={{ duration: 0.8, ease: 'easeOut' }}\n            />\n            {[...Array(6)].map((_, i) => (\n              <motion.div\n                key={i}\n                className=\"absolute w-1 h-1 rounded-full bg-[var(--icon-button-color)]\"\n                initial={{ x: '50%', y: '50%', scale: 0, opacity: 0 }}\n                animate={{\n                  x: `calc(50% + ${Math.cos((i * Math.PI) / 3) * 30}px)`,\n                  y: `calc(50% + ${Math.sin((i * Math.PI) / 3) * 30}px)`,\n                  scale: [0, 1, 0],\n                  opacity: [0, 1, 0],\n                }}\n                transition={{ duration: 0.8, delay: i * 0.05, ease: 'easeOut' }}\n              />\n            ))}\n          </>\n        )}\n      </AnimatePresence>\n    </motion.button>\n  );\n}\n\nexport { IconButton, sizes, type IconButtonProps };\n",
      "type": "registry:ui",
      "target": "components/animate-ui/buttons/icon.tsx"
    }
  ]
}