Import these from @grafloria/renderer.
Functions
camelToKebab
camelCase → kebab-case (strokeWidth → stroke-width).
tsfunction camelToKebab(str: string): string
createDomElement
Build a fresh detached DOM tree for vnode using the default patcher.
tsfunction createDomElement(vnode: VNode, namespace: string = SVG_NS): Element
createForeignObject
Create a foreignObject VNode
Creates a VNode representing an SVG foreignObject element, which allows embedding HTML content inside SVG. Automatically generates a container ID if not provided, and includes a default XHTML div wrapper.
tsfunction createForeignObject(options: ForeignObjectOptions): VNode
Parameters
options: Configuration options for the foreignObject
Returns A VNode of type 'foreignObject'
Example
typescriptconst vnode = createForeignObject({
nodeId: 'node-1',
x: 10,
y: 20,
width: 200,
height: 150
});
// Returns: { type: 'foreignObject', props: { x: 10, y: 20, ... }, children: [...] }
Example
With custom container ID and children
typescriptconst vnode = createForeignObject({
nodeId: 'node-1',
x: 10,
y: 20,
width: 200,
height: 150,
containerId: 'my-custom-id',
children: [
{ type: 'div', props: { className: 'custom-content' } }
]
});
getContainerId
Get the container ID from a foreignObject VNode
Extracts the container ID from a foreignObject VNode's props. Returns undefined if the VNode is not a foreignObject or doesn't have a container ID.
tsfunction getContainerId(vnode: VNode): string | undefined
Parameters
vnode: The VNode to extract the container ID from
Returns The container ID if the VNode is a foreignObject, undefined otherwise
Example
typescriptconst vnode = createForeignObject({
nodeId: 'node-1',
x: 0, y: 0, width: 100, height: 100
});
const containerId = getContainerId(vnode);
// Returns: 'fo-node-1-1'
Example
Non-foreignObject returns undefined
typescriptconst rectNode = { type: 'rect', props: { ... } };
const containerId = getContainerId(rectNode);
// Returns: undefined
isForeignObject
Check if a VNode is a foreignObject element
Type guard function that checks if the given VNode represents a foreignObject element.
tsfunction isForeignObject(vnode: VNode): boolean
Parameters
vnode: The VNode to check
Returns True if the VNode is a foreignObject, false otherwise
Example
typescriptconst foNode = createForeignObject({ ... });
const rectNode = { type: 'rect', props: { ... } };
isForeignObject(foNode); // true
isForeignObject(rectNode); // false
isOpaqueVNode
foreignObject subtrees embed live HTML (framework components, form controls, media). They are OPAQUE to the diff: props are patched, children are left exactly as they are. Diffing into them would wipe whatever was mounted there.
tsfunction isOpaqueVNode(vnode: VNode): boolean
reconcile
Reconcile vnode into container using the default patcher.
tsfunction reconcile(container: Element, vnode: VNode): Element
serializeStyle
Serialize a style prop. Accepts the object form the renderer emits
({ cursor: 'move' }) as well as a plain string. Returns '' for empty/absent styles.
tsfunction serializeStyle(style: unknown): string
Classes
ContainerIdGenerator
Generate unique container IDs for foreignObject elements
tsclass ContainerIdGenerator
Methods
static generate(nodeId: string): string(static) — Generate a unique container ID for a foreignObject elementstatic isContainerId(id: string): boolean(static) — Check if a given ID is a valid container IDstatic getNodeId(containerId: string): string | null(static) — Extract the node ID from a container IDstatic reset(): void(static) — Reset the internal counter to zero
VNodePatcher
Keyed VNode → DOM reconciler.
tsconst patcher = new VNodePatcher();
patcher.reconcile(container, vnodeTree); // first call: mount
patcher.reconcile(container, nextTree); // later calls: diff + patch in place
tsclass VNodePatcher
Methods
constructor(options: VNodePatcherOptions = {})get stats(): Readonly<PatchStats>— Work done during the most recentreconcile()call.reconcile(container: Element, vnode: VNode): Element— Diffvnodeagainst whatever this patcher last rendered intocontainerand patch the existing DOM in place. First call (or a lost root) mounts a fresh tree.hydrate(container: Element, vnode: VNode): Element— ADOPT the DOM already insidecontaineras the materialization ofvnode, without creating, moving or removing a single node.getMountedElement(container: Element): Element | undefined— The root element currently mounted incontainer, if any.unmount(container: Element): void— Remove the mounted tree and forget the container.createElement(vnode: VNode, namespace: string = SVG_NS): Element— Build a fresh detached DOM element (deep) for a VNode.patchElement(el: Element, oldVNode: VNode, newVNode: VNode): Element— Diff two VNodes onto an existing element.patchProps( el: Element, oldProps: Record<string, any>, newProps: Record<string, any> ): void— Apply a prop delta to an element (no children touched).
Constants
defaultPatcher
Process-wide default patcher — convenient for the common "one DOM, one tree"
case. Instantiate VNodePatcher directly for isolated instances.
tsconst defaultPatcher: VNodePatcher
SVG_NS
SVG namespace — everything outside a foreignObject is created here.
tsconst SVG_NS: "http://www.w3.org/2000/svg"
XHTML_NS
XHTML namespace — foreignObject children are HTML, not SVG.
tsconst XHTML_NS: "http://www.w3.org/1999/xhtml"
Interfaces
ForeignObjectOptions
Options for creating a foreignObject VNode
tsinterface ForeignObjectOptions
Properties
| Name | Type | Default | Description |
|---|---|---|---|
nodeId | string | ||
x | number | X coordinate (top-left corner) | |
y | number | Y coordinate (top-left corner) | |
width | number | Width in pixels | |
height | number | Height in pixels | |
containerId? | string | Optional custom container ID If not provided, will be auto-generated using ContainerIdGenerator | |
children? | VNode[] | Optional children VNodes If not provided, creates a default XHTML div wrapper | |
key? | string | Optional key for React/Angular diffing optimization |
PatchStats
Per-reconcile work counters. Reset at the top of every reconcile() call. Useful as a cheap regression guard: a steady-state frame should create ~0
elements ("no teardown-and-rebuild").
tsinterface PatchStats
Properties
| Name | Type | Default | Description |
|---|---|---|---|
created | number | DOM nodes created from scratch. | |
reused | number | DOM nodes reused in place (patched, not recreated). | |
moved | number | Reused DOM nodes that had to move to a new sibling index. | |
removed | number | DOM nodes removed because their VNode disappeared. | |
skipped | number | Subtrees skipped entirely because the VNode object was identical. |
VNodePatcherOptions
Options for a patcher instance.
tsinterface VNodePatcherOptions
Properties
| Name | Type | Default | Description |
|---|---|---|---|
document? | Document |
Types
VNodeChild
A child slot in a VNode tree. Strings/numbers materialise as text nodes.
tstype VNodeChild = VNode | string | number | null | undefined;
Members
toString(): string— Returns a string representation of a string.valueOf(): string— Returns the primitive value of the specified object.toLocaleString(): string— Returns a date converted to a string using the current locale.
Was this page helpful?