{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "book-icon",
  "dependencies": ["motion"],
  "devDependencies": [],
  "registryDependencies": [],
  "files": [
    {
      "path": "icons/book-icon.tsx",
      "content": "import { forwardRef, useImperativeHandle } from \"react\";\nimport type { AnimatedIconHandle, AnimatedIconProps } from \"./types\";\nimport { scaledStrokeWidth } from \"./types\";\nimport { motion, useAnimate } from \"motion/react\";\n\nconst BookIcon = forwardRef<AnimatedIconHandle, AnimatedIconProps>(\n  (\n    { size = 24, color = \"currentColor\", strokeWidth = 2, className = \"\" },\n    ref,\n  ) => {\n    const [scope, animate] = useAnimate();\n\n    const start = async () => {\n      await animate(\n        \".book-line\",\n        { pathLength: 0, opacity: 0 },\n        { duration: 0 },\n      );\n\n      await animate(\n        \".book-line-1\",\n        { pathLength: [0, 1], opacity: [0, 1] },\n        { duration: 0.3, ease: \"easeInOut\", delay: 0.1 },\n      );\n\n      await animate(\n        \".book-line-2\",\n        { pathLength: [0, 1], opacity: [0, 1] },\n        { duration: 0.3, ease: \"easeInOut\", delay: 0.05 },\n      );\n\n      await animate(\n        \".book-line-3\",\n        { pathLength: [0, 1], opacity: [0, 1] },\n        { duration: 0.3, ease: \"easeInOut\", delay: 0.05 },\n      );\n    };\n\n    const stop = () => {\n      animate(\".book-line\", { pathLength: 1, opacity: 1 }, { duration: 0.2 });\n    };\n\n    useImperativeHandle(ref, () => {\n      return {\n        startAnimation: start,\n        stopAnimation: stop,\n      };\n    });\n\n    const handleHoverStart = () => {\n      start();\n    };\n\n    const handleHoverEnd = () => {\n      stop();\n    };\n\n    return (\n      <motion.div\n        ref={scope}\n        onHoverStart={handleHoverStart}\n        onHoverEnd={handleHoverEnd}\n        className={`inline-flex cursor-pointer ${className}`}\n      >\n        <svg\n          xmlns=\"http://www.w3.org/2000/svg\"\n          width={size}\n          height={size}\n          viewBox=\"0 0 48 48\"\n          fill=\"none\"\n          stroke={color}\n          strokeWidth={scaledStrokeWidth(strokeWidth, 48)}\n          strokeMiterlimit=\"10\"\n          strokeLinecap=\"square\"\n        >\n          <motion.path className=\"book-spine\" d=\"M24 40.5V41L24 10V10.5\" />\n\n          <motion.path\n            className=\"book-cover\"\n            style={{ transformOrigin: \"24px 25px\" }}\n            d=\"M24 41C31.0005 36.9995 37.9995 36.9995 45 41V10.0003C37.9995 5.99989 31.0005 5.99989 24 10.0003C16.9995 5.99989 10.0005 5.99989 3 10.0003V41C10.0005 36.9995 16.9995 36.9995 24 41Z\"\n          />\n\n          <motion.path\n            className=\"book-line book-line-1\"\n            d=\"M30 16.5C32.8362 15.1345 36.5662 15.06 39.5 16.2763\"\n          />\n\n          <motion.path\n            className=\"book-line book-line-2\"\n            d=\"M30 23.5832C32.8362 22.2178 36.5662 22.1432 39.5 23.3596\"\n          />\n\n          <motion.path\n            className=\"book-line book-line-3\"\n            d=\"M30 30.6665C32.8362 29.301 36.5662 29.2265 39.5 30.4428\"\n          />\n        </svg>\n      </motion.div>\n    );\n  },\n);\n\nBookIcon.displayName = \"BookIcon\";\n\nexport default BookIcon;\n",
      "type": "registry:ui"
    },
    {
      "path": "icons/types.ts",
      "content": "import type { SVGProps } from \"react\";\n\n/** Standard stroke width for 24×24 outline icons */\nexport const DEFAULT_STROKE_WIDTH = 2;\n\n/** Scale stroke to match DEFAULT_STROKE_WIDTH on non-24 viewBoxes */\nexport function scaledStrokeWidth(\n  strokeWidth: number,\n  viewBoxSize: number,\n): number {\n  return strokeWidth * (viewBoxSize / 24);\n}\n\nexport type IconEasing =\n  | \"linear\"\n  | \"easeIn\"\n  | \"easeOut\"\n  | \"easeInOut\"\n  | \"circIn\"\n  | \"circOut\"\n  | \"circInOut\"\n  | \"backIn\"\n  | \"backOut\"\n  | \"backInOut\"\n  | \"anticipate\";\n\nexport interface AnimatedIconProps extends Omit<\n  SVGProps<SVGSVGElement>,\n  | \"ref\"\n  | \"onAnimationStart\"\n  | \"onAnimationEnd\"\n  | \"onAnimationIteration\"\n  | \"onDrag\"\n  | \"onDragEnd\"\n  | \"onDragEnter\"\n  | \"onDragExit\"\n  | \"onDragLeave\"\n  | \"onDragOver\"\n  | \"onDragStart\"\n  | \"onDrop\"\n  | \"values\"\n> {\n  /** Icon size in pixels or CSS string */\n  size?: number | string;\n  /** Icon color (defaults to currentColor) */\n  color?: string;\n  /** SVG stroke width */\n  strokeWidth?: number;\n  /** Additional CSS classes */\n  className?: string;\n}\n\nexport interface AnimatedIconHandle {\n  startAnimation: () => void;\n  stopAnimation: () => void;\n}\n",
      "type": "registry:ui"
    }
  ],
  "type": "registry:ui"
}
