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

EditorToolbar#

The neutral, theme-agnostic formatting toolbar for MarkdownEditor. The items are data from the editor core; each item's rendering is replaceable.

Import#

TSX
import { EditorToolbar, defaultToolbarItems } from '@sigx/lynx-markdown/editor';

Items are the core's ToolbarItem data — the same defaultToolbarItems every platform shares, plus whatever the editor's plugins contribute. Active and enabled states come from the core's toolbarState, derived from the editor state, so the toolbar needs nothing but the controller. The root carries ignore-focus so toolbar taps never blur the editor.

Usage#

The simplest path is to let MarkdownEditor mount it for you:

TSX
<MarkdownEditor value={draft.value} onChange={save} toolbar />

To place it yourself, render it standalone and pass the editor's controller:

TSX
import { component } from '@sigx/lynx';
import { MarkdownEditor, EditorToolbar, type MarkdownEditorController } from '@sigx/lynx-markdown/editor';

export const Composer = component(({ signal }) => {
  const state = signal({ controller: null as MarkdownEditorController | null });

  return () => (
    <>
      <EditorToolbar controller={state.controller} />
      <MarkdownEditor value={'# Draft'} controllerRef={(c) => (state.controller = c)} />
    </>
  );
});

Custom items#

items defaults to defaultToolbarItems: bold, italic, strike, inline code, link, H1–H3, paragraph, bullet / ordered / task list, quote, code block, divider, table, undo and redo. The editor's plugin items are appended. Pass your own array to add or reorder commands, and renderItem to skin each button.

TSX
<EditorToolbar
  controller={controller}
  items={myItems}
  renderItem={(item, active, run, enabled) => (
    <view class={active ? 'tb-on' : 'tb'} style={{ opacity: enabled ? 1 : 0.4 }} bindtap={run}>
      <text>{item.label ?? item.id}</text>
    </view>
  )}
/>

An item is data, not chrome:

TypeScript
interface ToolbarItem {
  id: string;
  label?: string;                        // short text: 'B', 'H1', …
  icon?: string;                         // an icon-set name, for skins
  group?: string;                        // items with the same group render adjacent
  isActive?(tb: ToolbarState): boolean;
  isEnabled?(tb: ToolbarState): boolean; // default: enabled whenever there is a selection
  run(tc: ToolbarContext): void;         // tc.run(command) runs a core command
}

ToolbarState carries activeMarks, blockType, attrs, ancestors, listKind, inBlockquote, canUndo, canRedo and mode.

Props#

PropTypeDescription
controllerMarkdownEditorController | nullThe editor's controller — the toolbar reads state and runs commands through it.
itemsreadonly ToolbarItem[]Base items; defaults to defaultToolbarItems. The editor's plugin items append.
renderItemToolbarRenderItemPer-item render override: (item, active, run, enabled) => JSXElement.
classstringExtra classes on the toolbar root.

A daisyUI skin ships in @sigx/lynx-daisyui/markdown (EditorToolbar, daisyToolbarItem).