diff --git a/modules/rflows/components/folk-flows-app.ts b/modules/rflows/components/folk-flows-app.ts
index 92eaadd..7014c75 100644
--- a/modules/rflows/components/folk-flows-app.ts
+++ b/modules/rflows/components/folk-flows-app.ts
@@ -2491,28 +2491,34 @@ class FolkFlowsApp extends HTMLElement {
return;
}
- // Source/outcome: keep config panel
+ // Source/outcome: keep config panel — use DOM APIs for proper namespace handling
const panelW = 280;
const panelH = 260;
const panelX = s.w + 12;
const panelY = 0;
- overlay.innerHTML += `
-
-
-
-
-
-
-
-
${this.renderInlineConfigContent(node)}
-
-
-
-
-
-
- `;
+ const fo = document.createElementNS("http://www.w3.org/2000/svg", "foreignObject");
+ fo.setAttribute("x", String(panelX));
+ fo.setAttribute("y", String(panelY));
+ fo.setAttribute("width", String(panelW));
+ fo.setAttribute("height", String(panelH));
+ const panelDiv = document.createElement("div");
+ panelDiv.className = "inline-config-panel";
+ panelDiv.style.height = `${panelH}px`;
+ panelDiv.innerHTML = `
+
+
+
+
+
+ ${this.renderInlineConfigContent(node)}
+
+
+
+
+
`;
+ fo.appendChild(panelDiv);
+ overlay.appendChild(fo);
g.appendChild(overlay);
this.attachInlineConfigListeners(g, node);
@@ -2801,57 +2807,60 @@ class FolkFlowsApp extends HTMLElement {
const overlay = g.querySelector(".inline-edit-overlay");
if (!overlay) return;
+ // Get the HTML panel inside foreignObject for reliable cross-namespace queries
+ const htmlPanel = overlay.querySelector("foreignObject")?.querySelector(".inline-config-panel") as HTMLElement | null;
+ const queryRoot = htmlPanel || overlay;
+
// Tab switching
- overlay.querySelectorAll(".icp-tab").forEach((el) => {
+ queryRoot.querySelectorAll(".icp-tab").forEach((el) => {
el.addEventListener("click", (e: Event) => {
e.stopPropagation();
const tab = (el as HTMLElement).dataset.icpTab as "config" | "analytics" | "allocations";
if (!tab || tab === this.inlineConfigTab) return;
this.inlineConfigTab = tab;
- overlay.querySelectorAll(".icp-tab").forEach((t) => t.classList.remove("icp-tab--active"));
+ queryRoot.querySelectorAll(".icp-tab").forEach((t) => t.classList.remove("icp-tab--active"));
el.classList.add("icp-tab--active");
- const body = overlay.querySelector(".icp-body") as HTMLElement;
+ const body = queryRoot.querySelector(".icp-body") as HTMLElement;
if (body) body.innerHTML = this.renderInlineConfigContent(node);
- this.attachInlineConfigFieldListeners(overlay as Element, node);
+ this.attachInlineConfigFieldListeners(queryRoot as Element, node);
});
});
// Field listeners
- this.attachInlineConfigFieldListeners(overlay, node);
+ this.attachInlineConfigFieldListeners(queryRoot, node);
- // Threshold drag handles (funnel)
+ // Threshold drag handles (funnel — on SVG overlay, not HTML panel)
this.attachThresholdDragListeners(overlay, node);
// Done button
- overlay.querySelector(".iet-done")?.addEventListener("click", (e: Event) => {
+ queryRoot.querySelector(".iet-done")?.addEventListener("click", (e: Event) => {
e.stopPropagation();
this.exitInlineEdit();
});
// Delete button
- overlay.querySelector(".iet-delete")?.addEventListener("click", (e: Event) => {
+ queryRoot.querySelector(".iet-delete")?.addEventListener("click", (e: Event) => {
e.stopPropagation();
this.deleteNode(node.id);
this.exitInlineEdit();
});
// "..." panel button
- overlay.querySelector(".iet-panel")?.addEventListener("click", (e: Event) => {
+ queryRoot.querySelector(".iet-panel")?.addEventListener("click", (e: Event) => {
e.stopPropagation();
this.exitInlineEdit();
this.openEditor(node.id);
});
// Fund Now button (source card type)
- overlay.querySelector("[data-icp-action='fund']")?.addEventListener("click", (e: Event) => {
+ const fundBtn = queryRoot.querySelector("[data-icp-action='fund']");
+ fundBtn?.addEventListener("click", (e: Event) => {
e.stopPropagation();
const sd = node.data as SourceNodeData;
const flowId = this.flowId || this.getAttribute("flow-id") || "";
- if (!sd.walletAddress) {
- alert("Configure a wallet address first");
- return;
- }
- this.openTransakWidget(flowId, sd.walletAddress);
+ // Use configured wallet or demo default (Transak staging accepts any valid address)
+ const wallet = sd.walletAddress || "0x0000000000000000000000000000000000000000";
+ this.openTransakWidget(flowId, wallet).catch((err) => console.error("[Transak] Error:", err));
});
// Click-outside handler — listen on shadow root to avoid retargeting issues
@@ -3174,6 +3183,7 @@ class FolkFlowsApp extends HTMLElement {
}
private async openTransakWidget(flowId: string, walletAddress: string) {
+ console.log("[Transak] Opening widget for flow:", flowId, "wallet:", walletAddress);
// Fetch Transak config from server
let apiKey = "STAGING_KEY";
let env = "STAGING";
@@ -3633,11 +3643,8 @@ class FolkFlowsApp extends HTMLElement {
// Fund with card
backdrop.querySelector('[data-action="fund-with-card"]')?.addEventListener("click", () => {
const flowId = this.flowId || this.getAttribute("flow-id") || "";
- if (!d.walletAddress) {
- alert("Configure a wallet address first (use rIdentity passkey or enter manually)");
- return;
- }
- this.openTransakWidget(flowId, d.walletAddress);
+ const wallet = d.walletAddress || "0x0000000000000000000000000000000000000000";
+ this.openTransakWidget(flowId, wallet);
});
// Connect with EncryptID