Skip to main content
Docs

11. Editor-UX & Click-to-Edit

The editor is a React SPA with a split view: CodeMirror (Markdown) on the left, Iframe (Preview) on the right.

11.1 PostMessage Protocol#

DirectionTypePayload
Editor → PreviewRENDER_DOCS{ docsPage, pack, editMode }
Editor → PreviewSET_EDIT_MODE{ enabled: bool }
Editor → PreviewCHANGE_PACK{ pack: string }
Preview → EditorPREVIEW_READY
Preview → EditorLAYOUT_VARIANT_CHANGED{ slug, variant } (project-scope)
Preview → EditorPAGE_VARIANT_CHANGED{ slug, variant } (page-scope)
Preview → EditorCONVERT_CODE_TO_MERMAID{ code, language }
Preview → EditorDOCS_NAVIGATE{ slug }

Origin check: event.origin === PREVIEW_ORIGIN (http://localhost:4173 in dev, same origin in prod).

11.2 Click-to-Edit-Flow#

In edit mode, each component wraps itself in an EditablePrimitiveWrapper:

  1. Hover → dashed indigo Outline (35% → 75%)
  2. Click → solid Outline + Swap-Bar top center: [← V1 V2 V3 →] [✨ To Mermaid] [✕]
  3. Variant change → postMessage to editor → API patch → Re-Generate → Re-Render

11.3 Variant Resolution#

Three scopes, hierarchical:

explicit (in MD frontmatter)
  → page.componentVariants[slug]   (page-scope, content primitives)
    → project.componentVariants[slug]   (project-scope, layout primitives)
      → pack.defaultVariants[slug]
        → 1 (canonical)

Example: a callout on a page with componentVariants: {callout: 2} → V2, regardless of what the pack default says.

11.4 Auto-Save#

Editor.tsx debounces the Markdown text every 800ms. After a pause → PATCH .../pages/:id with new mdContent. Generation is not automatically triggered — only explicitly via button (LLM calls cost money).#