{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "mouse-left-click-01",
  "title": "mouse-left-click-01",
  "description": "Animated mouse left click icon",
  "dependencies": [
    "motion"
  ],
  "files": [
    {
      "path": "icons/mouse-left-click-01.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 MouseLeftClick01IconHandle {\n  startAnimation: () => void;\n  stopAnimation: () => void;\n}\n\ninterface MouseLeftClick01IconProps extends HTMLAttributes<HTMLDivElement> {\n  size?: number;\n}\n\n// The click mark contracts as the mouse presses, then flicks back on release.\nconst clickMarkVariants: Variants = {\n  normal: { transform: 'translate(0px, 0px) scale(1)' },\n  animate: {\n    transform: [\n      'translate(0px, 0px) scale(1)',\n      'translate(1.15px, 0.45px) scale(0.82)',\n      'translate(1.15px, 0.45px) scale(0.82)',\n      'translate(-0.18px, -0.12px) scale(1.08)',\n      'translate(0px, 0px) scale(1)',\n    ],\n    transition: {\n      duration: 0.26,\n      ease: [0.23, 1, 0.32, 1],\n      times: [0, 0.5, 0.64, 0.86, 1],\n    },\n  },\n};\n\n// The complete mouse stays connected while its left side leads the downstroke.\nconst mousePressVariants: Variants = {\n  normal: {\n    transform: 'translate(0px, 0px) rotate(0deg) scaleY(1)',\n  },\n  animate: {\n    transform: [\n      'translate(0px, 0px) rotate(0deg) scaleY(1)',\n      'translate(0px, 0.2px) rotate(-1.5deg) scaleY(0.975)',\n      'translate(0px, 0.2px) rotate(-1.5deg) scaleY(0.975)',\n      'translate(0px, -0.1px) rotate(0.3deg) scaleY(1.006)',\n      'translate(0px, 0px) rotate(0deg) scaleY(1)',\n    ],\n    transition: {\n      duration: 0.26,\n      ease: [0.23, 1, 0.32, 1],\n      times: [0, 0.5, 0.64, 0.86, 1],\n    },\n  },\n};\n\nconst MouseLeftClick01Icon = forwardRef<MouseLeftClick01IconHandle, MouseLeftClick01IconProps>(\n  ({ onMouseEnter, onMouseLeave, className, size = 28, ...props }, ref) => {\n    const controls = useAnimation();\n    const { handleMouseEnter, handleMouseLeave } = useIconAnimation({\n      controls,\n      loops: false,\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=\"M5 2C3.94531 3.13158 3.23544 4.50113 3 6\"\n            stroke=\"currentColor\"\n            strokeLinecap=\"round\"\n            strokeWidth=\"1.5\"\n            variants={clickMarkVariants}\n            animate={controls}\n            initial=\"normal\"\n            style={{ originX: 1, originY: 0 }}\n          />\n          <motion.g\n            variants={mousePressVariants}\n            animate={controls}\n            initial=\"normal\"\n            style={{ originX: 1, originY: 1 }}\n          >\n            <path\n              d=\"M13.5 2L13.5 6M13.5 10L13.5 12\"\n              stroke=\"currentColor\"\n              strokeLinecap=\"round\"\n              strokeLinejoin=\"round\"\n              strokeWidth=\"1.5\"\n            />\n            <path\n              d=\"M12 7.5C12 7.03406 12 6.80109 12.0761 6.61732C12.1776 6.37229 12.3723 6.17761 12.6173 6.07612C12.8011 6 13.0341 6 13.5 6C13.9659 6 14.1989 6 14.3827 6.07612C14.6277 6.17761 14.8224 6.37229 14.9239 6.61732C15 6.80109 15 7.03406 15 7.5V8.5C15 8.96594 15 9.19891 14.9239 9.38268C14.8224 9.62771 14.6277 9.82239 14.3827 9.92388C14.1989 10 13.9659 10 13.5 10C13.0341 10 12.8011 10 12.6173 9.92388C12.3723 9.82239 12.1776 9.62771 12.0761 9.38268C12 9.19891 12 8.96594 12 8.5V7.5Z\"\n              stroke=\"currentColor\"\n              strokeWidth=\"1.5\"\n            />\n            <path\n              d=\"M6.24061 17.0888C6.43047 19.4803 8.32417 21.511 10.765 21.8118C11.6626 21.9223 12.5752 22 13.5 22C14.4247 22 15.3373 21.9223 16.2349 21.8118C18.6758 21.511 20.5694 19.4803 20.7593 17.0888C20.8909 15.4317 21 13.732 21 12C21 10.268 20.8909 8.56832 20.7593 6.91118C20.5694 4.51965 18.6758 2.48893 16.2349 2.1882C15.3373 2.07762 14.4247 2 13.5 2C12.5752 2 11.6626 2.07762 10.765 2.1882C8.32417 2.48893 6.43047 4.51965 6.24061 6.91118C6.10903 8.56832 6 10.268 6 12C6 13.732 6.10903 15.4317 6.24061 17.0888Z\"\n              stroke=\"currentColor\"\n              strokeWidth=\"1.5\"\n            />\n          </motion.g>\n        </svg>\n      </div>\n    );\n  }\n);\n\nMouseLeftClick01Icon.displayName = 'MouseLeftClick01Icon';\n\nexport { MouseLeftClick01Icon };\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"
}