Bridge Training
Rich Text

RichEditor

Composable compound component for rich text editing.

RichEditor is a compound component that wraps Plate.js. It provides Root, Toolbar, Area, and Input parts that consumers compose into their layout.

import { RichEditor, useRichEditorRef } from '@workspace/rich-text/components/rich-editor';

Usage

const ref = useRichEditorRef();

<RichEditor.Root
  config={{ mode: 'default', lists: true }}
  defaultValue={richText}
  ref={ref}
>
  <RichEditor.Toolbar>
    <MarkToolbarButton nodeType="bold">B</MarkToolbarButton>
    <MarkToolbarButton nodeType="italic">I</MarkToolbarButton>
    <ListToolbarButton listType="ordered" />
    <ListToolbarButton listType="bulleted" />
    <SuitSymbolButton suit="S" />
    <SuitSymbolButton suit="H" />
    <SuitSymbolButton suit="D" />
    <SuitSymbolButton suit="C" />
  </RichEditor.Toolbar>
  <RichEditor.Area variant="edge">
    <RichEditor.Input placeholder="Write..." variant="edge" />
  </RichEditor.Area>
</RichEditor.Root>

Parts

RichEditor.Root

The editor provider. Creates a Plate editor instance and exposes an imperative ref handle.

PropTypeDefaultDescription
configRichEditorConfig{}Editor configuration (mode, lists)
defaultValueRichText[]Initial content. Only read on mount.
onContentChange() => voidNotification callback (no value). Use ref to read.
refRef<RichEditorHandle>Imperative handle

RichEditor.Toolbar

Toolbar wrapper. Pass toolbar buttons as children.

PropTypeDescription
classNamestringAdditional CSS class
childrenReactNodeToolbar buttons

RichEditor.Area

Scroll container around the editable area.

PropTypeDescription
variant'default' | 'comment' | 'demo' | 'edge' | 'select'Style variant
classNamestringAdditional CSS class

RichEditor.Input

The contenteditable area.

PropTypeDescription
placeholderstringPlaceholder text
variant'default' | 'comment' | 'edge'Style variant
classNamestringAdditional CSS class

Ref Handle (RichEditorHandle)

type RichEditorHandle = {
  getValue(): RichText;
  setValue(value: RichText): void;
  hasContent(): boolean;
  focus(): void;
  setMode(mode: EditorMode): void;
};

Reading content

const value = ref.current.getValue();       // RichText (domain)
const html = toHTML(ref.current.getValue()); // use lib/ for serialization

Writing content

ref.current.setValue(newRichText);

Config (RichEditorConfig)

type RichEditorConfig = {
  mode?: EditorMode;  // 'default' | 'petit-bridge'
  lists?: boolean;    // default: true
};
  • mode controls how suit symbols render (standard Unicode vs petit-bridge squares)
  • lists enables/disables ordered and bulleted list plugins

Uncontrolled Pattern

The editor follows Plate's recommendation for uncontrolled usage:

  • defaultValue is only read on mount
  • After mount, Plate manages its own internal state
  • Use ref.getValue() / ref.setValue() for imperative access
  • There is no value + onChange controlled pattern

On this page