Renderer DOM API
The Renderer DOM API provides the rendering layer that converts models to DOM using VNode reconciliation.
DOMRenderer Class
The main renderer class that manages DOM rendering with VNode reconciliation.
Constructor
new DOMRenderer(registry?: RendererRegistry, options?: DOMRendererOptions)
Parameters:
registry?: RendererRegistry- Optional renderer registryoptions?: DOMRendererOptions- Optional renderer options
Options:
interface DOMRendererOptions {
enableSelectionPreservation?: boolean; // Enable selection-preserving TextNodePool
name?: string; // Renderer name for debugging
dataStore?: DataStore; // DataStore instance for getting model data
}
Example:
import { DOMRenderer } from '@barocss/renderer-dom';
import { getGlobalRegistry } from '@barocss/dsl';
const registry = getGlobalRegistry();
const renderer = new DOMRenderer(registry, {
name: 'content',
enableSelectionPreservation: true
});
Methods
render(container, model, decorators?, runtime?, selection?, options?): void
Renders model to container (main entry point).
Parameters:
container: HTMLElement- Root container elementmodel: ModelData- Model data (must havestypeproperty)decorators?: Decorator[]- Array of decorators to apply (default:[])runtime?: Record<string, any>- Runtime context (e.g.,{ dataStore })selection?: SelectionContext- Selection context for text node preservationoptions?: { onComplete?: () => void }- Render options
Behavior:
- Builds complete VNode tree from model
- Reconciles VNode tree to container
- Pattern decorators are automatically generated
- Preserves selection if provided
Example:
renderer.render(
container,
{
sid: 'doc-1',
stype: 'document',
content: ['p-1']
},
[],
{ dataStore },
{
textNode: textNode,
restoreSelection: (textNode, offset) => {
// Restore selection
},
model: { sid: 'text-1', modelOffset: 5 }
},
{
onComplete: () => {
console.log('Render complete');
}
}
);
renderContent(container, model, decorators?, runtime?, selection?): void
Renders content area with optional selection preservation.
Parameters:
container: HTMLElement- Root containermodel: ModelData- Content modeldecorators?: Decorator[]- Decorators for contentruntime?: Record<string, any>- Runtime contextselection?: SelectionContext- Selection context
Behavior:
- Similar to
render()but optimized for content layer - Injects selection context and pool when
enableSelectionPreservation=true
Example:
renderer.renderContent(
contentLayer,
model,
decorators,
{ dataStore },
{
textNode: textNode,
restoreSelection: (textNode, offset) => {
// Restore selection
}
}
);
renderChildren(container, models, runtime?, selection?): void
Renders children models directly into container (no root element).
Parameters:
container: HTMLElement- Parent container elementmodels: ModelData[]- Array of ModelData to render as childrenruntime?: Record<string, any>- Runtime contextselection?: SelectionContext- Selection context
Behavior:
- Used for layer rendering (decorator, selection, context, custom)
- Renders multiple models as children without root element
Example:
renderer.renderChildren(
decoratorLayer,
[
{ sid: 'decorator-1', stype: 'highlight', ... },
{ sid: 'decorator-2', stype: 'comment', ... }
],
{ dataStore }
);
build(model, decorators?): VNode
Builds VNode from model and decorators.
Parameters:
model: ModelData- Model data (must havestypeproperty)decorators?: Decorator[]- Array of decorators (default:[])
Returns:
VNode- Built VNode ready for rendering
Example:
const vnode = renderer.build({
sid: 'p-1',
stype: 'paragraph',
text: 'Hello'
}, []);
getInstance(sid: string): ComponentInstance | undefined
Gets component instance by sid.
Parameters:
sid: string- Component sid (Model ID)
Returns:
ComponentInstance | undefined- Component instance orundefined
Example:
const instance = renderer.getInstance('text-1');
if (instance) {
instance.setState({ count: 5 });
}
updateDecoratorsBySid(sid: string, decorators: Decorator[]): boolean
Updates decorators for a specific sid.
Parameters:
sid: string- Component siddecorators: Decorator[]- New decorators
Returns:
boolean-trueif successful
Example:
const updated = renderer.updateDecoratorsBySid('text-1', [
{ sid: 'highlight-1', stype: 'highlight', ... }
]);
unmountBySid(sid: string): boolean
Unmounts a specific sid host and its component.
Parameters:
sid: string- Component sid
Returns:
boolean-trueif successful
Example:
const unmounted = renderer.unmountBySid('node-1');
moveBySid(sid: string, newParentSid: string, targetIndex?: number): boolean
Moves a component host by sid under a new parent host.
Parameters:
sid: string- Component sid to movenewParentSid: string- New parent sidtargetIndex?: number- Target index (default:-1for end)
Returns:
boolean-trueif successful
Behavior:
- DOM-level move with minimal reconcile
- Avoids cycles
Example:
const moved = renderer.moveBySid('node-1', 'parent-2', 0);
getRegistry(): RendererRegistry
Gets the renderer registry.
Returns:
RendererRegistry- Renderer registry instance
getInstanceId(): string
Gets DOMRenderer instance ID (for debugging).
Returns:
string- Instance ID
getReconcilerInstanceId(): string
Gets Reconciler instance ID (for debugging).
Returns:
string- Reconciler instance ID
getPatternDecoratorGenerator(): PatternDecoratorGenerator
Gets pattern decorator generator (for external configuration).
Returns:
PatternDecoratorGenerator- Pattern decorator generator
getComponentManager(): ComponentManager
Gets ComponentManager (for DOM Query optimization).
Returns:
ComponentManager- Component manager instance
getCurrentVNode(): VNode | null
Gets current VNode.
Returns:
VNode | null- Current VNode ornull
getVNodeSnapshotBySid(sid: string): VNode | undefined
Gets VNode snapshot by sid (for testing/diagnostics).
Parameters:
sid: string- Component sid
Returns:
VNode | undefined- VNode snapshot orundefined
clearCache(): void
Clears caches.
destroy(): void
Destroys renderer instance.
Behavior:
- Clears current VNode
- Clears root element
- Clears cache
Component State Management
defineState(stype, StateClass)
Defines a state class for a component type.
Parameters:
stype: string- Component typeStateClass: new (...args: any[]) => T- State class constructor
Example:
import { defineState, BaseComponentState } from '@barocss/renderer-dom';
class MyComponentState extends BaseComponentState {
getCount(): number {
return this.get('count') || 0;
}
setCount(count: number): void {
this.set({ count });
}
}
defineState('my-component', MyComponentState);
BaseComponentState Class
Base class for component state management.
Constructor
new BaseComponentState(initial?: Record<string, any>, options?: {
componentManager?: ComponentManager;
sid?: string;
})
Methods
init(initial: Record<string, any>): void
Initializes state.
Parameters:
initial: Record<string, any>- Initial state values
set(patch: Record<string, any>): void
Sets state values (patches).
Parameters:
patch: Record<string, any>- State patch
Behavior:
- Merges patch into existing state
- Emits
changeStateevent if componentManager and sid available - Prevents setState during reconciliation
Example:
state.set({ count: 5, visible: true });
get<T = any>(key: string): T
Gets state value.
Parameters:
key: string- State key
Returns:
T- State value
Example:
const count = state.get<number>('count');
snapshot(): Record<string, any>
Gets state snapshot.
Returns:
Record<string, any>- State snapshot (copy)
Example:
const snapshot = state.snapshot();
VNode Types
VNode Interface
interface VNode {
tag?: string; // HTML tag or component name
text?: string | number; // Text content (for text nodes)
attrs?: Record<string, any>; // Element attributes
style?: Record<string, any>; // Inline styles
children?: (string | number | VNode)[]; // Child nodes
key?: string; // Key for efficient reconciliation
sid?: string; // Schema ID (for component-generated VNodes)
stype?: string; // Schema Type (for component-generated VNodes)
props?: Record<string, any>; // Pure props (for component-generated VNodes)
isExternal?: boolean; // External component flag
portal?: {
target: HTMLElement;
template: any;
portalId?: string;
};
meta?: {
sidAutogenerated?: boolean;
[key: string]: any;
};
}
VNode Tag Constants
VNodeTag.TEXT = '#text'; // Text node
VNodeTag.PORTAL = 'portal'; // Portal node
DOM Attribute Constants
DOMAttribute.BC_SID = 'data-bc-sid'; // Component Schema ID
DOMAttribute.DECORATOR_SID = 'data-decorator-sid'; // Decorator Schema ID
DOMAttribute.DECORATOR_STYPE = 'data-decorator-stype'; // Decorator Schema Type
DOMAttribute.DECORATOR_CATEGORY = 'data-decorator-category';
DOMAttribute.DECORATOR_POSITION = 'data-decorator-position';
DOMAttribute.SKIP_RECONCILE = 'data-skip-reconcile';
DOMAttribute.DECORATOR = 'data-decorator';
Component Instance
ComponentInstance Interface
interface ComponentInstance {
element: HTMLElement; // DOM element
vnode: VNode; // Current VNode
state?: Record<string, any>; // Component state
setState?: (newState: Record<string, any>) => void; // setState method
// ... other properties
}
Access:
const instance = renderer.getInstance('text-1');
if (instance) {
// Access DOM element
const element = instance.element;
// Access state
const state = instance.state;
// Update state
instance.setState?.({ count: 5 });
}
Event System
on(event: 'changeState', handler: Function): void
Subscribes to component state change events.
Parameters:
event: 'changeState'- Event namehandler: Function- Event handler
Example:
renderer.on('changeState', (sid, data) => {
console.log('State changed:', sid, data.state, data.patch);
});
off(event: 'changeState', handler?: Function): void
Unsubscribes from component state change events.
Parameters:
event: 'changeState'- Event namehandler?: Function- Optional handler to remove (removes all if not provided)
Scheduler
The renderer uses a scheduler for efficient rendering.
Note: Scheduler is internal. Rendering is automatically scheduled when state changes.
Complete Example
import { DOMRenderer } from '@barocss/renderer-dom';
import { getGlobalRegistry } from '@barocss/dsl';
import { DataStore } from '@barocss/datastore';
// Create renderer
const registry = getGlobalRegistry();
const dataStore = new DataStore();
const renderer = new DOMRenderer(registry, {
name: 'content',
enableSelectionPreservation: true,
dataStore
});
// Render model
const container = document.getElementById('editor');
renderer.render(
container,
{
sid: 'doc-1',
stype: 'document',
content: ['p-1']
},
[], // decorators
{ dataStore }, // runtime
{
textNode: textNode,
restoreSelection: (textNode, offset) => {
const range = document.createRange();
range.setStart(textNode, offset);
range.setEnd(textNode, offset);
const selection = window.getSelection();
selection?.removeAllRanges();
selection?.addRange(range);
},
model: { sid: 'text-1', modelOffset: 5 }
},
{
onComplete: () => {
console.log('Render complete');
}
}
);
// Listen to state changes
renderer.on('changeState', (sid, data) => {
console.log('Component state changed:', sid, data);
});
// Get component instance
const instance = renderer.getInstance('text-1');
if (instance) {
instance.setState?.({ count: 5 });
}
Related
- Architecture: Renderer DOM - Renderer architecture
- Core Concepts: Rendering - Rendering concepts
- DSL API - Template DSL
- Editor View DOM API - Editor View DOM integration