"use client"; import { useState, useSyncExternalStore } from "react"; import { defineCatalog } from "@json-render/core"; import { schema, defineRegistry } from "@json-render/react"; import { threeComponentDefinitions, threeComponents, ThreeCanvas, } from "@json-render/react-three-fiber"; import { scenes } from "./scenes"; const catalog = defineCatalog(schema, { components: { ...threeComponentDefinitions, }, actions: {}, }); const { registry } = defineRegistry(catalog, { components: { ...threeComponents, }, }); function highlightJson(json: string): string { return json.replace( /("(?:\\.|[^"\\])*")\s*(:)|("(?:\\.|[^"\\])*")|([-+]?\d+(?:\.\d+)?(?:[eE][+-]?\d+)?)|(\btrue\b|\bfalse\b|\bnull\b)|([{}[\]:,])/g, (_, key, colon, str, num, lit, punct) => { if (key) return `${key}${colon}`; if (str) return `${str}`; if (num) return `${num}`; if (lit) return `${lit}`; if (punct) return `${punct}`; return _; }, ); } const MOBILE_BREAKPOINT = 768; function subscribeToResize(cb: () => void) { window.addEventListener("resize", cb); return () => window.removeEventListener("resize", cb); } function getIsMobile() { return typeof window !== "undefined" ? window.innerWidth < MOBILE_BREAKPOINT : false; } function useIsMobile() { return useSyncExternalStore(subscribeToResize, getIsMobile, () => false); } const LIST_WIDTH = 220; const JSON_WIDTH = 380; const HEADER_HEIGHT = 40; const headerStyle: React.CSSProperties = { height: HEADER_HEIGHT, display: "flex", alignItems: "center", padding: "0 16px", fontSize: 11, fontWeight: 600, color: "#555", letterSpacing: "0.08em", textTransform: "uppercase", fontFamily: "ui-monospace, monospace", borderBottom: "1px solid #1e1e1e", flexShrink: 0, whiteSpace: "nowrap", overflow: "hidden", textOverflow: "ellipsis", boxSizing: "border-box", }; function DesktopLayout() { const [selectedIndex, setSelectedIndex] = useState(0); const selected = scenes[selectedIndex]!; return (
Scenes
{scenes.map((scene, i) => ( ))}
{selected.description}
Spec JSON
      
); } function MobileLayout() { const [selectedIndex, setSelectedIndex] = useState(0); const [showJson, setShowJson] = useState(false); const [showScenes, setShowScenes] = useState(false); const selected = scenes[selectedIndex]!; return (
{selected.description}
{showScenes && ( <>
setShowScenes(false)} style={{ position: "absolute", inset: 0, background: "rgba(0,0,0,0.5)", zIndex: 10, }} />
Scenes
{scenes.map((scene, i) => ( ))}
)} {showJson && ( <>
setShowJson(false)} style={{ position: "absolute", inset: 0, background: "rgba(0,0,0,0.5)", zIndex: 10, }} />
Spec JSON
            
)}
); } export default function Page() { const isMobile = useIsMobile(); return isMobile ? : ; }