Lynx/Modules/Markdown/API reference
@sigx/lynx-markdown · Stable · Component library

API reference#

Exports of @sigx/lynx-markdown v0.35.0.

The package has two entry points. The root (@sigx/lynx-markdown, the "." export) carries the renderer, the mention plugin and the richtext re-exports, with no runtime peer imports beyond @sigx/lynx. The @sigx/lynx-markdown/editor subpath adds the block-tree editor; importing it turns the optional peers (@sigx/lynx-keyboard, @sigx/lynx-richtext) into real requirements. The renderer is pure JS and renders identically on iOS, Android and Harmony — there is no native module.

The document model, formats, plugin contract and editor core are @sigx/richtext's; this page documents the Lynx surface and links there for the rest.

Components#

Each component has its own page with usage, props and events — see the Components catalog:

Root entry#

MarkdownViewProps#

TypeScript
export type MarkdownViewProps =
  & Define.Prop<'value', string, false>
  & Define.Prop<'onLink', LinkHandler, false>                 // (url, node) => void — url is sanitised
  & Define.Prop<'onImageTap', (url: string) => void, false>
  & Define.Prop<'components', Partial<LynxMarkdownComponents>, false>
  & Define.Prop<'plugins', readonly RichTextPlugin[], false>;

plugins must be a stable array — changing its identity resets the incremental parse state.

defaultComponents#

The neutral, theme-agnostic Lynx component map. MarkdownView merges your partial components over it. Bullets and checkboxes are drawn as <view> shapes, text collapses soft breaks to a space, html shows raw HTML as literal text, and image renders as a tappable label.

TypeScript
export const defaultComponents: LynxMarkdownComponents;

LynxMarkdownComponents#

@sigx/richtext's ComponentMap over Lynx elements: only root is required, the standard slots are typed and optional, and plugin node types are keyed by node.type. See Rendering → component maps for every slot's props.

TypeScript
export type LynxMarkdownComponents = ComponentMap<JSXElement>;
export type LynxMarkdownChild = RenderChild<JSXElement>;

export interface LynxImageProps extends ImageProps {
  onImageTap?: (url: string) => void;
}

createMentionPlugin#

The Lynx half of the reference mention plugin: the core mention editor slice with candidate search and cleaning, the popup row renderer, lynxMentionNode, and @[label](id) through mentionMarkdown.

TypeScript
export function createMentionPlugin(options: MentionPluginOptions): LynxMentionPlugin;

export interface MentionPluginOptions {
  search(query: string): MentionCandidate[] | Promise<MentionCandidate[]>;
  renderItem?: SuggestionRenderItem;                                        // popup row
  component?: (props: MentionComponentProps) => JSXElement | string;        // preview for MarkdownView
  trigger?: string;                                                          // default '@'
  debounce?: number;
}

export interface MentionCandidate {
  id: string;
  label: string;
  kind?: string;
  [key: string]: unknown;   // display-only extras, reach renderItem only
}

export interface MentionComponentProps {
  node: Mention;
  children: LynxMarkdownChild[];
}

export interface LynxMentionPlugin extends RichTextPlugin {
  component?: (props: MentionComponentProps) => JSXElement | string;
}

A label cannot contain ], CR or LF and an id cannot contain ), CR or LF; candidates are cleaned, and a candidate that cleans to empty is dropped.

lynxMentionNode#

The mention node spec with the candidate's kind kept on the chip — a display-only field that lives in the document but never in the markdown.

TypeScript
export const lynxMentionNode: NodeSpec;

mentionPlugin, mentionSyntax#

Re-exported from @sigx/richtext-markdown: the read-only mention plugin ({ name: 'mention', nodes: [mentionNode], formats: { markdown: mentionMarkdown } }) and its @[label](id) inline syntax.

Richtext re-exports#

So a Lynx app keeps a single import, the root re-exports:

ExportFromDescription
createTextStream@sigx/richtextThe streaming controller
renderDocument@sigx/richtextThe render engine, for custom renderers
markdownFormat, parseMarkdown, createIncrementalEngine@sigx/richtext-markdownThe markdown format
every typebothexport type * from @sigx/richtext and @sigx/richtext-markdown — Root, Mention, RichTextPlugin, NodeSpec, ComponentMap, InlineSyntaxExtension, …

Editor subpath#

All exports in this section live on @sigx/lynx-markdown/editor.

MarkdownEditorProps#

TypeScript
export type MarkdownEditorProps =
  & Define.Prop<'value', string, false>
  & Define.Prop<'document', Root, false>
  & Define.Prop<'placeholder', string, false>
  & Define.Prop<'minLines', number, false>
  & Define.Prop<'maxLines', number, false>
  & Define.Prop<'mode', MarkdownEditorMode, false>                 // 'auto' | 'fixed' | 'fullscreen'
  & Define.Prop<'fontSize', number, false>
  & Define.Prop<'textColor', string, false>
  & Define.Prop<'accentColor', string, false>
  & Define.Prop<'placeholderColor', string, false>
  & Define.Prop<'confirmType', 'send' | 'search' | 'next' | 'go' | 'done', false>
  & Define.Prop<'autoFocus', boolean, false>
  & Define.Prop<'disabled', boolean, false>
  & Define.Prop<'class', string, false>
  & Define.Prop<'toolbar', boolean | 'top' | 'bottom', false>
  & Define.Prop<'toolbarItems', readonly ToolbarItem[], false>
  & Define.Prop<'renderToolbarItem', ToolbarRenderItem, false>
  & Define.Prop<'plugins', readonly RichTextPlugin[], false>
  & Define.Prop<'components', Partial<LynxMarkdownComponents>, false>
  & Define.Prop<'suggestionPopup', SuggestionPopupStyle, false>
  & Define.Prop<'suggestions', 'popup' | 'none', false>
  & Define.Prop<'renderSuggestions', (api: SuggestionsApi) => JSXElement | null, false>
  & Define.Prop<'onTriggerSession', (session: TriggerSession | null) => void, false>
  & Define.Prop<'keymap', Keymap, false>
  & Define.Prop<'inputRules', readonly InputRule[] | false, false>
  & Define.Prop<'fullscreenClass', string, false>
  & Define.Prop<'onFullscreenChange', (open: boolean) => void, false>
  & Define.Prop<'onChange', (markdown: string) => void, false>
  & Define.Prop<'onDocumentChange', (doc: Root, transaction: Transaction) => void, false>
  & Define.Prop<'onSelectionChange', (selection: EditorSelection) => void, false>
  & Define.Prop<'onFocus', () => void, false>
  & Define.Prop<'onBlur', () => void, false>
  & Define.Prop<'controllerRef', (ctrl: MarkdownEditorController) => void, false>;

See MarkdownEditor for what each prop does.

MarkdownEditorController#

TypeScript
export interface MarkdownEditorController {
  readonly editor: Editor;                       // the @sigx/richtext core instance
  run(command: Command | string): boolean;
  toggleBold(): void;
  toggleItalic(): void;
  toggleStrike(): void;
  toggleCode(): void;
  setHeading(level: 0 | 1 | 2 | 3 | 4 | 5 | 6): void;          // 0 reverts to paragraph
  setList(kind: 'bullet' | 'ordered' | 'task' | 'none'): void;
  toggleQuote(): void;
  insertLink(href: string, text?: string): void;
  insertText(text: string): void;
  replaceRange(start: number, end: number, text: string): void; // in the current block
  insertChip(chip: { id: string; label: string; kind?: string }, replace?: { from: number; to: number }): void;
  clear(): void;
  openFullscreen(): void;
  closeFullscreen(): void;
  isFullscreen(): boolean;
  focus(): void;
  blur(): void;
  getMarkdown(): string;
  getDocument(): Root;
  setMarkdown(markdown: string): void;
  setDocument(doc: Root): void;
  getSelection(): EditorSelection;
  undo(): boolean;
  redo(): boolean;
}

SuggestionsApi#

What renderSuggestions receives.

TypeScript
export interface SuggestionsApi {
  session: TriggerSession;          // { plugin, key, anchor, query, caret, items, loading }
  activeIndex: number;
  setActive(index: number): void;
  pick(item: TriggerItem): void;
  close(): void;
}

LynxTriggerExtras#

A TriggerSpec may carry a Lynx row renderer for the built-in popup.

TypeScript
export interface LynxTriggerExtras {
  renderItem?: SuggestionRenderItem;
}

EditorToolbar, defaultToolbarItems, toolbarState#

The neutral toolbar and the core's item contract. See EditorToolbar.

TypeScript
export type EditorToolbarProps =
  & Define.Prop<'controller', MarkdownEditorController | null, false>
  & Define.Prop<'items', readonly ToolbarItem[], false>
  & Define.Prop<'renderItem', ToolbarRenderItem, false>
  & Define.Prop<'class', string, false>;

export type ToolbarRenderItem = (item: ToolbarItem, active: boolean, run: () => void, enabled: boolean) => JSXElement;

ToolbarItem, ToolbarContext, ToolbarState, defaultToolbarItems and toolbarState are re-exported from @sigx/richtext/editor — see Editor → toolbar state.

SuggestionPopup, SuggestionPopupStyle#

The neutral popup and the style bundle MarkdownEditor forwards through suggestionPopup. See SuggestionPopup.

TypeScript
export interface SuggestionPopupStyle {
  class?: string;
  width?: number;                              // dp, default 240
  maxHeight?: number;                          // dp, default 220
  placement?: 'auto' | 'above' | 'below';
  surfaceColor?: string;
  borderColor?: string;
  activeColor?: string;
  textColor?: string;
}

export type SuggestionRenderItem = (item: TriggerItem, active: boolean) => JSXElement;
export function derivePopupStyleFromText(textColor?: string): SuggestionPopupStyle;

Blocks, view and surfaces#

For hosts that compose their own layout:

ExportDescription
BlockViewOne root block, dispatching on its schema role (block: EditorBlock)
InlineBlockA text block as a <sigx-richtext boundary-keys> field
CodeBlockA code block as a <textarea>
createLynxEditorView, useLynxEditorView, LynxEditorView, EditorFieldStyleThe view context blocks read
createLynxInlineSurface, LynxInlineSurface, LynxInlineSurfaceOptionsThe core's InlineSurface over a rich-text field
createLynxCodeSurface, LynxCodeSurface, LynxCodeSurfaceOptionsThe core's CodeSurface over a textarea
flatToDoc, docToFlat, blockAttrForMap one block's InlineFlat to the field's RichDoc and back
SelectionStateRe-exported from @sigx/lynx-richtext

Core re-exports#

From @sigx/richtext/editor: createEditor, commands, commandRegistry, createSlashPlugin, createTriggerSessionManager, and createMentionPlugin as createCoreMentionPlugin; from @sigx/richtext-markdown/editor: markdownPreset. Types: Editor, EditorOptions, EditorState, EditorSelection, EditorPlugin, EditorPluginSlice, Command, CommandContext, Keymap, InputRule, Transaction, TriggerSpec, TriggerItem, TriggerSelectApi, TriggerSession, TriggerSessionManager, SlashItem, SlashPluginOptions, MentionItem, InlineFlat, InlineSpan. See Editor for their reference.