Default Implementation & UI

This page covers two areas: default_implementation (the ready-to-use components and factories the tutorial is built on) and implbase / uibase (the infrastructure you reach for when writing custom renderers). It is organized by export, for looking up signatures; for a systematic account of how this layer is used and why it is built the way it is, read the Default Implementation part.

The two top-level components

DefaultEditorComponent

The complete default editor interface. It accepts all props of EditorComponentProps (see the editor page), plus:

{
    config?: PartialEditorConfig            // style configuration (fonts, margins, widths), partial override
    texts?: PartialEditorTexts              // interface text (button hints, panel titles, toasts), partial override
    onSave?: () => void                     // called when the user triggers the save action
    sidebar_extras?: (() => React.ReactNode)[]  // custom buttons appended to the sidebar
    end_element?: React.ReactNode           // an element appended after the document
}

It includes the paper, the sidebar, the floating areas for parameter and concept editing, the overlay for editing abstract nodes, and keyboard navigation. Notifications are built in as well (it carries its own notistack SnackbarProvider). Calling get_editor() through a ref returns the inner working EditorComponent, which gives access to get_root() and the other methods.

DefaultPrinterComponent

{
    printer: Printer
    root: AbstractNode
    config?: PartialPrinterConfig
    onUpdateCache?: (cache: PrinterCache) => void
    onDidMount?: (printer_comp: PrinterComponent, me: DefaultPrinterComponent) => void
}

The complete default printing interface. onUpdateCache hands you the cache after every preprocessing pass (used for cross references, tutorial chapter 6). onDidMount provides the inner PrinterComponent; take it from here when you need methods like scroll_to_idx.

Editor renderer factories

These functions generate fully interactive editing appearances for each node kind. The shared customization points: get_label (the label; called as a component, so hooks are allowed inside), surrounder (how the content is wrapped), buttons_extra (additional buttons), and rightbar_extra (an extension slot in the right bar).

FactoryNode kindCharacter
get_deafult_group_editor_with_appbargroupA card with a top title bar. The "deafult" in the name is a historical spelling.
get_default_group_editor_with_rightbargroupA right-side bar style with buttons folded into a menu; visually more compact
get_default_inline_editorinlineInline style; surrounder decides how the text is wrapped while editing
get_default_struct_editor_with_rightbarstructureMulti-column layout; get_numchildren and get_widths decide the number and widths of columns, and child groups are added or removed to match
get_default_spliter_editorsupportDivider style; get_title supplies the caption on the rule
get_default_display_editorsupportDisplay style (images and the like): render_element renders the actual content, is_empty decides when to show a placeholder icon
get_default_abstract_editorabstractContainer for abstract nodes (the root, annotations)
get_default_editors()allReturns default renderers for all seven node kinds, for EditorCore's default_renderers

One more function export relates to abstract editing: open_abstract_editor(node, abs_idx) opens the abstract editor programmatically, editing the abstract on node whose idx equals abs_idx (note that the second argument is the abstract node's identifier, not its position in the list). The abstract-management buttons of the default interface use this same entry; call it directly when drawing your own abstract management UI inside a custom renderer.

Printer renderer factories

The printing-side factories. The shared customization point is contexters (an array of contexter-producing functions, wired into preprocessing automatically; tutorial chapter 6). The block-level factories additionally take pre_element and aft_element (content injected before and after the body) and, for deeper changes, inner and outer (replacing the inner or outer wrapper entirely).

FactoryNode kindCharacter
get_default_group_renderergroupThe workhorse for blocks; small_margin_enter tightens the spacing before the block
get_default_structure_rendererstructureMulti-column grid; subinner customizes the wrapper of each column
get_default_paragraph_rendererparagraphParagraphs; supports injecting elements or text at the start
get_default_inline_rendererinlineouter decides the wrapping of the inline content
get_default_abstract_rendererabstractRenders as a badged link; clicking opens a dialog showing the full sub-document
auto_rendereranyThe most general one: give it a render function (and optionally contexters) and it constructs a PrinterRenderer directly
useless_renderer_block / useless_renderer_inline / useless_renderer_textas defaultsPass-through renderers adding no styling; tutorial chapter 3 assembled default_renderers from them

The contexter family

The preprocessing-phase tools; mechanism and usage in tutorial chapter 6.

ClassConstructorPurpose
ContexterBase<NT, CtxT, EnvT>(key, default_val)The base class. Provides the enter/exit hooks and the accessors get_env / set_env / get_context / set_context; custom contexters inherit from it
OrderContexter(order_key, separate_groups?)Automatic numbering. Same counter name means shared numbers; with separate_groups true, separating groups restart the count
ReferenceContexter(get_reference)Generates a reference name per node into the cache; the basis of cross references
InjectContexter(infokey, {preinfo?, aftinfo?})Writes a piece of information into the environment when its node is entered or exited
ConsumerContexter(infokey)Later nodes read that information out of the environment into their own contexts

Companion types: PreprocessInformation<NT> is the information bundle passed to contexter-producing functions ({node, parameters, context, env}), and PreprocessFunction<NT, R> is the type of such functions.

implbase: hooks and widgets inside renderers

When writing a custom editor renderer (or its get_label and buttons_extra), these are the everyday tools:

ExportDescription
useNode(is_equal?)The concept node currently being rendered; pass a comparison function to control when re-renders happen
useParameters()The current node's processed parameters; the staple of get_label
useEditor()The current EditorComponent, giving access to the tree operations
useResetSelection()Returns a pair of functions: save the cursor position, restore it. Used to bring the editing position back after an overlay interaction
UniversalExtraA small generic inline input component, often embedded in a node's right bar for quickly editing one parameter (the example application uses it for link targets and image sources; supports pasting images directly)
DefaultParameterContainerThe parameter editing panel itself; the default parameter drawer is built around it
AutoIconButton / ButtonGroup / FoldedButtonGroup / MouselessButtonButton components with keyboard navigation support; base custom buttons on them
MouselessHint / ShowHintControlButtonShortcut hint bubbles, and a toggle to keep hints visible
EditorTexts / make_editortexts / useTextsThe interface text table, its merge function and the hook renderers read it with
EditorConfig / make_editorconfig / useEditorConfigThe editor style configuration: its type, the merge function, and the reading hook

uibase: general UI utilities

uibase is a set of general UI utilities unrelated to the editor itself. The default implementation uses them heavily, and they are equally usable when you build custom interface pieces (sidebar buttons, parameter editing extensions), saving you from reinventing them:

ExportDescription
AutoStack / AutoStackButtons / AutoTooltip / AutoStackedPopperA family of components that adjust to the layout direction automatically: inside a horizontal container the inner stack turns vertical, and tooltip placement follows
mod_scrollbar(el) / ScrollBarBoxApply OverlayScrollbars styling to a container
usePersistedState(key, default)React state synchronized with localStorage
TextIconA circular text icon
with_partial_props(Comp, defaults)Pre-fill part of a component's props and get a new component
light_grey(color)Convert a color to light grey (works with the color package)

Printing typography widgets

The printing side also ships a set of typography widgets. Using them in printer renderers keeps your spacing and type scale consistent with the defaults: PrinterPartBox (a content block), PrinterParagraphBox (a paragraph box), PrinterStructureBoxText (structural text; tutorial chapter 5 uses it for theorem headings), PrinterNewLevelBox and PrinterOldLevelBox (entering and leaving an indentation level), PrinterDisplayText (display text), PrinterWeakenText (de-emphasized text), and PrinterConfigContext for reading the printing style configuration. The full list is in the TypeDoc reference.