Load a graph
Load a real saved xenolith.v1 graph and reframe it. Built-in controls + a reload panel.
import { useRef } from 'react'
import { XenolithGraph, XenolithControls, XenolithPanel, XenolithButton } from '@xenolithengine/graph-react'
import type { XenolithEditor } from '@xenolithengine/graph-editor'
import { DemoStage } from '../Layout.js'
import { loadDemo, demoGraph } from '../demo-data.js'
/** Island: load a real saved xenolith.v1 graph; an in-editor panel reloads it. */
export function LoadDemo() {
const editorRef = useRef<XenolithEditor | null>(null)
return (
<DemoStage>
<XenolithGraph
className="xeno"
resizeToWindow={false}
onReady={(e) => { editorRef.current = e; loadDemo(e) }}
>
<XenolithControls position="bottom-left" />
<XenolithPanel position="top-right">
<XenolithButton onClick={() => { const e = editorRef.current; if (e) { e.loadJSON(demoGraph); e.fitView({ padding: 48, maxZoom: 1 }) } }}>
Reload graph
</XenolithButton>
</XenolithPanel>
</XenolithGraph>
</DemoStage>
)
} // The canonical shared demo scene: register the canvas custom widgets + demo node schemas, load the
// shared demo graph (xenolith.v1), and frame it. Framework-agnostic — every host (React/Vue/Svelte)
// calls this in its onReady so the registry has the schemas before loadJSON.
import { demoGraph, demoSchemas, createCurveWidget, createXYPadWidget } from './demo-graph.js'
import type { XenolithEditor } from '@xenolithengine/graph-editor'
export function loadDemo(editor: XenolithEditor): void {
editor.registerWidget('curve', createCurveWidget())
editor.registerWidget('xypad', createXYPadWidget())
for (const schema of demoSchemas) editor.registry.register(schema)
editor.loadJSON(demoGraph)
editor.fitView({ padding: 48, maxZoom: 1 })
}