{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "laugh",
  "type": "registry:ui",
  "addGlobalCss": false,
  "registryDependencies": [],
  "dependencies": [
    "motion"
  ],
  "devDependencies": [],
  "files": [
    {
      "path": "laugh-icon.tsx",
      "content": "\"use client\";\n\nimport { cn } from \"@/lib/utils\";\nimport type { Variants } from \"motion/react\";\nimport {\n LazyMotion,\n domMin,\n m,\n useAnimation,\n useReducedMotion,\n} from \"motion/react\";\nimport {\n forwardRef,\n useCallback,\n useImperativeHandle,\n useRef,\n type HTMLAttributes,\n} from \"react\";\nexport interface LaughIconHandle {\n startAnimation: () => void;\n stopAnimation: () => void;\n}\n\ninterface LaughIconProps extends Omit<\n HTMLAttributes<HTMLDivElement>,\n | \"color\"\n | \"onDrag\"\n | \"onDragStart\"\n | \"onDragEnd\"\n | \"onAnimationStart\"\n | \"onAnimationEnd\"\n | \"onAnimationIteration\"\n> {\n size?: number;\n duration?: number;\n isAnimated?: boolean;\n color?: string;\n}\n\nconst LaughIcon = forwardRef<LaughIconHandle, LaughIconProps>(\n (\n  {\n   onMouseEnter,\n   onMouseLeave,\n   className,\n   size = 24,\n   duration = 1,\n   isAnimated = true,\n   color,\n   ...props\n  },\n  ref,\n ) => {\n  const controls = useAnimation();\n  const reduced = useReducedMotion();\n  const isControlled = useRef(false);\n\n  useImperativeHandle(ref, () => {\n   isControlled.current = true;\n   return {\n    startAnimation: () =>\n     reduced ? controls.start(\"normal\") : controls.start(\"animate\"),\n    stopAnimation: () => controls.start(\"normal\"),\n   };\n  });\n\n  const handleEnter = useCallback(\n   (e?: React.MouseEvent<HTMLDivElement>) => {\n    if (!isAnimated || reduced) return;\n    if (!isControlled.current) controls.start(\"animate\");\n    else onMouseEnter?.(e as any);\n   },\n   [controls, reduced, isAnimated, onMouseEnter],\n  );\n\n  const handleLeave = useCallback(\n   (e?: React.MouseEvent<HTMLDivElement>) => {\n    if (!isControlled.current) controls.start(\"normal\");\n    else onMouseLeave?.(e as any);\n   },\n   [controls, onMouseLeave],\n  );\n\n  const featuresVariants: Variants = {\n   normal: { y: 0 },\n   animate: {\n    y: [0, -1.2, 0.6, -1.2, 0.6, 0],\n    transition: {\n     duration: 0.6 * duration,\n     ease: \"easeInOut\",\n    },\n   },\n  };\n\n  return (\n   <LazyMotion features={domMin} strict>\n    <m.div\n     className={cn(\"inline-flex items-center justify-center\", className)}\n     onMouseEnter={handleEnter}\n     onMouseLeave={handleLeave}\n     {...props}\n     style={{ color, ...props.style }}\n    >\n     <m.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      stroke=\"currentColor\"\n      strokeWidth=\"2\"\n      strokeLinecap=\"round\"\n      strokeLinejoin=\"round\"\n      animate={controls}\n      initial=\"normal\"\n     >\n      <m.g variants={featuresVariants}>\n       <path d=\"M6.99609 9.5C6.99609 8.67157 7.66767 8 8.49609 8C9.32452 8 9.99609 8.67157 9.99609 9.5M13.9961 9.5C13.9961 8.67157 14.6677 8 15.4961 8C16.3245 8 16.9961 8.67157 16.9961 9.5\" />\n       <path d=\"M13.995 14C14.9572 14 15.4383 14 15.7288 14.4902C16.0193 14.9804 15.8482 15.2929 15.506 15.9179C14.8268 17.1587 13.5091 18 11.995 18C10.4808 18 9.16308 17.1587 8.48389 15.9179C8.14173 15.2929 7.97065 14.9804 8.26114 14.4902C8.55163 14 9.03274 14 9.99495 14H13.995Z\" />\n      </m.g>\n      <circle cx=\"11.9961\" cy=\"12\" r=\"10\" />\n     </m.svg>\n    </m.div>\n   </LazyMotion>\n  );\n },\n);\n\nLaughIcon.displayName = \"LaughIcon\";\nexport { LaughIcon };\n",
      "type": "registry:ui"
    }
  ]
}