feat: add drag-and-drop functionality for flowchart nodes#7713
Conversation
Add a comprehensive drag-and-drop editor for flowchart diagrams that allows users to reposition nodes interactively with multi-select, undo/redo, and position persistence via localStorage. New modules: - CoordinateConverter: converts between viewBox and client coordinates - DragHandler: handles pointer events for single and multi-node dragging with shift-click multi-select and real-time edge updates - EdgeUpdater: updates edge paths when connected nodes are moved - MermaidDragEditor: main orchestrator tying scanning, drag, undo, and storage together - NodeScanner: discovers and monitors flowchart nodes in SVG DOM - OverrideStore: persists node position overrides to localStorage with version migration, lock support, and merge logic - UndoManager: undo/redo stack with configurable depth - types: shared TypeScript interfaces and types - index: barrel export for the interaction module - interaction.spec.ts: unit tests for coordinate conversion Demo: - demos/drag-editor-demo.html: visual demo with multi-node selection, drag, undo/redo UI, and position persistence
- Add data-source and data-target attributes to edge SVG paths in both dagre-wrapper and rendering-util edge renderers to enable the drag editor's EdgeUpdater to identify connected nodes - Export MermaidDragEditor class and related types (DragEditorOptions, OverrideData) from the public mermaid module entry point - Add /.trae/ directory to .gitignore
✅ Deploy Preview for mermaid-js ready!
To edit notification comments on pull requests, go to your Netlify project configuration. |
|
@mermaid-js/examples
mermaid
@mermaid-js/mermaid-flowchart-drag
@mermaid-js/layout-elk
@mermaid-js/layout-tidy-tree
@mermaid-js/mermaid-zenuml
@mermaid-js/parser
@mermaid-js/tiny
commit: |
Codecov Report❌ Patch coverage is Additional details and impacted files@@ Coverage Diff @@
## develop #7713 +/- ##
==========================================
- Coverage 3.26% 3.24% -0.03%
==========================================
Files 598 600 +2
Lines 60610 61093 +483
Branches 914 916 +2
==========================================
+ Hits 1981 1982 +1
- Misses 58629 59111 +482
Flags with carried forward coverage won't be shown. Click here to find out more.
🚀 New features to boost your workflow:
|
|
The latest updates on your projects. Learn more about Argos notifications ↗︎
|
- Translate all JSDoc comments from Chinese to English - Escape `>` to `→` in JSDoc to satisfy tsdoc/syntax rule - Rename rAFId -> rafId, buildEdgePathD -> buildEdgePathData - Fix cspell issue: redoable -> operations to redo
- Add dragEditor config option (boolean | DragEditorConfig) to enable drag-and-drop node repositioning for flowcharts via mermaid.render() - Wire auto-activation in mermaidAPI.ts render() — when dragEditor is enabled, bindFunctions automatically instantiates MermaidDragEditor on the rendered SVG - Fix XSS vulnerabilities in drag-editor-demo.html (DOMParser instead of innerHTML) - Add 47 unit tests covering the interaction module, including 5 auto-activation tests
knsv
left a comment
There was a problem hiding this comment.
Thanks for the substantial effort here, @BobcGn — there's a lot of careful work in this PR (multi-select drag, undo/redo, edge re-routing, persistence, an extensive demo). Before we can move toward merge though, I'd like to surface some concerns about scope and architecture, in addition to the failing CI.
CI / housekeeping
unit-test,lint,e2e (1–5),build-docs,Publish preview release, and the Netlify deploy are all failing on the latest commit. These will need to be green.- No changeset has been added (changeset-bot flagged this). A user-facing feature like this needs
pnpm changeset. - Codecov reports ~0.66% patch coverage (1,208 lines uncovered). The new
interaction.spec.tsis sizable but only coverstypes.tsand a thin slice ofCoordinateConverter— the core logic inDragHandler,EdgeUpdater,MermaidDragEditor,NodeScanner,OverrideStore, andUndoManageris essentially untested. - The PR is opened from the contributor's
developbranch into upstreamdevelop. That's not a blocker but tends to cause grief on subsequent PRs — a feature branch is much easier to live with.
Architectural concerns (the bigger items)
-
Diagram-type-specific branching inside
mermaidAPI.render(). The newif (config.dragEditor && (diagramType === 'flowchart-v2' || diagramType === 'flowchart'))block inmermaidAPI.tscouples a flowchart-only interactive feature directly into the shared render pipeline. The diagram-isolation rules inCLAUDE.md/ project conventions ask us to avoid exactly this pattern — features that apply to one diagram type shouldn't live in the cross-cutting core API. -
bindFunctionsis silently wrapped. Today, callers usingbindFunctions(el)get DOM-event hookup. After this PR, the same call also constructs aMermaidDragEditor, attaches pointer listeners, and starts writing tolocalStorage. That's a surprising side effect for downstream consumers (GitHub, GitLab, Docusaurus, Obsidian, etc.) who only opted into "render this SVG." -
localStoragein core. Mermaid is rendered server-side by GitHub/GitLab and in many Node toolchains.OverrideStorereaches forlocalStorageunguarded, which will throw or no-op in those environments, and on the client it silently mutates browser storage by default. Persistence policy should be the host application's choice, not the library's. -
Public API expansion.
MermaidDragEditor,DragEditorOptions, andOverrideDataare now exported frommermaid.ts. Once shipped, those are part of the supported API surface forever. For a non-roadmap experimental feature that's a heavy commitment. -
Cross-cutting changes to shared edge code. Both
dagre-wrapper/edges.jsandrendering-util/rendering-elements/edges.jsare modified to emitdata-source/data-targetattributes purely so the editor can re-route edges. Touching shared rendering code on behalf of a flowchart-only feature is the failure modeCLAUDE.mdcalls out as the #1 cross-diagram regression risk. -
Documentation language. The auto-generated public docs (e.g.
docs/config/setup/mermaid/classes/MermaidDragEditor.md) currently ship Chinese-language descriptions ("Mermaid 图表可视化微调主控制器"). The site is English; JSDoc on exported classes should be English so it renders consistently on mermaid.js.org. (The demo itself being in Chinese is fine.)
Suggested direction
The core question is whether this belongs inside packages/mermaid at all. Mermaid's job has always been "text → SVG"; interactive editing has historically lived in separate projects (mermaid-live-editor, mermaid-chart, etc.).
A much smaller, less invasive shape would be:
- Publish this as an external package (e.g.
@mermaid-js/drag-editor) that consumes the SVG returned bymermaid.render()and attaches its own behavior. - Keep the only upstream change minimal: optionally adding
data-source/data-targetto edges (already useful for other consumers), behind no diagram-specific branch. - Skip the global
localStorageandbindFunctionswrapping entirely — let the host app decide when/where to instantiate the editor.
That model gives you full freedom on the editor's shape, avoids the API-surface and SSR concerns, and is much easier to iterate on outside the core release cadence.
If you'd like to pursue that, I'd suggest opening an issue/discussion first so the maintainers can confirm appetite and the approach before more work goes in. Happy to help sketch what the minimal upstream change would look like if that helps.
|
Thank you for the detailed and constructive feedback! I completely understand and agree with your architectural concerns. Mermaid's core philosophy of "text → SVG" should absolutely be preserved, and I realize now that integrating heavy interactive editing, localStorage, and DOM event wrapping directly into the core API is too invasive. |
BREAKING CHANGE: Remove entire interaction module (MermaidDragEditor, DragHandler, UndoManager, OverrideStore, NodeScanner, CoordinateConverter, EdgeUpdater, types, tests) along with the dragEditor config option and auto-activation wiring in mermaidAPI.ts. Also remove the drag-editor-demo. Only the data-source and data-target attributes on SVG edge path elements are preserved — these are generic, diagram-agnostic attributes that enable future external editor integrations to map edges to their connected nodes.
Replaces the removed drag-editor-demo with a focused demo that highlights the data-source / data-target attributes on SVG edge paths. Layout puts the flowchart editor in the main central area with a sidebar showing edge data mapping tables, summary stats, and raw SVG attribute inspection.
Create packages/mermaid-flowchart-drag/ as a self-contained drag-and-drop plugin for rendered flowchart SVGs. Works purely on SVG DOM — no runtime dependency on mermaid internals. Includes smooth bezier edge recalculation, label repositioning, undo/redo stack, and enable/disable/destroy lifecycle. Zero intrusion into main mermaid source code. Only new files added.
Scope type-checked ESLint configs to .ts files only, fix docs.mts readFileSync path for vitest CWD-independence, and add missing cspell term 'lerp'.
Update pnpm-lock.yaml to match mermaid-flowchart-drag package.json dependencies, and replace innerHTML with safe DOM API in demo error handler.
|
Hi @knsv , I've checked the pending After inspecting the diffs closely, I can confirm there are no structural layout breaks. The flags are catching sub-pixel shifts/anti-aliasing differences (the text and icons have slight visual ghosts in the diff). This appears to be a minor rendering recalculation triggered by adding the new Since I followed the advice to keep this change generic (without diagram-specific branching) and the visual baseline remains structurally intact, could a maintainer please review and approve the Argos build when possible? Thanks! |
|
@BobcGn Reviewed and approved the argos test |
|
@ashishjain0512 After you manually approved it through Argos last time, today when I was updating the branch, Argos encountered the same problem as last time. Could you approve it again? |
|
It has been done. We are in the process of fixing these flaky tests. |
📑 Summary
This PR introduces a new interactive feature: Node Drag-and-Drop for Flowcharts.
Previously, users were limited by the default layout engine's positioning. This feature allows users to manually reposition nodes within the canvas, providing greater flexibility for organizing complex diagrams and enhancing the overall user experience for custom visualizations.
📏 Design Decisions
📋 Tasks
Make sure you
MERMAID_RELEASE_VERSIONis used for all new features.pnpm changesetand following the prompts. Changesets that add features should beminorand those that fix bugs should bepatch. Please prefix changeset messages withfeat:,fix:, orchore:.