feat(flowchart): replace window.prompt with inline modal (C1)

The standalone flowchart generator still used window.prompt() for
editing edge kind/label and changing node kind — defeating the v4.9.9
modal work that's already in flowchart-bundle.js.

This commit switches to the existing window.FlowchartModals helpers:
  - onEdgeClick now does two sequential promptInline calls (kind,
    then label) instead of two blocking window.prompt calls.
  - onShapeMenu uses promptInline for node-kind change.
  - onEmptyClick (new) replaces the canvas's old 'auto-add a process
    node labelled Node on any empty click' behaviour. The canvas
    now hands off x/y to the controller, which prompts for kind +
    label before adding.

Canvas change is one line: drop the auto-add and call opts.onEmptyClick.

followups in this batch:
  - select/dropdown fields in the modal (currently text-only inputs)
  - edge connection geometry (centre-to-centre → boundary)
  - connect-mode preview line
  - canvas-owned selection state (DOM .selected is fragile)
  - undo/redo toolbar + counter
  - edge label auto-size + theme-safe background
  - zoom/pan, snap-to-grid, copy/paste, mermaid re-import, file IO

Amit Haridas
This commit is contained in:
Amit Haridas
2026-09-30 21:22:22 +05:30
parent d5efdfa8d9
commit 855dfcd9f5
2 changed files with 50 additions and 9 deletions
+6 -2
View File
@@ -223,12 +223,16 @@ function createCanvas(container, store, opts = {}) {
ev.preventDefault();
return;
}
// Click on empty canvas: add a process node at the click point.
// Click on empty canvas: hand off to the controller via onEmptyClick so it
// can prompt the user for the shape kind + label. v4.13.0 — the canvas
// no longer auto-creates a process node with placeholder label "Node".
if (ev.target === svg || ev.target === nodesLayer || ev.target === edgesLayer) {
const p = getSvgPoint(ev.clientX, ev.clientY);
const x = Math.max(0, p.x - DEFAULT_WIDTH / 2);
const y = Math.max(0, p.y - DEFAULT_HEIGHT / 2);
store.addNode({ kind: 'process', x, y, label: 'Node' });
if (typeof opts.onEmptyClick === 'function') {
opts.onEmptyClick(x, y, ev);
}
ev.preventDefault();
}
}