Mount an editor
The honest minimum: register a node type, add one, frame it. Xen is the default theme — no setup.
{
"version": "xenolith.v1",
"nodes": [
{
"id": "greeter",
"type": "Greeter",
"position": {
"x": 0,
"y": 0
},
"render": {
"title": "Greeter"
},
"state": {
"msg": "Hello, Xenolith"
},
"pins": [
{
"id": "greeter:out",
"kind": "data",
"direction": "out",
"type": "string",
"multiple": true,
"label": "Out"
}
],
"widgets": [
{
"id": "msg",
"type": "text",
"key": "msg",
"label": "Message",
"freeFloating": true
}
]
}
],
"edges": []
} import { XenolithGraph } from '@xenolithengine/graph-react'
import { buildMount } from '@xenolithengine/demo/mount'
import { DemoStage } from '../Layout.js'
/** Island: the honest minimum — Xen is the default theme; load one node (mount.json) and frame it. */
export function MountDemo() {
return (
<DemoStage>
<XenolithGraph className="xeno" resizeToWindow={false} onReady={(editor) => buildMount(editor)} />
</DemoStage>
)
} // The honest minimum: no theme (Xen is the default), one node, framed. The node is DATA (mount.json)
// loaded with editor.loadJSON — the smallest possible xenolith.v1 graph.
import type { XenolithEditor } from '@xenolithengine/graph-editor'
import graph from './mount.json'
export function buildMount(editor: XenolithEditor): void {
editor.loadJSON(graph)
editor.fitView({ padding: 80, maxZoom: 1 })
} <script setup lang="ts">
// Vue 3 SFC — the honest minimum: load one node, frame it. Xen is the default theme.
import { XenolithGraph } from '@xenolithengine/graph-vue'
import { buildMount } from '@xenolithengine/demo/mount'
</script>
<template>
<div class="app" style="position:absolute;inset:0;">
<XenolithGraph class="xeno" :resize-to-window="false" @ready="buildMount" />
</div>
</template> // The honest minimum: no theme (Xen is the default), one node, framed. The node is DATA (mount.json)
// loaded with editor.loadJSON — the smallest possible xenolith.v1 graph.
import type { XenolithEditor } from '@xenolithengine/graph-editor'
import graph from './mount.json'
export function buildMount(editor: XenolithEditor): void {
editor.loadJSON(graph)
editor.fitView({ padding: 80, maxZoom: 1 })
} <!-- Svelte 5 — the honest minimum: the use:xenolith action mounts the editor, on:ready hands
you the live editor for one-shot seed work (register, insert, frame). -->
<script lang="ts">
import { xenolith } from '@xenolithengine/graph-svelte'
import { buildMount } from '@xenolithengine/demo/mount'
</script>
<div
use:xenolith={{ resizeToWindow: false }}
on:ready={(e) => buildMount(e.detail)}
style="position:absolute;inset:0"
></div> // The honest minimum: no theme (Xen is the default), one node, framed. The node is DATA (mount.json)
// loaded with editor.loadJSON — the smallest possible xenolith.v1 graph.
import type { XenolithEditor } from '@xenolithengine/graph-editor'
import graph from './mount.json'
export function buildMount(editor: XenolithEditor): void {
editor.loadJSON(graph)
editor.fitView({ padding: 80, maxZoom: 1 })
} // Solid — the honest minimum: the use:xenolith directive mounts the editor; on:ready (colon
// names are native in Solid) hands you the live editor for one-shot seed work.
import { xenolith } from '@xenolithengine/graph-solid'
import { buildMount } from '@xenolithengine/demo/mount'
export function MountDemo() {
return (
<div
use:xenolith={{ resizeToWindow: false }}
on:ready={(e) => buildMount(e.detail)}
style="position:absolute;inset:0"
/>
)
} // The honest minimum: no theme (Xen is the default), one node, framed. The node is DATA (mount.json)
// loaded with editor.loadJSON — the smallest possible xenolith.v1 graph.
import type { XenolithEditor } from '@xenolithengine/graph-editor'
import graph from './mount.json'
export function buildMount(editor: XenolithEditor): void {
editor.loadJSON(graph)
editor.fitView({ padding: 80, maxZoom: 1 })
} // Angular standalone host component — mount. Provides the XenolithGraphService per editor,
// mounts into a #host div from ngAfterViewInit, and does the imperative seed work on the
// resolved editor. The host component is YOURS — compiled by your Angular CLI; the adapter
// ships no components (Angular libraries need ng-packagr partial compilation), only the
// decorator-free service.
import { AfterViewInit, Component, ElementRef, OnDestroy, inject, viewChild } from '@angular/core'
import { XenolithGraphService } from '@xenolithengine/graph-angular'
import { buildMount } from '@xenolithengine/demo/mount'
@Component({
selector: 'mount-demo',
standalone: true,
providers: [XenolithGraphService],
template: `
<div class="app" style="position:absolute;inset:0;">
<div #host class="xeno" style="position:absolute;inset:0;"></div>
</div>
`,
})
export class MountDemoComponent implements AfterViewInit, OnDestroy {
private graph = inject(XenolithGraphService)
private host = viewChild.required<ElementRef<HTMLDivElement>>('host')
async ngAfterViewInit(): Promise<void> {
const editor = await this.graph.mount(this.host().nativeElement, { resizeToWindow: false })
buildMount(editor)
}
ngOnDestroy(): void { this.graph.destroy() }
} // The honest minimum: no theme (Xen is the default), one node, framed. The node is DATA (mount.json)
// loaded with editor.loadJSON — the smallest possible xenolith.v1 graph.
import type { XenolithEditor } from '@xenolithengine/graph-editor'
import graph from './mount.json'
export function buildMount(editor: XenolithEditor): void {
editor.loadJSON(graph)
editor.fitView({ padding: 80, maxZoom: 1 })
}