Skip to content

Web Components Basics

The @sciflow/editor-start package registers two custom elements:

Element Purpose
<sciflow-editor> The full ProseMirror-powered editor surface.
<sciflow-formatbar> Optional toolbar that issues editor commands.

This chapter covers loading the bundle, understanding attributes and events, wiring the toolbar, and applying theme tokens.

Loading the Bundle

<script type="module" src="/node_modules/@sciflow/editor-start/dist/bundle/sciflow-editor.js"></script>

Self-host or CDN

For production builds you can copy the emitted bundle to your own CDN. The file is an ES module and can be tree-shaken by modern bundlers.

Core Properties

Property Type Description
doc SciFlowDocJSON \| null Sets the full document snapshot. Assign a new object to replace the content.
initialContent ProseMirrorNode \| null Alternative way to seed the document with a ProseMirror node.
placeholder string Placeholder string shown when the document is empty.
headingText string Display heading for the built-in default document template.
commands (getter) CommandRunner \| null Provides immediate commands plus flow helpers.
editorView (getter) EditorView \| null Gives you direct access to ProseMirror for advanced use cases.

Events

Event Fired when Detail payload
editor-ready Editor has mounted and commands/views become available. { editor: SciFlowEditorElement }
editor-change Document content changes. { doc: SciFlowDocJSON, operations: Operation[] }
editor-selection-change Selection/cursor changes. { anchor: number, head: number }

All events bubble across the shadow boundary so you can attach listeners to parent components or frameworks.

editor.addEventListener('editor-change', (event) => {
  const { doc } = event.detail;
  saveDraft(doc);
});

Connecting the Format Bar

1. Declarative (for attribute)

<sciflow-formatbar for="editor"></sciflow-formatbar>
<sciflow-editor id="editor"></sciflow-editor>

The toolbar auto-discovers the editor with that id once both elements are in the DOM.

2. Programmatic

const toolbar = document.querySelector('sciflow-formatbar');
const editor = document.querySelector('sciflow-editor');

editor.addEventListener('editor-ready', () => {
  toolbar.editor = editor;
}, { once: true });

Material Symbols required

The toolbar uses Material Symbols. Include the font in your <head>:

<link rel="stylesheet"
  href="https://fonts.googleapis.com/css2?family=Material+Symbols+Rounded:opsz,wght,FILL,GRAD@20..48,400,0..1,0" />

Issuing Commands

const runner = editor.commands;
if (runner) {
  runner.commands.focus();
  runner.commands.insertText('Hello, world!');
  runner.flow().toggleMark('strong').insertText(' bold text').run();
}

Use runner.available() to check capabilities before toggling marks or nodes.

Lists & Blockquotes

The list and blockquote features expose familiar commands that mirror the ProseMirror examples. Once those features are enabled (they are toggled on in the demo), you can drive them like any other command:

const commands = editor.commands?.commands;

// Toggle bullet/ordered lists
commands?.toggleBulletList?.();
commands?.toggleOrderedList?.();

// Nest or lift list items
commands?.sinkListItem?.();
commands?.liftListItem?.();

// Wrap/unwrap blockquotes
commands?.toggleBlockquote?.();

Each command returns true on success, so you can wire them into toolbars or keyboard shortcuts as needed.

Styling & Layout

  • The editor exposes CSS custom properties such as --sciflow-editor-border and --sciflow-editor-focus-ring. Override them on the host element to match your design system.
  • Wrap the component inside any layout container; it behaves like a block element that expands to the width of its parent.

Keyboard focus

Call runner.commands.focus() after programmatic updates (e.g., clicking entries in your own outline) so screen readers and caret navigation keep working.

Custom Events & Integrations

The demo shows how to:

  • Mirror the selection into a reference sidebar via editor-selection-change.
  • Dispatch navigation requests (outline clicks → commands.setSelection).
  • Drive custom insertions (commands.insertFigure, commands.insertCitation).

Refer to the Customization Recipes for full walk-throughs.