{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "demo-perspective-flow",
  "title": "Perspective Flow Demo",
  "description": "Demo showing the Perspective Flow component.",
  "registryDependencies": [
    "@unlumen-ui/perspective-flow"
  ],
  "files": [
    {
      "path": "registry/demo/components/unlumen/perspective-flow/index.tsx",
      "content": "\"use client\";\n\nimport { useEffect, useMemo, useRef, useState } from \"react\";\nimport Lenis from \"lenis\";\n\nimport {\n  PerspectiveFlow,\n  type PerspectiveFlowProps,\n} from \"@/components/unlumen-ui/perspective-flow\";\n\ntype PerspectiveFlowDemoProps = Pick<\n  PerspectiveFlowProps,\n  \"engine\" | \"perspective\" | \"gap\" | \"verticalGap\" | \"minItemWidth\"\n> & {\n  imageCount?: number;\n  smooth?: boolean;\n};\n\nexport default function PerspectiveFlowDemo({\n  engine = \"gsap\",\n  perspective = 2000,\n  gap = 32,\n  verticalGap = 92,\n  minItemWidth = 170,\n  imageCount = 24,\n  smooth = true,\n}: PerspectiveFlowDemoProps) {\n  const scrollContainerRef = useRef<HTMLDivElement>(null);\n  const contentRef = useRef<HTMLDivElement>(null);\n  const [previewWidth, setPreviewWidth] = useState(900);\n\n  useEffect(() => {\n    const node = scrollContainerRef.current;\n    if (!node) return;\n\n    const update = () => setPreviewWidth(node.clientWidth || 900);\n    update();\n\n    const observer = new ResizeObserver(update);\n    observer.observe(node);\n\n    return () => observer.disconnect();\n  }, []);\n\n  useEffect(() => {\n    const wrapper = scrollContainerRef.current;\n    const content = contentRef.current;\n    if (!smooth || !wrapper || !content) return;\n\n    const lenis = new Lenis({\n      wrapper,\n      content,\n      smoothWheel: true,\n      wheelMultiplier: 0.95,\n      lerp: 0.09,\n    });\n\n    let rafId = 0;\n    const raf = (time: number) => {\n      lenis.raf(time);\n      rafId = window.requestAnimationFrame(raf);\n    };\n\n    rafId = window.requestAnimationFrame(raf);\n\n    return () => {\n      window.cancelAnimationFrame(rafId);\n      lenis.destroy();\n    };\n  }, [smooth]);\n\n  const images = useMemo(() => {\n    const availableWidth = Math.max(320, previewWidth);\n    const estimatedColumns = Math.max(\n      1,\n      Math.min(2, Math.round(availableWidth / (minItemWidth + 30))),\n    );\n    const targetWidth = Math.max(\n      260,\n      Math.round(\n        (availableWidth - (estimatedColumns - 1) * 24) / estimatedColumns,\n      ),\n    );\n    const targetHeight = Math.round(targetWidth * 1.2);\n\n    return Array.from({ length: imageCount }, (_, i) => ({\n      src: `https://picsum.photos/seed/ps${i + 1}/${targetWidth}/${targetHeight}`,\n      alt: `Demo image ${i + 1}`,\n    }));\n  }, [imageCount, minItemWidth, previewWidth]);\n\n  const reloadKey = useMemo(\n    () =>\n      [\n        engine,\n        perspective,\n        gap,\n        verticalGap ?? \"\",\n        minItemWidth,\n        imageCount,\n        smooth,\n      ].join(\"|\"),\n    [engine, perspective, gap, verticalGap, minItemWidth, imageCount, smooth],\n  );\n\n  return (\n    <div ref={scrollContainerRef} className=\"h-full w-full overflow-y-auto\">\n      <div ref={contentRef}>\n        <div className=\"spacer h-40\" />\n        <PerspectiveFlow\n          key={reloadKey}\n          images={images}\n          engine={engine}\n          perspective={perspective}\n          maxWidth=\"100%\"\n          gap={gap}\n          verticalGap={verticalGap}\n          minItemWidth={minItemWidth}\n          scrollContainerRef={scrollContainerRef}\n        />\n      </div>\n    </div>\n  );\n}\n",
      "type": "registry:ui",
      "target": "components/unlumen-ui/demo/components/unlumen/perspective-flow.tsx"
    }
  ],
  "type": "registry:ui"
}