Inline block-swap live-preview markdown editor

Inline block-swap live-preview markdown editor

#34 in Riparion/riparion-cms — merged 2026-06-02

Summary

Replaces the side-by-side markdown preview with an inline, Typora/Obsidian-style block-swap editor: the document renders as styled markdown blocks, and the block you're editing swaps to a raw <textarea> in place. Pure Dioxus — no contenteditable, no JS engine (just web-sys for caret/selection).

The editor lives in its own repo (Riparion/riparion-editor) and is consumed here as a git dependency, like arium-dioxus and dx-dnd.

Editor (riparion-editor crate)

  • Block-swap editing — rendered blocks; the active one is a textarea. App-agnostic: the host injects render_block + is_atomic, so the crate pins no markdown dialect. body stays the single source of truth (save path unchanged).
  • Lossless block modelsplit_blocks/join_blocks round-trip byte-for-byte (respecting fenced code + atomic embed lines).
  • Keyboard editing (web): double-Enter starts a new block below with the caret in it; column-preserving cross-block arrow navigation; selection formatting — type * _ ` ~ to wrap, plus Cmd/Ctrl+B / +I / +K (link).
  • Drag-to-reorder via dx-dnd; auto-growing textarea; discoverable + New block.

App integration

  • MarkdownPane gains a Live / Raw toggle (Live default mounts BlockEditor wired to the real parse_body + render_segments pipeline); public signature unchanged, so posts.rs is untouched.
  • mdx::is_embed_line exposes embed detection for the editor's atomic predicate.
  • Syntax highlighting in the live preview: a #[post("/api/highlight-block")] server fn reuses the published-page parse_body_highlighted (syntect stays server-only); EditorBlock fetches highlighted segments only for code-fence blocks and renders prose instantly client-side.
  • Repo is no longer a workspace (the editor moved out); reverts to a plain package.

Verification

  • clippy -D warnings clean: wasm web, server sqlite, server postgres
  • cargo fmt --check clean · server tests pass (26)
  • Manual end-to-end steps captured locally in TODO_VERIFICATION.md (gitignored)

Note: interactive behaviors (caret follow, arrow nav, drag, selection formatting, highlighting) are best confirmed by running the app at /admin/posts/new.

🤖 Generated with Claude Code

Last updated 2026-06-02