Skip to main content

API

import { MarkdownEditor, useMarkdownEditor } from '@zuilib/text-editor'
import '@zuilib/text-editor/styles.css'

Package entry points: . (ESM + types: the editor, the hook, the pure drawing API and the first-party plugins), ./markdown (the editor without the drawing canvas), ./lexical (node classes, transformers, presets and every $-prefixed helper, for assembling your own Lexical editor), ./drawing (the canvas on its own), ./mentions, ./comments, ./images, ./paste (the plugins on their own entries, not on ./markdown), ./styles.css, ./package.json. DRAWING_FORMAT.md and CHANGELOG.md ship in the package too. Hosts that only render <MarkdownEditor> never need ./lexical; no $-name and no Lexical node class leaves the root entry.

Component and hook​

ExportPurpose
MarkdownEditorThe component. Compound parts as statics: .Root, .Content, .Toolbar, .ToolbarButton, .ToolbarDivider, .FormatButtons, .BlockButtons, .InsertButtons, .HistoryButtons, .Outline, .CharacterCount
MarkdownEditorProps, ToolbarItemsProps of the component; the groups (format, block, insert, history) handed to a toolbar render function
EditorRootProps, EditorContentProps, EditorMode, EditorFieldPropsTypes of the compound parts
useMarkdownEditor(), MarkdownEditorApi, BlockTypeHeadless hook and its return type (Toolbar)
useEditorContext(), useLabels()Editor context (mode, labels, field attributes) and resolved labels, for plugins
EditorLabels, EditorLabelsInput, DeepPartial, DEFAULT_LABELS, resolveLabelsLocalisation (Editor)
CollapsibleHeadingsLabels, TableRowShortcutsLabels, TableColumnShortcutsLabelsLabel types of the individual plugins
Toolbar, ToolbarButton, ToolbarDivider, FormatButtons, BlockButtons, InsertButtons, HistoryButtons, CharacterCountToolbar primitives and the character counter as named exports
useToolbarKeyboard, TOOLBAR_ITEM_ATTRIBUTEAPG toolbar keyboard pattern for your own toolbars
isSafeUrl, SAFE_LINK_PROTOCOLSLink validation (http, https, mailto, tel, scheme-less)
EDIT_LINK_COMMANDOpens the link bubble for a non-empty selection (what the toolbar link button dispatches); nothing is written until a URL is applied
INSERT_HORIZONTAL_RULE_COMMANDInserts a rule after the current block (what insertHorizontalRule() dispatches)
INSERT_FOOTNOTE_COMMAND, GOTO_FOOTNOTE_DEFINITION_COMMAND, GOTO_FOOTNOTE_REF_COMMANDInsert a cue plus note ({ id? }; what insertFootnote() dispatches); move the caret to a note / back after its first cue

Lexical assembly (./lexical)​

For assembling your own Lexical editor with the same dialect. Use the exported lists rather than rebuilding them: DRAWING_PRESET_NODES and DRAWING_PRESET_TRANSFORMERS are what the default MarkdownEditor mounts, MARKDOWN_NODES and MARKDOWN_TRANSFORMERS what ./markdown mounts. The order is FRONTMATTER, DRAWING, DIAGRAM, LISTS, CHECK_LIST, TABLE, CODE_BLOCK, HORIZONTAL_RULE, the three FOOTNOTES, then Lexical's TRANSFORMERS without CODE: the fenced blocks claim their syntax before CODE_BLOCK, LISTS and CHECK_LIST before UNORDERED_LIST, and --- / [^id] before HEADING / LINK.

The custom headless assembly below imports Lexical directly. Declare @lexical/headless and @lexical/markdown as direct application dependencies for this integration; the standard MarkdownEditor install remains one package.

import { createHeadlessEditor } from '@lexical/headless'
import { $convertFromMarkdownString } from '@lexical/markdown'
import { DRAWING_PRESET_NODES, DRAWING_PRESET_TRANSFORMERS } from '@zuilib/text-editor/lexical'

const editor = createHeadlessEditor({ namespace: 'x', nodes: DRAWING_PRESET_NODES, onError: console.error })
editor.update(() => $convertFromMarkdownString(markdown, DRAWING_PRESET_TRANSFORMERS))
ExportPurpose
DRAWING_PRESET, DRAWING_PRESET_NODES, DRAWING_PRESET_TRANSFORMERSThe default entry's preset and its node / transformer lists
MARKDOWN_PRESET, MARKDOWN_NODES, MARKDOWN_TRANSFORMERSThe same without drawings (./markdown)
createMarkdownEditor(preset), EditorPreset, TransformersInputBuild the component around a preset of nodes, transformers and plugins (Extending)
resolveTransformers(defaults, prop), shortcutTransformers(list)How the transformers prop is merged; which of the result double as typing shortcuts
editorNodeClassNames, mergeNodeClassNamesThe built-in node class names and the merge behind the nodeClassNames prop
$replaceMarkdown(markdown, transformers), replaceMarkdown, EXTERNAL_UPDATE_TAGReplace the whole document from markdown inside editor.update; what the controlled value prop uses, keeps the caret position when it still exists
TABLEGFM table transformer
LISTSNested lists: 2 or 4 spaces on import, 2 on export
CODE_BLOCKFenced code transformer; untagged blocks export as bare fences
FRONTMATTER, FrontmatterNode, $createFrontmatterNode, $isFrontmatterNode, SerializedFrontmatterNodeFrontmatter block
HORIZONTAL_RULE, HorizontalRuleNode, $createHorizontalRuleNode, $isHorizontalRuleNodeThematic break (---); the node is Lexical's own
FootnoteRefNode, FootnoteDefinitionNode, FootnoteSectionNode (+ $create*, $is*, Serialized*), FOOTNOTES, FOOTNOTE_DEFINITION, FOOTNOTE_CONTINUATION, FOOTNOTE_REFFootnote cue, note and section nodes and their GFM transformers
$insertFootnote(id?), $normalizeFootnotes(), $computeFootnoteNumbers(), $collectFootnoteRefs(), $getFootnoteSection(), $getFootnoteDefinitions(), $findFootnoteDefinition(id), $selectFootnoteDefinition(id), $selectFootnoteRef(id), $getSelectedFootnoteDefinition(), $nextFootnoteId(), FootnotesPluginFootnote model (inside editor.update / read); the plugin keeps the section last and sorted, numbers the cues and wires the keys — the root mounts it
DRAWING, DIAGRAM, DrawingNode, $createDrawingNode, $isDrawingNode, SerializedDrawingNodeDrawing node and its two transformers (```drawing and ```diagram). Also on ./drawing
$getSelectedTable, $getTableSettings, $setTableSettings, $isTableWidthExplicit, $getTableWidth, $setTableWidth, $getTableDensity, $setTableDensityTable setting helpers, inside editor.update / read
$getSelectedTableCell, $getTableCellPositionWhere the selection is
$insertTableRowAt, $deleteTableRowAt, $insertTableRowNear, $deleteTableRowNearRow operations
$insertTableColumnAt, $deleteTableColumnAt, $insertTableColumnNear, $deleteTableColumnNearColumn operations
codeTokenizer, registerCodeBlockHighlightingLexical tokenizer adapter and editor wiring for code highlighting
MentionNode, $createMentionNode, $isMentionNode, MENTION; ImageNode, $createImageNode, $isImageNode, $getSelectedImage, IMAGE; COMMENT, $getMarkNodes, $getCommentIds, $removeComment, $plainTextOffsetThe first-party plugin nodes and helpers (also on their own entries)

Tables​

ExportPurpose
TableDensity, TableSettings, TableSettingsOptions, DEFAULT_TABLE_SETTINGSSetting types and defaults
parseTableSettingsMarker, formatTableSettingsMarkerMarker comment ⇄ TableSettings
TABLE_WIDTH_MARKERDeprecated; use formatTableSettingsMarker
TableCellPositionWhere the selection is
insertableRowIndices, insertableColumnIndices, canDeleteRow, canDeleteColumnPure guards for custom toolbars

The $-prefixed table helpers are on ./lexical.

Block width​

ExportPurpose
BlockWidth'full' | 'text' | 'content'
BLOCK_WIDTHS, isBlockWidthValues and type guard
NewBlockWidthsShape of the newBlockWidth prop

Drawing payload​

ExportPurpose
DrawingData, DrawingShape, DrawingShapeType, NodeShapeType, ConnectorType, Binding, BindingSide, PointPayload types
deserializeDrawingData, serializeDrawingData, normalizeDrawingDataLenient parse (version 2 payloads migrate to version 3), serialise, re-anchor bindings
DRAWING_DATA_JSON_SCHEMAJSON Schema of the payload
isNodeShapeType, NODE_SHAPE_TYPES, CONNECTOR_TYPES, SHAPE_TYPES, SIDE_FIXED_POINTS, STROKE_COLORS, FILL_COLORS, EMPTY_DRAWINGConstants and guards
NODE_SHAPE_DEFINITIONS, NodeShapeDefinition, TextFieldData-driven shape geometry and text slots
findNodeShapeAt, createBindingHit-test a node shape; build a binding
DrawingPlugin, INSERT_DRAWING_COMMAND, DRAWING_FOCUS_COMMANDHandles insertion (the hook's insertDrawing dispatches the command); the canvas reports focus through the second. Also on ./drawing
DrawingStyle'clean' | 'ink' (Diagrams)

Geometry internals (binding resolution, elbow routing, ink rendering, outline math) are implementation details and are not exported.

Skeleton and Mermaid​

ExportPurpose
DrawingSkeleton, SkeletonBox, SkeletonConnector, SkeletonEnd, SkeletonText, ColorNameSkeleton types
parseDrawingSkeleton, isDrawingSkeleton, expandDrawingSkeletonParse and expand to DrawingData
DRAWING_SKELETON_JSON_SCHEMA, COLOR_PRESETSJSON Schema; palette name → stroke / fill
drawingToMermaid, MermaidOptions, MermaidDirectionMermaid flowchart export

Code highlighting​

ExportPurpose
CodeGrammar, CodeRule, CodeToken, CodeTokenTypeGrammar and token types
registerCodeLanguage, hasCodeLanguage, resolveCodeLanguage, getCodeLanguagesRegistry (built-ins load on first lookup)
tokenizeCodeThe lexer, for use outside the editor
BUILTIN_CODE_LANGUAGES, CODE_TOKEN_TYPES, PLAIN_LANGUAGEConstants

The Lexical wiring (codeTokenizer, registerCodeBlockHighlighting) is on ./lexical.