Skip to main content

@barocss/editor-view-react

The Editor-View-React package provides the React view layer for Barocss Editor. It connects the Editor to the DOM through React components, handling user input, selection synchronization, decorator management, and rendering via ReactRenderer.

Purpose

React view layer for Barocss Editor (Editor + ReactRenderer). Bridges user interactions (typing, clicking, keyboard shortcuts) with editor commands, all rendered as a React component tree.

Key Exports

  • EditorView - Main React component (with static sub-components: ContentLayer, DecoratorLayer, SelectionLayer, ContextLayer, CustomLayer, Layer)
  • EditorViewContentLayer - Content layer component (contenteditable)
  • EditorViewLayer - Generic overlay layer component
  • EditorViewContextProvider - Context provider managing editor state, handlers, and decorator managers
  • useEditorViewContext - Hook to access the editor view context (throws if outside provider)
  • useOptionalEditorViewContext - Hook that returns null if outside provider
  • createMutationObserverManager - Factory for the React mutation observer manager

Types

  • EditorViewOptions - Options for EditorView (registry, className, layers config)
  • EditorViewProps - Props for EditorView (editor, options, children)
  • EditorViewRef / EditorViewHandle - Ref API type (addDecorator, removeDecorator, getDecorators, selection conversion, etc.)
  • DecoratorExportData - Serializable decorator export format
  • LoadDecoratorsPatternFunctions - Functions required when loading pattern decorators
  • DecoratorQueryOptions - Filtering and sorting options for getDecorators
  • DecoratorTypeSchema - Schema for defining decorator types
  • ModelSelection - Model selection type
  • EditorViewContentLayerOptions / EditorViewContentLayerProps - Content layer types
  • EditorViewLayerOptions / EditorViewLayerProps - Overlay layer types
  • EditorViewLayersConfig / EditorViewLayerType - Layer configuration types

Basic Usage

import { EditorView } from '@barocss/editor-view-react';
import { Editor } from '@barocss/editor-core';
import { getGlobalRegistry } from '@barocss/dsl';

const editor = new Editor(/* ... */);

function App() {
const viewRef = useRef<EditorViewRef>(null);

return (
<EditorView
ref={viewRef}
editor={editor}
options={{
registry: getGlobalRegistry(),
className: 'my-editor',
}}
/>
);
}

// Use ref API for decorators and selection
viewRef.current?.addDecorator({
sid: 'highlight-1',
stype: 'highlight',
category: 'inline',
target: { sid: 'p1', startOffset: 0, endOffset: 5 },
});

Component Architecture

EditorView
└─ EditorViewContextProvider (manages editor, handlers, decorator managers)
└─ EditorViewRoot (exposes ref API via useImperativeHandle)
├─ EditorViewContentLayer (contenteditable div, renders model via ReactRenderer)
├─ DecoratorLayer (overlay: decorator decorators)
├─ SelectionLayer (overlay: selection decorators)
├─ ContextLayer (overlay: context decorators)
└─ CustomLayer (overlay: custom decorators + children)

EditorView wraps everything in EditorViewContextProvider, then renders EditorViewRoot which creates the layered structure. The ref is forwarded through to EditorViewRoot which exposes the full EditorViewHandle API.

Context System

EditorViewContextProvider creates and manages:

  • editor — The Editor instance
  • viewStateRef — Mutable state flags (isModelDrivenChange, isRendering, isComposing, skipNextRenderFromMO, skipApplyModelSelectionToDOM)
  • selectionHandlerReactSelectionHandler for bidirectional selection sync
  • inputHandlerReactInputHandler for text input and composition handling
  • mutationObserverManager — Tracks DOM mutations in the contenteditable
  • contentEditableRef — Ref to the contenteditable DOM element
  • Decorator managersDecoratorManager, RemoteDecoratorManager, PatternDecoratorConfigManager, DecoratorGeneratorManager, DecoratorSchemaRegistry
  • getMergedDecorators — Merges local, remote, pattern, and generator decorators
  • decoratorVersion — Bumped on decorator changes to trigger re-renders

Access the context from any child component:

import { useEditorViewContext } from '@barocss/editor-view-react';

function MyPlugin() {
const { editor, selectionHandler } = useEditorViewContext();
// ...
}

Layer System

EditorView uses a layered architecture with five layers:

LayerComponentPurpose
ContentEditorViewContentLayerThe contenteditable div. Renders model via ReactRenderer.build(). Handles input events and mutation observation.
DecoratorEditorViewLayer (decorator)Overlay for decorator-category decorators (CSS highlights, widgets).
SelectionEditorViewLayer (selection)Overlay for selection-category decorators (custom carets, selection highlights).
ContextEditorViewLayer (context)Overlay for context-category decorators (tooltips, floating menus).
CustomEditorViewLayer (custom)Overlay for custom decorators. Also accepts React children passed to EditorView.

Overlay layers use ReactRenderer.buildOverlayDecorators() to render decorator content. Each layer is positioned absolutely over the content layer.

Decorator Management

The ref API (EditorViewHandle) provides full decorator CRUD:

// Add a decorator
viewRef.current.addDecorator({
sid: 'comment-1',
stype: 'comment-highlight',
category: 'inline',
target: { sid: 'text-1', startOffset: 5, endOffset: 15 },
});

// Update a decorator
viewRef.current.updateDecorator('comment-1', {
data: { resolved: true },
});

// Remove a decorator
viewRef.current.removeDecorator('comment-1');

// Query decorators with filtering and sorting
const inlineDecorators = viewRef.current.getDecorators({
category: 'inline',
nodeId: 'text-1',
sortBy: 'id',
sortOrder: 'asc',
});

// Export/import decorators for persistence
const data = viewRef.current.exportDecorators();
viewRef.current.loadDecorators(data, patternFunctions);

Decorator generators can also be registered via addDecorator by passing an object with a generate property.

Selection

The ref API exposes selection conversion between model and DOM:

// Apply model selection to DOM
viewRef.current.convertModelSelectionToDOM(modelSelection);

// Read DOM selection as model selection
const modelSel = viewRef.current.convertDOMSelectionToModel(window.getSelection());

// Convert a StaticRange (from beforeinput) to model selection
const sel = viewRef.current.convertStaticRangeToModel(staticRange);

Selection sync is bidirectional: DOM selection changes update the model, and model selection changes (from commands or transactions) update the DOM.

Comparison with editor-view-dom

Aspecteditor-view-domeditor-view-react
RenderingDOMRenderer (VNode → DOM reconciliation)ReactRenderer (DSL → ReactNode, React reconciliation)
Mountnew EditorViewDOM(editor, { container })<EditorView editor={editor} /> component
Decorator APIview.addDecorator(), view.removeDecorator()viewRef.current.addDecorator(), viewRef.current.removeDecorator()
Layer structure5 layers (content, decorator, selection, context, custom)Same 5 layers as React components
Selection syncDirect DOM manipulationSame, via ReactSelectionHandler
When to useVanilla JS / non-React appsReact applications

The decorator API surface is the same — decorators created for one view work in the other.

When to Use

  • React applications — When your app is built with React
  • React ecosystem — When you need React hooks, context, and component composition around the editor
  • Custom layers — When you want to render custom React components in overlay layers

Integration

Editor-View-React connects:

  • Editor-Core — Executes commands on the Editor instance
  • Renderer-React — Renders model to ReactNode via ReactRenderer
  • Shared — Uses DecoratorManager, PatternDecoratorConfigManager, and other decorator utilities from @barocss/shared