fix: single-click inline editing for rflows nodes

- Single click on a node now opens the inline config panel directly
  (instead of requiring double-click which was broken by pointer capture)
- New nodes from toolbar open inline editor instead of side panel
- Click-outside handler uses shadow root instead of document to avoid
  event retargeting that dismissed the panel on any interaction

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Jeff Emmett 2026-03-05 14:07:31 -08:00
parent bfb1e3d0d7
commit ecebf84bcc
1 changed files with 9 additions and 13 deletions

View File

@ -1172,11 +1172,12 @@ class FolkFlowsApp extends HTMLElement {
nodeDragStarted = false; nodeDragStarted = false;
svg.classList.remove("dragging"); svg.classList.remove("dragging");
// Single click = select only (inline edit on double-click) // Single click = select + open inline editor
if (!wasDragged) { if (!wasDragged) {
this.selectedNodeId = clickedNodeId; this.selectedNodeId = clickedNodeId;
this.selectedEdgeKey = null; this.selectedEdgeKey = null;
this.updateSelectionHighlight(); this.updateSelectionHighlight();
this.enterInlineEdit(clickedNodeId);
} else { } else {
this.scheduleSave(); this.scheduleSave();
} }
@ -2727,21 +2728,16 @@ class FolkFlowsApp extends HTMLElement {
this.openTransakWidget(flowId, sd.walletAddress); this.openTransakWidget(flowId, sd.walletAddress);
}); });
// Click-outside handler — use composedPath() to see through shadow DOM // Click-outside handler — listen on shadow root to avoid retargeting issues
const clickOutsideHandler = (e: PointerEvent) => { const clickOutsideHandler = (e: Event) => {
const path = e.composedPath(); const target = e.target as Element;
const hitNode = path.some((el) => { if (!target.closest(`[data-node-id="${node.id}"]`) && !target.closest(".inline-config-panel")) {
const elem = el as HTMLElement;
return elem.dataset?.nodeId === node.id ||
elem.classList?.contains?.("inline-config-panel");
});
if (!hitNode) {
this.exitInlineEdit(); this.exitInlineEdit();
document.removeEventListener("pointerdown", clickOutsideHandler as EventListener, true); this.shadow.removeEventListener("pointerdown", clickOutsideHandler, true);
} }
}; };
setTimeout(() => { setTimeout(() => {
document.addEventListener("pointerdown", clickOutsideHandler as EventListener, true); this.shadow.addEventListener("pointerdown", clickOutsideHandler, true);
}, 100); }, 100);
} }
@ -3557,7 +3553,7 @@ class FolkFlowsApp extends HTMLElement {
this.drawCanvasContent(); this.drawCanvasContent();
this.selectedNodeId = id; this.selectedNodeId = id;
this.updateSelectionHighlight(); this.updateSelectionHighlight();
this.openEditor(id); this.enterInlineEdit(id);
this.scheduleSave(); this.scheduleSave();
} }