Skip to main content
Reference status

This page predates the current package split. Use the current package guides for checked installation, public imports, and onboarding examples. The detailed examples below have not all been revalidated.

@barocss/dsl

The DSL package provides a template definition layer with functional DSL builders. It's how you define how your model data is rendered to the DOM.

Purpose​

Template definition layer with functional DSL builders. Instead of writing HTML or JSX, you use pure functions to describe your templates.

Key Exports​

  • define() - Register templates in the registry
  • element() - Create HTML element templates
  • data() - Bind model data to templates
  • when() - Conditional rendering
  • component() - Component templates with state
  • slot() - Slot for child content
  • portal() - Portal templates for overlays

Basic Usage​

import { define, element, data, slot } from '@barocss/dsl';

// Register a paragraph template
define('paragraph', element('p', {
className: 'paragraph'
}, [slot('content')]));

// Register a text template
define('inline-text', element('span', {
className: 'text'
}, [data('text', '')]));

Template Builders​

element()​

Creates an HTML element template:

element('div', { className: 'container' }, [
// children
]);

data()​

Binds model data to the template:

data('text', '')  // Binds model.text
data('title', 'default') // Binds model.title with default

slot()​

Creates a slot for child nodes:

slot('content')  // Renders child nodes here

when()​

Conditional rendering:

when(
(d) => d('published') === true,
element('span', {}, ['Published'])
)

Function Components​

All templates defined with define() are components. You can define them as functions:

// Function component (direct definition)
define('button', (props, model, context) => {
return element('button', {
onClick: props.onClick,
className: 'btn'
}, [
data('label', props.label || model.label || 'Click me')
]);
});

Function signature:

  • props: External data passed to component
  • model: The model node being rendered
  • context: Editor context and utilities

Note: Template builders (like element()) are automatically converted to function components internally.

Mark Definitions​

Marks are defined using defineMark():

import { defineMark, element, data } from '@barocss/dsl';

// Define bold mark
defineMark('bold', element('strong', {}, [data('text')]));

// Define highlight mark with attributes
defineMark('highlight', element('mark', {
style: { backgroundColor: data('color', '#ffff00') }
}, [data('text')]));

React Component Marks​

Marks can also be defined as React components using external():

import { defineMark, external } from '@barocss/dsl';
import type { MarkComponentProps } from '@barocss/dsl';

function HighlightMark({ markType, attributes, children }: MarkComponentProps) {
return <mark style={{ backgroundColor: attributes?.color ?? '#ffff00' }}>{children}</mark>;
}

defineMark('highlight', external(HighlightMark));

When renderer-react encounters an external mark component, it renders it directly as a React element. When renderer-dom encounters it, it falls back to a <span class="mark-{type}"> wrapper.

Type Interfaces​

The DSL package exports type interfaces for React component props:

  • BlockComponentProps<A> — Props for block node components (sid, stype, model, attributes, text, children)
  • MarkComponentProps<A> — Props for mark components (markType, attributes, text, children)

Decorator Definitions​

Decorators are defined using defineDecorator():

import { defineDecorator, element, data } from '@barocss/dsl';

// Define comment decorator
defineDecorator('comment', element('div', {
className: 'comment',
style: { position: 'absolute' }
}, [data('text')]));

Template Registry​

All templates are stored in a global registry:

import { getGlobalRegistry } from '@barocss/dsl';

const registry = getGlobalRegistry();
const template = registry.get('paragraph'); // Get template by node type

Registry features:

  • Global template storage
  • Template lookup by node type (stype)
  • Mark and decorator registration
  • Template validation

When to Use​

  • Template Definition: Define how nodes are rendered
  • Before Rendering: Templates must be registered before rendering
  • Component Creation: Create reusable component templates

Integration​

DSL templates are used by:

  • Renderer-DOM: Looks up templates from registry
  • VNodeBuilder: Converts templates to VNodes
  • Components: Component templates use DSL builders