import type { CodeComponentMeta } from "@plasmicapp/host"; import { useEffect, useRef, useState } from "react"; interface LazyRenderProps { className?: string; forceLoad?: boolean; forceFallback?: boolean; threshold?: number; fallback?: React.ReactNode; delay?: number; children?: React.ReactNode; onBecomesVisible?: () => void; } const DefaultFallback = () =>
asdf
; export const LazyRender: React.FC = ({ className = "", children, forceLoad = false, forceFallback = false, threshold = 0.1, delay = 0, fallback = , onBecomesVisible, }) => { const [isVisible, setIsVisible] = useState(forceLoad); const ref = useRef(null); /* console.log("props", { delay, threshold, fallback, isVisible, forceLoad, forceFallback, children, }); */ useEffect(() => { if (forceLoad || forceFallback) { setIsVisible(true); return; } const observerOptions: IntersectionObserverInit = { threshold: threshold < 1 ? threshold : 0.1, }; const observerCallback: IntersectionObserverCallback = (entries) => { entries.forEach((entry) => { if (entry.isIntersecting && !isVisible) { setTimeout(() => { setIsVisible(true); onBecomesVisible?.(); if (ref.current) observer.unobserve(ref.current); }, delay); } }); }; const observer = new IntersectionObserver(observerCallback, observerOptions); if (ref.current) observer.observe(ref.current); return () => { if (ref.current) observer.unobserve(ref.current); }; }, [forceLoad, threshold, forceFallback, delay]); return (
{isVisible && !forceFallback ? children : fallback}
); }; export const LazyRenderMeta: CodeComponentMeta> = { name: "LazyRender", importPath: import.meta.dir, props: { forceLoad: { type: "boolean", defaultValue: false, }, forceFallback: { type: "boolean", defaultValue: false, }, threshold: { type: "number", defaultValue: 0.1, }, fallback: { type: "slot", //allowedComponents: ["*"], }, delay: { type: "number", defaultValue: 0, }, onBecomesVisible: { type: "code", lang: "javascript", }, children: { type: "slot", //allowedComponents: ["*"], }, }, };