import { useEffect, useState, type ComponentType } from "react"; import { modules as discoveredModules } from "./.generated/mockup-components"; type ModuleMap = Record Promise>>; function _resolveComponent( mod: Record, name: string, ): ComponentType | undefined { const fns = Object.values(mod).filter( (v) => typeof v === "function", ) as ComponentType[]; return ( (mod.default as ComponentType) || (mod.Preview as ComponentType) || (mod[name] as ComponentType) || fns[fns.length - 1] ); } function PreviewRenderer({ componentPath, modules, }: { componentPath: string; modules: ModuleMap; }) { const [Component, setComponent] = useState(null); const [error, setError] = useState(null); useEffect(() => { let cancelled = false; setComponent(null); setError(null); async function loadComponent(): Promise { const key = `./components/mockups/${componentPath}.tsx`; const loader = modules[key]; if (!loader) { setError(`No component found at ${componentPath}.tsx`); return; } try { const mod = await loader(); if (cancelled) { return; } const name = componentPath.split("/").pop()!; const comp = _resolveComponent(mod, name); if (!comp) { setError( `No exported React component found in ${componentPath}.tsx\n\nMake sure the file has at least one exported function component.`, ); return; } setComponent(() => comp); } catch (e) { if (cancelled) { return; } const message = e instanceof Error ? e.message : String(e); setError(`Failed to load preview.\n${message}`); } } void loadComponent(); return () => { cancelled = true; }; }, [componentPath, modules]); if (error) { return (
        {error}
      
); } if (!Component) return null; return ; } function getBasePath(): string { return import.meta.env.BASE_URL.replace(/\/$/, ""); } function getPreviewExamplePath(): string { const basePath = getBasePath(); return `${basePath}/preview/ComponentName`; } function Gallery() { return (

Component Preview Server

This server renders individual components for the workspace canvas.

Access component previews at{" "} {getPreviewExamplePath()}

); } function getPreviewPath(): string | null { const basePath = getBasePath(); const { pathname } = window.location; const local = basePath && pathname.startsWith(basePath) ? pathname.slice(basePath.length) || "/" : pathname; const match = local.match(/^\/preview\/(.+)$/); return match ? match[1] : null; } function App() { const previewPath = getPreviewPath(); if (previewPath) { return ( ); } return ; } export default App;