{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "fire",
  "title": "fire",
  "description": "Animated fire icon",
  "dependencies": [
    "motion"
  ],
  "files": [
    {
      "path": "icons/fire.tsx",
      "content": "'use client';\n\nimport type { Variants } from 'motion/react';\nimport { motion, useAnimation } from 'motion/react';\nimport type { HTMLAttributes } from 'react';\nimport { forwardRef } from 'react';\nimport { useIconAnimation } from '@/lib/use-icon-animation';\nimport { cn } from '@/lib/utils';\n\nexport interface FireIconHandle {\n  startAnimation: () => void;\n  stopAnimation: () => void;\n}\n\ninterface FireIconProps extends HTMLAttributes<HTMLDivElement> {\n  size?: number;\n}\n\nconst FLAME_REST =\n  'M13.8561 22C26.0783 19 19.2338 7 10.9227 2C9.9453 5.5 8.47838 6.5 5.54497 10C1.66121 14.6339 3.5895 20 8.96719 22C8.1524 21 6.04958 18.9008 7.5 16C8 15 9 14 8.5 12C9.47778 12.5 11.5 13 12 15.5C12.8148 14.5 13.6604 12.4 12.8783 10C19 14.5 16.5 19 13.8561 22Z';\nconst FLAME_LEAN_LEFT =\n  'M13.8561 22C25.4 19.2 18.4 7.2 9.65 2.15C8.75 5.7 7.65 6.8 4.9 10.45C1.7 14.8 3.6 20 8.96719 22C8.15 21 6.15 18.65 7.65 16.15C8.35 15.1 9.4 14.15 8.85 12.45C9.65 12.9 11.45 13.35 11.9 15.85C12.75 14.7 13.35 12.8 12.55 10.55C18.2 14.8 16.1 19.15 13.8561 22Z';\nconst FLAME_LIFT =\n  'M13.8561 22C26.15 19.05 19.55 5.7 11.25 1.1C10.6 4.9 9.4 6.25 6.05 9.85C1.66121 14.6339 3.5895 20 8.96719 22C8.1524 21 6.35 18.85 7.65 16.05C8.25 14.9 9.15 13.9 8.7 11.8C9.65 12.45 11.55 13.1 12 15.55C12.85 14.4 13.45 12.15 12.7 9.65C19.1 14.15 16.7 18.85 13.8561 22Z';\nconst FLAME_LEAN_RIGHT =\n  'M13.8561 22C26.5 18.45 20.15 6.45 12.25 1.6C10.5 5.15 8.9 6.1 5.9 9.55C1.66121 14.6339 3.5895 20 8.96719 22C8.1524 21 5.9 19.05 7.3 15.65C7.8 14.75 8.7 13.65 8.2 11.45C9.3 12.05 11.55 12.65 12.1 15.1C12.95 14.05 13.95 11.95 13.2 9.45C19.65 14.05 16.8 18.75 13.8561 22Z';\nconst FLAME_QUICK =\n  'M13.8561 22C26.2 19.1 19.95 6.7 12.05 1.35C10.95 5 9.4 6.25 6.1 9.65C1.66121 14.6339 3.5895 20 8.96719 22C8.1524 21 6.2 18.9 7.55 16.15C8.2 15 9.1 14.05 8.55 12.05C9.45 12.55 11.2 13.05 11.95 15.45C12.8 14.2 13.75 12.15 12.55 10C18.7 14.4 16.45 19 13.8561 22Z';\n\nconst flameVariants: Variants = {\n  normal: {\n    originX: '50%',\n    originY: '100%',\n    d: FLAME_REST,\n    transform: 'translate(0px, 0px) scaleY(1)',\n  },\n  animate: {\n    originX: '50%',\n    originY: '100%',\n    d: [\n      FLAME_REST,\n      FLAME_LEAN_LEFT,\n      FLAME_LIFT,\n      FLAME_LEAN_RIGHT,\n      FLAME_QUICK,\n      FLAME_REST,\n    ],\n    transform: [\n      'translate(0px, 0px) scaleY(1)',\n      'translate(-0.15px, 0px) scaleY(1.02)',\n      'translate(0px, -0.15px) scaleY(1.06)',\n      'translate(0.18px, 0px) scaleY(0.98)',\n      'translate(-0.05px, 0.08px) scaleY(1.01)',\n      'translate(0px, 0px) scaleY(1)',\n    ],\n    transition: {\n      duration: 1.1,\n      ease: [0.4, 0, 0.2, 1],\n      times: [0, 0.16, 0.32, 0.52, 0.72, 1],\n      repeat: Infinity,\n    },\n  },\n};\n\nconst FireIcon = forwardRef<FireIconHandle, FireIconProps>(\n  ({ onMouseEnter, onMouseLeave, className, size = 28, ...props }, ref) => {\n    const controls = useAnimation();\n    const { handleMouseEnter, handleMouseLeave } = useIconAnimation({\n      controls,\n      loops: true,\n      onMouseEnter,\n      onMouseLeave,\n      ref,\n    });\n\n    return (\n      <div\n        className={cn(className)}\n        onMouseEnter={handleMouseEnter}\n        onMouseLeave={handleMouseLeave}\n        {...props}\n      >\n        <svg\n          xmlns=\"http://www.w3.org/2000/svg\"\n          width={size}\n          height={size}\n          viewBox=\"0 0 24 24\"\n          fill=\"none\"\n          overflow=\"visible\"\n        >\n          <motion.path\n            d={FLAME_REST}\n            stroke=\"currentColor\"\n            strokeLinecap=\"round\"\n            strokeLinejoin=\"round\"\n            strokeWidth=\"1.5\"\n            variants={flameVariants}\n            animate={controls}\n            initial=\"normal\"\n            style={{ transformBox: 'fill-box', transformOrigin: '50% 100%' }}\n          />\n        </svg>\n      </div>\n    );\n  }\n);\n\nFireIcon.displayName = 'FireIcon';\n\nexport { FireIcon };\n",
      "type": "registry:ui"
    },
    {
      "path": "lib/use-icon-animation.ts",
      "content": "'use client';\n\nimport type { LegacyAnimationControls } from 'motion/react';\nimport { useReducedMotion } from 'motion/react';\nimport type {\n  ForwardedRef,\n  MouseEventHandler,\n} from 'react';\nimport { useCallback, useImperativeHandle, useRef } from 'react';\n\nexport interface AnimatedIconHandle {\n  startAnimation: () => void;\n  stopAnimation: () => void;\n}\n\ninterface UseIconAnimationOptions {\n  controls: LegacyAnimationControls;\n  loops?: boolean;\n  onMouseEnter?: MouseEventHandler<HTMLDivElement>;\n  onMouseLeave?: MouseEventHandler<HTMLDivElement>;\n  ref: ForwardedRef<AnimatedIconHandle>;\n}\n\nexport function useIconAnimation({\n  controls,\n  loops = false,\n  onMouseEnter,\n  onMouseLeave,\n  ref,\n}: UseIconAnimationOptions) {\n  const shouldReduceMotion = useReducedMotion();\n  const isControlledRef = useRef(false);\n  const isPlayingRef = useRef(false);\n  const runRef = useRef(0);\n\n  const startAnimation = useCallback(() => {\n    if (shouldReduceMotion || isPlayingRef.current) return;\n\n    isPlayingRef.current = true;\n    const run = ++runRef.current;\n    controls.set('normal');\n    void controls.start('animate').then(() => {\n      if (runRef.current === run) isPlayingRef.current = false;\n    });\n  }, [controls, shouldReduceMotion]);\n\n  const stopAnimation = useCallback(() => {\n    if (!loops) return;\n\n    runRef.current++;\n    isPlayingRef.current = false;\n    void controls.start('normal');\n  }, [controls, loops]);\n\n  useImperativeHandle(\n    ref,\n    () => {\n      isControlledRef.current = true;\n      return { startAnimation, stopAnimation };\n    },\n    [startAnimation, stopAnimation]\n  );\n\n  const handleMouseEnter = useCallback<MouseEventHandler<HTMLDivElement>>(\n    (event) => {\n      onMouseEnter?.(event);\n      if (!isControlledRef.current) startAnimation();\n    },\n    [onMouseEnter, startAnimation]\n  );\n\n  const handleMouseLeave = useCallback<MouseEventHandler<HTMLDivElement>>(\n    (event) => {\n      onMouseLeave?.(event);\n      if (!isControlledRef.current) stopAnimation();\n    },\n    [onMouseLeave, stopAnimation]\n  );\n\n  return { handleMouseEnter, handleMouseLeave };\n}\n",
      "type": "registry:lib"
    }
  ],
  "type": "registry:ui"
}