@designa8/vibedesign-stripe-deepseek-85ea 0.1.2 → 0.1.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/dist/index.cjs +294 -52
- package/dist/index.js +294 -52
- package/dist/styles.css +3 -0
- package/package.json +1 -1
- package/src/atoms/PaymentRoutingCanvas/PaymentRoutingCanvas.tsx +417 -49
- package/src/atoms/PaymentRoutingCanvas/preview.tsx +26 -10
- package/src/atoms/RoutingNode/RoutingNode.tsx +18 -13
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# @designa8/vibedesign-stripe-deepseek-85ea
|
|
2
2
|
|
|
3
|
-
Complete design system generated by Atoms Design, version **0.1.
|
|
3
|
+
Complete design system generated by Atoms Design, version **0.1.4**.
|
|
4
4
|
Tokens, atoms, molecules, organisms, and templates — import from the package root;
|
|
5
5
|
never hardcode visual values in consumer code.
|
|
6
6
|
|
package/dist/index.cjs
CHANGED
|
@@ -11854,7 +11854,7 @@ var RoutingNode = React60.forwardRef(
|
|
|
11854
11854
|
...rest
|
|
11855
11855
|
}, ref) => {
|
|
11856
11856
|
const glyph5 = icon ?? defaultIconByType[type];
|
|
11857
|
-
const
|
|
11857
|
+
const highlighted = selected || active;
|
|
11858
11858
|
return /* @__PURE__ */ (0, import_jsx_runtime60.jsxs)(
|
|
11859
11859
|
"div",
|
|
11860
11860
|
{
|
|
@@ -11863,6 +11863,7 @@ var RoutingNode = React60.forwardRef(
|
|
|
11863
11863
|
style: { width: NODE_WIDTH, ...style },
|
|
11864
11864
|
"data-node-type": type,
|
|
11865
11865
|
"data-selected": selected || void 0,
|
|
11866
|
+
"data-active": active || void 0,
|
|
11866
11867
|
...rest,
|
|
11867
11868
|
children: [
|
|
11868
11869
|
/* @__PURE__ */ (0, import_jsx_runtime60.jsxs)(
|
|
@@ -11871,8 +11872,8 @@ var RoutingNode = React60.forwardRef(
|
|
|
11871
11872
|
className: cn52(
|
|
11872
11873
|
"flex items-stretch overflow-hidden rounded-md border bg-surface",
|
|
11873
11874
|
"transition duration-150 ease-out",
|
|
11874
|
-
disabled ? "border-hairline-soft opacity-50" : unreachable ? "border-dashed border-semantic-warning" : selected
|
|
11875
|
-
dragging ? "shadow-lg" :
|
|
11875
|
+
disabled ? "border-hairline-soft opacity-50" : selected && unreachable ? "border-dashed border-semantic-warning ring-2 ring-primary" : selected ? "border-primary ring-2 ring-primary" : unreachable ? "border-dashed border-semantic-warning" : active ? "border-primary ring-2 ring-primary/25" : conflict ? "border-semantic-error/50" : "border-hairline",
|
|
11876
|
+
dragging ? "shadow-lg" : highlighted ? "shadow-md" : "shadow-sm",
|
|
11876
11877
|
disabled ? "" : "group-hover/node:border-hairline-strong group-hover/node:shadow-md"
|
|
11877
11878
|
),
|
|
11878
11879
|
children: [
|
|
@@ -11928,7 +11929,7 @@ var RoutingNode = React60.forwardRef(
|
|
|
11928
11929
|
"aria-hidden": "true",
|
|
11929
11930
|
className: cn52(
|
|
11930
11931
|
"absolute -left-xs top-1/2 size-sm -translate-y-1/2 rounded-full border-2 transition-colors duration-150 ease-out",
|
|
11931
|
-
|
|
11932
|
+
highlighted ? "border-primary bg-primary" : "border-hairline-strong bg-surface"
|
|
11932
11933
|
)
|
|
11933
11934
|
}
|
|
11934
11935
|
),
|
|
@@ -11938,7 +11939,7 @@ var RoutingNode = React60.forwardRef(
|
|
|
11938
11939
|
"aria-hidden": "true",
|
|
11939
11940
|
className: cn52(
|
|
11940
11941
|
"absolute -right-xs top-1/2 size-sm -translate-y-1/2 rounded-full border-2 transition-colors duration-150 ease-out",
|
|
11941
|
-
|
|
11942
|
+
highlighted ? "border-primary bg-primary" : "border-hairline-strong bg-surface"
|
|
11942
11943
|
)
|
|
11943
11944
|
}
|
|
11944
11945
|
),
|
|
@@ -11961,7 +11962,7 @@ var RoutingNode = React60.forwardRef(
|
|
|
11961
11962
|
size: "inline",
|
|
11962
11963
|
disabled,
|
|
11963
11964
|
"aria-label": ariaLabel ?? `${eyebrowByType2[type]}, ${title}`,
|
|
11964
|
-
"aria-
|
|
11965
|
+
"aria-pressed": selected,
|
|
11965
11966
|
onClick: onNodeSelect,
|
|
11966
11967
|
className: "absolute inset-0 rounded-md focus-visible:ring-focus-blue focus-visible:ring-offset-0",
|
|
11967
11968
|
children: /* @__PURE__ */ (0, import_jsx_runtime60.jsx)("span", { className: "sr-only", children: title })
|
|
@@ -12106,6 +12107,10 @@ var SCENE_H = 342;
|
|
|
12106
12107
|
var PLANE_H = 372;
|
|
12107
12108
|
var PLANE_PAD = 18;
|
|
12108
12109
|
var PANEL_W = 296;
|
|
12110
|
+
var SNAP = 8;
|
|
12111
|
+
var MARQUEE_MIN = 4;
|
|
12112
|
+
var clampTo = (value, min, max) => Math.min(Math.max(value, min), max);
|
|
12113
|
+
var boxesIntersect = (a, b) => a.x < b.x + b.w && a.x + a.w > b.x && a.y < b.y + b.h && a.y + a.h > b.y;
|
|
12109
12114
|
var DEFAULT_NODES = [
|
|
12110
12115
|
{
|
|
12111
12116
|
id: "source",
|
|
@@ -12218,6 +12223,7 @@ var DEFAULT_SAMPLES = [
|
|
|
12218
12223
|
]
|
|
12219
12224
|
}
|
|
12220
12225
|
];
|
|
12226
|
+
var DEFAULT_SELECTION = ["brand"];
|
|
12221
12227
|
var computeIssues = (nodes, edges) => {
|
|
12222
12228
|
const issues = [];
|
|
12223
12229
|
const seenFields = /* @__PURE__ */ new Map();
|
|
@@ -12256,6 +12262,7 @@ var computeIssues = (nodes, edges) => {
|
|
|
12256
12262
|
});
|
|
12257
12263
|
return issues;
|
|
12258
12264
|
};
|
|
12265
|
+
var sameIds = (a, b) => a.length === b.length && a.every((id, index) => id === b[index]);
|
|
12259
12266
|
var PaymentRoutingCanvas = React62.forwardRef(
|
|
12260
12267
|
({
|
|
12261
12268
|
nodes,
|
|
@@ -12263,6 +12270,9 @@ var PaymentRoutingCanvas = React62.forwardRef(
|
|
|
12263
12270
|
onNodesChange,
|
|
12264
12271
|
onEdgesChange,
|
|
12265
12272
|
onNodeSelect,
|
|
12273
|
+
selectedNodeIds,
|
|
12274
|
+
defaultSelectedNodeIds,
|
|
12275
|
+
onSelectionChange,
|
|
12266
12276
|
sampleTransaction,
|
|
12267
12277
|
onSimulationStep,
|
|
12268
12278
|
onValidationChange,
|
|
@@ -12273,7 +12283,7 @@ var PaymentRoutingCanvas = React62.forwardRef(
|
|
|
12273
12283
|
const graphEdges = edges ?? DEFAULT_EDGES;
|
|
12274
12284
|
const samples = sampleTransaction ?? DEFAULT_SAMPLES;
|
|
12275
12285
|
const [localNodes, setLocalNodes] = React62.useState(incomingNodes);
|
|
12276
|
-
const [
|
|
12286
|
+
const [panelNodeId, setPanelNodeId] = React62.useState("brand");
|
|
12277
12287
|
const [panelOpen, setPanelOpen] = React62.useState(true);
|
|
12278
12288
|
const [zoom, setZoom] = React62.useState(1);
|
|
12279
12289
|
const [fit, setFit] = React62.useState(1);
|
|
@@ -12291,15 +12301,42 @@ var PaymentRoutingCanvas = React62.forwardRef(
|
|
|
12291
12301
|
const [replaying, setReplaying] = React62.useState(false);
|
|
12292
12302
|
const [focusedId, setFocusedId] = React62.useState(null);
|
|
12293
12303
|
const [anchor, setAnchor] = React62.useState({ top: 0, right: 16 });
|
|
12304
|
+
const controlledSelection = selectedNodeIds !== void 0;
|
|
12305
|
+
const [internalSelection, setInternalSelection] = React62.useState(
|
|
12306
|
+
() => defaultSelectedNodeIds ?? DEFAULT_SELECTION
|
|
12307
|
+
);
|
|
12308
|
+
const selection = controlledSelection ? selectedNodeIds : internalSelection;
|
|
12309
|
+
const selectionRef = React62.useRef(selection);
|
|
12310
|
+
selectionRef.current = selection;
|
|
12311
|
+
const onSelectionChangeRef = React62.useRef(onSelectionChange);
|
|
12312
|
+
onSelectionChangeRef.current = onSelectionChange;
|
|
12313
|
+
const [marqueeBox, setMarqueeBox] = React62.useState(null);
|
|
12314
|
+
const [marqueeIds, setMarqueeIds] = React62.useState(null);
|
|
12315
|
+
const marqueeRef = React62.useRef(null);
|
|
12316
|
+
const [modifierHeld, setModifierHeld] = React62.useState(false);
|
|
12294
12317
|
const rootRef = React62.useRef(null);
|
|
12295
12318
|
const planeRef = React62.useRef(null);
|
|
12296
12319
|
const triggerRef = React62.useRef(null);
|
|
12297
12320
|
const nodeRefs = React62.useRef({});
|
|
12298
12321
|
const suppressClick = React62.useRef(false);
|
|
12299
12322
|
const nodeDragActive = React62.useRef(false);
|
|
12323
|
+
const nodesRef = React62.useRef(localNodes);
|
|
12324
|
+
nodesRef.current = localNodes;
|
|
12300
12325
|
React62.useEffect(() => {
|
|
12301
12326
|
setLocalNodes(incomingNodes);
|
|
12302
12327
|
}, [incomingNodes]);
|
|
12328
|
+
React62.useEffect(() => {
|
|
12329
|
+
const syncModifier = (event) => setModifierHeld(Boolean(event.metaKey || event.ctrlKey));
|
|
12330
|
+
const releaseModifier = () => setModifierHeld(false);
|
|
12331
|
+
window.addEventListener("keydown", syncModifier);
|
|
12332
|
+
window.addEventListener("keyup", syncModifier);
|
|
12333
|
+
window.addEventListener("blur", releaseModifier);
|
|
12334
|
+
return () => {
|
|
12335
|
+
window.removeEventListener("keydown", syncModifier);
|
|
12336
|
+
window.removeEventListener("keyup", syncModifier);
|
|
12337
|
+
window.removeEventListener("blur", releaseModifier);
|
|
12338
|
+
};
|
|
12339
|
+
}, []);
|
|
12303
12340
|
React62.useEffect(() => {
|
|
12304
12341
|
const plane = planeRef.current;
|
|
12305
12342
|
if (!plane) return;
|
|
@@ -12367,56 +12404,127 @@ var PaymentRoutingCanvas = React62.forwardRef(
|
|
|
12367
12404
|
x: node.x + (side === "out" ? NODE_W : 0),
|
|
12368
12405
|
y: node.y + (node.h ?? NODE_H) / 2
|
|
12369
12406
|
});
|
|
12370
|
-
const focusedNode =
|
|
12407
|
+
const focusedNode = panelNodeId ? nodeById.get(panelNodeId) : void 0;
|
|
12408
|
+
const selectionSet = React62.useMemo(() => new Set(selection), [selection]);
|
|
12409
|
+
const marqueeSet = React62.useMemo(() => new Set(marqueeIds ?? []), [marqueeIds]);
|
|
12410
|
+
const commitSelection = React62.useCallback(
|
|
12411
|
+
(next) => {
|
|
12412
|
+
const unique = next.filter((id, index) => next.indexOf(id) === index);
|
|
12413
|
+
if (sameIds(unique, selectionRef.current)) return;
|
|
12414
|
+
selectionRef.current = unique;
|
|
12415
|
+
if (!controlledSelection) setInternalSelection(unique);
|
|
12416
|
+
onSelectionChangeRef.current?.(unique);
|
|
12417
|
+
},
|
|
12418
|
+
[controlledSelection]
|
|
12419
|
+
);
|
|
12420
|
+
const openNodePanel = (node) => {
|
|
12421
|
+
commitSelection([node.id]);
|
|
12422
|
+
setPanelNodeId(node.id);
|
|
12423
|
+
setPanelOpen(true);
|
|
12424
|
+
onNodeSelect?.(node);
|
|
12425
|
+
};
|
|
12371
12426
|
const selectNode = (node) => {
|
|
12372
12427
|
if (suppressClick.current) {
|
|
12373
12428
|
suppressClick.current = false;
|
|
12374
12429
|
return;
|
|
12375
12430
|
}
|
|
12376
|
-
|
|
12377
|
-
setPanelOpen(true);
|
|
12378
|
-
onNodeSelect?.(node);
|
|
12431
|
+
openNodePanel(node);
|
|
12379
12432
|
};
|
|
12380
12433
|
const closePanel = () => {
|
|
12381
|
-
const previous =
|
|
12434
|
+
const previous = panelNodeId;
|
|
12382
12435
|
setPanelOpen(false);
|
|
12383
|
-
|
|
12436
|
+
setPanelNodeId(null);
|
|
12384
12437
|
onNodeSelect?.(null);
|
|
12385
12438
|
if (previous) nodeRefs.current[previous]?.querySelector("button")?.focus();
|
|
12386
12439
|
};
|
|
12440
|
+
const clearSelection = () => {
|
|
12441
|
+
commitSelection([]);
|
|
12442
|
+
if (panelOpen) {
|
|
12443
|
+
setPanelOpen(false);
|
|
12444
|
+
setPanelNodeId(null);
|
|
12445
|
+
onNodeSelect?.(null);
|
|
12446
|
+
}
|
|
12447
|
+
};
|
|
12448
|
+
const nudgeSelection = (key) => {
|
|
12449
|
+
const ids = new Set(selectionRef.current);
|
|
12450
|
+
if (ids.size === 0) return;
|
|
12451
|
+
const dx = key === "ArrowLeft" ? -SNAP : key === "ArrowRight" ? SNAP : 0;
|
|
12452
|
+
const dy = key === "ArrowUp" ? -SNAP : key === "ArrowDown" ? SNAP : 0;
|
|
12453
|
+
if (!dx && !dy) return;
|
|
12454
|
+
const next = nodesRef.current.map(
|
|
12455
|
+
(node) => ids.has(node.id) ? { ...node, x: node.x + dx, y: node.y + dy } : node
|
|
12456
|
+
);
|
|
12457
|
+
setLocalNodes(next);
|
|
12458
|
+
onNodesChange?.(next);
|
|
12459
|
+
onEdgesChange?.(graphEdges);
|
|
12460
|
+
};
|
|
12387
12461
|
const beginDrag = (event, node) => {
|
|
12388
12462
|
if (event.button !== 0) return;
|
|
12389
12463
|
event.stopPropagation();
|
|
12464
|
+
suppressClick.current = false;
|
|
12390
12465
|
nodeDragActive.current = true;
|
|
12466
|
+
const additive = event.metaKey || event.ctrlKey;
|
|
12467
|
+
const current = selectionRef.current;
|
|
12468
|
+
const isIn = current.includes(node.id);
|
|
12469
|
+
let dragIds;
|
|
12470
|
+
let deselectOnClick = false;
|
|
12471
|
+
let openOnClick = false;
|
|
12472
|
+
if (additive) {
|
|
12473
|
+
if (isIn) {
|
|
12474
|
+
dragIds = current;
|
|
12475
|
+
deselectOnClick = true;
|
|
12476
|
+
} else {
|
|
12477
|
+
dragIds = [...current, node.id];
|
|
12478
|
+
commitSelection(dragIds);
|
|
12479
|
+
}
|
|
12480
|
+
} else if (isIn && current.length > 1) {
|
|
12481
|
+
dragIds = current;
|
|
12482
|
+
openOnClick = true;
|
|
12483
|
+
} else {
|
|
12484
|
+
dragIds = [node.id];
|
|
12485
|
+
if (!(current.length === 1 && current[0] === node.id)) commitSelection([node.id]);
|
|
12486
|
+
openOnClick = true;
|
|
12487
|
+
}
|
|
12488
|
+
const dragged = new Set(dragIds);
|
|
12489
|
+
const origins = /* @__PURE__ */ new Map();
|
|
12490
|
+
nodesRef.current.forEach((item) => {
|
|
12491
|
+
if (dragged.has(item.id)) origins.set(item.id, { x: item.x, y: item.y });
|
|
12492
|
+
});
|
|
12391
12493
|
const startX = event.clientX;
|
|
12392
12494
|
const startY = event.clientY;
|
|
12393
12495
|
const scale2 = fit * zoom || 1;
|
|
12394
12496
|
let moved = false;
|
|
12497
|
+
let finalNodes = null;
|
|
12395
12498
|
const move = (moveEvent) => {
|
|
12396
|
-
const
|
|
12397
|
-
const
|
|
12398
|
-
if (!moved && Math.abs(
|
|
12499
|
+
const rawX = (moveEvent.clientX - startX) / scale2;
|
|
12500
|
+
const rawY = (moveEvent.clientY - startY) / scale2;
|
|
12501
|
+
if (!moved && Math.abs(rawX) + Math.abs(rawY) < 4) return;
|
|
12399
12502
|
moved = true;
|
|
12400
|
-
|
|
12401
|
-
|
|
12402
|
-
|
|
12403
|
-
|
|
12404
|
-
|
|
12405
|
-
|
|
12406
|
-
|
|
12407
|
-
|
|
12408
|
-
);
|
|
12503
|
+
const dx = Math.round(rawX / SNAP) * SNAP;
|
|
12504
|
+
const dy = Math.round(rawY / SNAP) * SNAP;
|
|
12505
|
+
const next = nodesRef.current.map((item) => {
|
|
12506
|
+
const origin = origins.get(item.id);
|
|
12507
|
+
return origin ? { ...item, x: origin.x + dx, y: origin.y + dy } : item;
|
|
12508
|
+
});
|
|
12509
|
+
finalNodes = next;
|
|
12510
|
+
setLocalNodes(next);
|
|
12409
12511
|
};
|
|
12410
12512
|
const end = () => {
|
|
12411
12513
|
nodeDragActive.current = false;
|
|
12412
12514
|
window.removeEventListener("pointermove", move);
|
|
12413
|
-
if (!moved) return;
|
|
12414
12515
|
suppressClick.current = true;
|
|
12415
|
-
|
|
12416
|
-
|
|
12417
|
-
|
|
12418
|
-
|
|
12419
|
-
|
|
12516
|
+
if (moved) {
|
|
12517
|
+
if (finalNodes) {
|
|
12518
|
+
onNodesChange?.(finalNodes);
|
|
12519
|
+
onEdgesChange?.(graphEdges);
|
|
12520
|
+
}
|
|
12521
|
+
return;
|
|
12522
|
+
}
|
|
12523
|
+
if (deselectOnClick) {
|
|
12524
|
+
commitSelection(selectionRef.current.filter((id) => id !== node.id));
|
|
12525
|
+
return;
|
|
12526
|
+
}
|
|
12527
|
+
if (openOnClick) openNodePanel(node);
|
|
12420
12528
|
};
|
|
12421
12529
|
window.addEventListener("pointermove", move);
|
|
12422
12530
|
window.addEventListener("pointerup", end, { once: true });
|
|
@@ -12427,16 +12535,106 @@ var PaymentRoutingCanvas = React62.forwardRef(
|
|
|
12427
12535
|
const startX = event.clientX;
|
|
12428
12536
|
const startY = event.clientY;
|
|
12429
12537
|
const origin = pan;
|
|
12538
|
+
let moved = false;
|
|
12430
12539
|
const move = (moveEvent) => {
|
|
12431
|
-
|
|
12432
|
-
|
|
12433
|
-
|
|
12434
|
-
|
|
12540
|
+
const dx = moveEvent.clientX - startX;
|
|
12541
|
+
const dy = moveEvent.clientY - startY;
|
|
12542
|
+
if (!moved && Math.abs(dx) + Math.abs(dy) < 4) return;
|
|
12543
|
+
moved = true;
|
|
12544
|
+
setPan({ x: origin.x + dx, y: origin.y + dy });
|
|
12545
|
+
};
|
|
12546
|
+
const end = () => {
|
|
12547
|
+
window.removeEventListener("pointermove", move);
|
|
12548
|
+
if (!moved) clearSelection();
|
|
12435
12549
|
};
|
|
12436
|
-
const end = () => window.removeEventListener("pointermove", move);
|
|
12437
12550
|
window.addEventListener("pointermove", move);
|
|
12438
12551
|
window.addEventListener("pointerup", end, { once: true });
|
|
12439
12552
|
};
|
|
12553
|
+
const beginMarquee = (event) => {
|
|
12554
|
+
if (event.button !== 0) return;
|
|
12555
|
+
if (nodeDragActive.current) return;
|
|
12556
|
+
const plane = planeRef.current;
|
|
12557
|
+
if (!plane) return;
|
|
12558
|
+
const box = plane.getBoundingClientRect();
|
|
12559
|
+
if (!box.width || !box.height) return;
|
|
12560
|
+
const gestureScale = fit * zoom || 1;
|
|
12561
|
+
const originX = clampTo(event.clientX - box.left, 0, box.width);
|
|
12562
|
+
const originY = clampTo(event.clientY - box.top, 0, box.height);
|
|
12563
|
+
const gesture = {
|
|
12564
|
+
originX,
|
|
12565
|
+
originY,
|
|
12566
|
+
box: { left: box.left, top: box.top, width: box.width, height: box.height },
|
|
12567
|
+
offsetX: PLANE_PAD + pan.x,
|
|
12568
|
+
offsetY: Math.max((planeHeight - SCENE_H * gestureScale) / 2, 0) + pan.y,
|
|
12569
|
+
scale: gestureScale,
|
|
12570
|
+
base: selectionRef.current,
|
|
12571
|
+
rect: { x: originX, y: originY, w: 0, h: 0 }
|
|
12572
|
+
};
|
|
12573
|
+
marqueeRef.current = gesture;
|
|
12574
|
+
setMarqueeBox(gesture.rect);
|
|
12575
|
+
setMarqueeIds([]);
|
|
12576
|
+
const hitsFor = (rect) => {
|
|
12577
|
+
const scene = {
|
|
12578
|
+
x: (rect.x - gesture.offsetX) / gesture.scale,
|
|
12579
|
+
y: (rect.y - gesture.offsetY) / gesture.scale,
|
|
12580
|
+
w: rect.w / gesture.scale,
|
|
12581
|
+
h: rect.h / gesture.scale
|
|
12582
|
+
};
|
|
12583
|
+
return nodesRef.current.filter(
|
|
12584
|
+
(node) => boxesIntersect(scene, {
|
|
12585
|
+
x: node.x,
|
|
12586
|
+
y: node.y,
|
|
12587
|
+
w: NODE_W,
|
|
12588
|
+
h: node.h ?? NODE_H
|
|
12589
|
+
})
|
|
12590
|
+
).map((node) => node.id);
|
|
12591
|
+
};
|
|
12592
|
+
const cleanup = () => {
|
|
12593
|
+
window.removeEventListener("pointermove", move);
|
|
12594
|
+
window.removeEventListener("pointerup", end);
|
|
12595
|
+
window.removeEventListener("pointercancel", cancel);
|
|
12596
|
+
window.removeEventListener("keydown", onKeyDown);
|
|
12597
|
+
};
|
|
12598
|
+
const settle = () => {
|
|
12599
|
+
cleanup();
|
|
12600
|
+
marqueeRef.current = null;
|
|
12601
|
+
setMarqueeBox(null);
|
|
12602
|
+
setMarqueeIds(null);
|
|
12603
|
+
};
|
|
12604
|
+
function cancel() {
|
|
12605
|
+
settle();
|
|
12606
|
+
}
|
|
12607
|
+
function onKeyDown(keyEvent) {
|
|
12608
|
+
if (keyEvent.key !== "Escape") return;
|
|
12609
|
+
keyEvent.preventDefault();
|
|
12610
|
+
cancel();
|
|
12611
|
+
}
|
|
12612
|
+
function move(moveEvent) {
|
|
12613
|
+
const x = clampTo(moveEvent.clientX - gesture.box.left, 0, gesture.box.width);
|
|
12614
|
+
const y = clampTo(moveEvent.clientY - gesture.box.top, 0, gesture.box.height);
|
|
12615
|
+
const rect = {
|
|
12616
|
+
x: Math.min(gesture.originX, x),
|
|
12617
|
+
y: Math.min(gesture.originY, y),
|
|
12618
|
+
w: Math.abs(x - gesture.originX),
|
|
12619
|
+
h: Math.abs(y - gesture.originY)
|
|
12620
|
+
};
|
|
12621
|
+
gesture.rect = rect;
|
|
12622
|
+
setMarqueeBox(rect);
|
|
12623
|
+
setMarqueeIds(hitsFor(rect));
|
|
12624
|
+
}
|
|
12625
|
+
function end() {
|
|
12626
|
+
const rect = gesture.rect;
|
|
12627
|
+
settle();
|
|
12628
|
+
if (Math.max(rect.w, rect.h) < MARQUEE_MIN) return;
|
|
12629
|
+
const hits = hitsFor(rect);
|
|
12630
|
+
if (hits.length === 0) return;
|
|
12631
|
+
commitSelection([...gesture.base, ...hits]);
|
|
12632
|
+
}
|
|
12633
|
+
window.addEventListener("pointermove", move);
|
|
12634
|
+
window.addEventListener("pointerup", end);
|
|
12635
|
+
window.addEventListener("pointercancel", cancel);
|
|
12636
|
+
window.addEventListener("keydown", onKeyDown);
|
|
12637
|
+
};
|
|
12440
12638
|
const moveFocus = (node, key) => {
|
|
12441
12639
|
const column = localNodes.filter((item) => Math.abs(item.x - node.x) < 1).sort((a, b) => a.y - b.y);
|
|
12442
12640
|
let target;
|
|
@@ -12461,7 +12659,7 @@ var PaymentRoutingCanvas = React62.forwardRef(
|
|
|
12461
12659
|
y: Math.min(Math.max(node.y / SCENE_H * 100 + 2, 2), 82),
|
|
12462
12660
|
w: 21,
|
|
12463
12661
|
h: 18,
|
|
12464
|
-
highlighted: node.id
|
|
12662
|
+
highlighted: selectionSet.has(node.id) || traversed.has(node.id)
|
|
12465
12663
|
}));
|
|
12466
12664
|
const issueByNode = (nodeId) => issues.filter((issue) => issue.nodeId === nodeId);
|
|
12467
12665
|
const currentStep = steps[stepIndex];
|
|
@@ -12553,12 +12751,30 @@ var PaymentRoutingCanvas = React62.forwardRef(
|
|
|
12553
12751
|
ref: planeRef,
|
|
12554
12752
|
role: "application",
|
|
12555
12753
|
"aria-label": "Payment routing graph",
|
|
12754
|
+
"aria-describedby": "routing-selection-status",
|
|
12556
12755
|
tabIndex: 0,
|
|
12557
|
-
onPointerDown:
|
|
12756
|
+
onPointerDown: (event) => {
|
|
12757
|
+
if (event.metaKey || event.ctrlKey) beginMarquee(event);
|
|
12758
|
+
else beginPan(event);
|
|
12759
|
+
},
|
|
12558
12760
|
onKeyDown: (event) => {
|
|
12761
|
+
const modifier = event.metaKey || event.ctrlKey;
|
|
12762
|
+
if (modifier && (event.key === "a" || event.key === "A")) {
|
|
12763
|
+
event.preventDefault();
|
|
12764
|
+
commitSelection(localNodes.map((item) => item.id));
|
|
12765
|
+
return;
|
|
12766
|
+
}
|
|
12559
12767
|
if (event.key === "Escape") {
|
|
12768
|
+
event.preventDefault();
|
|
12769
|
+
if (marqueeRef.current) return;
|
|
12560
12770
|
setIssuesOpen(false);
|
|
12561
|
-
|
|
12771
|
+
clearSelection();
|
|
12772
|
+
return;
|
|
12773
|
+
}
|
|
12774
|
+
if (event.shiftKey && (event.key === "ArrowUp" || event.key === "ArrowDown" || event.key === "ArrowLeft" || event.key === "ArrowRight")) {
|
|
12775
|
+
event.preventDefault();
|
|
12776
|
+
nudgeSelection(event.key);
|
|
12777
|
+
return;
|
|
12562
12778
|
}
|
|
12563
12779
|
if (event.key === "+" || event.key === "=") {
|
|
12564
12780
|
setZoom((current) => Math.min(current + 0.1, 1.6));
|
|
@@ -12572,7 +12788,9 @@ var PaymentRoutingCanvas = React62.forwardRef(
|
|
|
12572
12788
|
}
|
|
12573
12789
|
},
|
|
12574
12790
|
className: cn54(
|
|
12575
|
-
"relative min-h-0 min-w-0 flex-1
|
|
12791
|
+
"relative min-h-0 min-w-0 flex-1 overflow-hidden bg-canvas",
|
|
12792
|
+
// Held Cmd / Ctrl over the background means "drag to select".
|
|
12793
|
+
modifierHeld || marqueeBox ? "cursor-crosshair" : "cursor-grab",
|
|
12576
12794
|
"focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-focus-blue focus-visible:ring-inset"
|
|
12577
12795
|
),
|
|
12578
12796
|
style: {
|
|
@@ -12583,6 +12801,7 @@ var PaymentRoutingCanvas = React62.forwardRef(
|
|
|
12583
12801
|
backgroundSize: "16px 16px"
|
|
12584
12802
|
},
|
|
12585
12803
|
children: [
|
|
12804
|
+
/* @__PURE__ */ (0, import_jsx_runtime62.jsx)("p", { id: "routing-selection-status", role: "status", "aria-live": "polite", className: "sr-only", children: selection.length === 0 ? "No nodes selected" : `${selection.length} node${selection.length === 1 ? "" : "s"} selected` }),
|
|
12586
12805
|
/* @__PURE__ */ (0, import_jsx_runtime62.jsxs)(
|
|
12587
12806
|
"div",
|
|
12588
12807
|
{
|
|
@@ -12627,6 +12846,7 @@ var PaymentRoutingCanvas = React62.forwardRef(
|
|
|
12627
12846
|
(issue) => issue.kind === "no-fallback"
|
|
12628
12847
|
);
|
|
12629
12848
|
const active = traversed.has(node.id);
|
|
12849
|
+
const isSelected = selectionSet.has(node.id) || marqueeSet.has(node.id);
|
|
12630
12850
|
return /* @__PURE__ */ (0, import_jsx_runtime62.jsx)(
|
|
12631
12851
|
"div",
|
|
12632
12852
|
{
|
|
@@ -12644,31 +12864,35 @@ var PaymentRoutingCanvas = React62.forwardRef(
|
|
|
12644
12864
|
metric: node.metric,
|
|
12645
12865
|
trailing: node.trailing,
|
|
12646
12866
|
icon: node.icon,
|
|
12647
|
-
selected:
|
|
12867
|
+
selected: isSelected,
|
|
12648
12868
|
active: active && !unreachable,
|
|
12649
12869
|
unreachable,
|
|
12650
12870
|
noFallback,
|
|
12651
12871
|
conflict: conflict ? "Conflicts with Priority 2" : void 0,
|
|
12652
12872
|
disabled: node.disabled,
|
|
12653
|
-
showHint: focusedId === node.id &&
|
|
12654
|
-
ariaLabel: `${node.type}, ${node.title}${node.metric ? `, ${node.metric}` : ""}${unreachable ? ", unreachable" : ""}`,
|
|
12873
|
+
showHint: focusedId === node.id && isSelected,
|
|
12874
|
+
ariaLabel: `${node.type}, ${node.title}${node.metric ? `, ${node.metric}` : ""}${isSelected ? ", selected" : ""}${unreachable ? ", unreachable" : ""}`,
|
|
12655
12875
|
onNodeSelect: () => selectNode(node),
|
|
12656
12876
|
onFocus: () => setFocusedId(node.id),
|
|
12657
12877
|
onKeyDown: (event) => {
|
|
12878
|
+
if (event.shiftKey && (event.key === "ArrowUp" || event.key === "ArrowDown" || event.key === "ArrowLeft" || event.key === "ArrowRight")) {
|
|
12879
|
+
return;
|
|
12880
|
+
}
|
|
12658
12881
|
if (event.key === "ArrowUp" || event.key === "ArrowDown" || event.key === "ArrowLeft" || event.key === "ArrowRight") {
|
|
12659
12882
|
event.preventDefault();
|
|
12660
12883
|
moveFocus(node, event.key);
|
|
12884
|
+
return;
|
|
12661
12885
|
}
|
|
12662
|
-
if (event.key === "
|
|
12886
|
+
if (event.key === " " || event.shiftKey && event.key === "Enter") {
|
|
12663
12887
|
event.preventDefault();
|
|
12664
|
-
|
|
12665
|
-
|
|
12666
|
-
|
|
12888
|
+
commitSelection(
|
|
12889
|
+
selectionRef.current.includes(node.id) ? selectionRef.current.filter((id) => id !== node.id) : [...selectionRef.current, node.id]
|
|
12890
|
+
);
|
|
12891
|
+
return;
|
|
12667
12892
|
}
|
|
12668
|
-
if (event.key === "
|
|
12893
|
+
if (event.key === "Enter") {
|
|
12669
12894
|
event.preventDefault();
|
|
12670
|
-
|
|
12671
|
-
if (panelOpen) closePanel();
|
|
12895
|
+
openNodePanel(node);
|
|
12672
12896
|
}
|
|
12673
12897
|
}
|
|
12674
12898
|
}
|
|
@@ -12680,6 +12904,25 @@ var PaymentRoutingCanvas = React62.forwardRef(
|
|
|
12680
12904
|
]
|
|
12681
12905
|
}
|
|
12682
12906
|
),
|
|
12907
|
+
/* @__PURE__ */ (0, import_jsx_runtime62.jsx)(
|
|
12908
|
+
"div",
|
|
12909
|
+
{
|
|
12910
|
+
"aria-hidden": "true",
|
|
12911
|
+
"data-state": marqueeBox ? "active" : "idle",
|
|
12912
|
+
className: cn54(
|
|
12913
|
+
"pointer-events-none absolute rounded-xs border border-dashed border-primary bg-primary/10",
|
|
12914
|
+
"transition-opacity duration-150 ease-out",
|
|
12915
|
+
marqueeBox ? "opacity-100" : "opacity-0"
|
|
12916
|
+
),
|
|
12917
|
+
style: {
|
|
12918
|
+
left: marqueeBox?.x ?? 0,
|
|
12919
|
+
top: marqueeBox?.y ?? 0,
|
|
12920
|
+
width: marqueeBox?.w ?? 0,
|
|
12921
|
+
height: marqueeBox?.h ?? 0,
|
|
12922
|
+
zIndex: "var(--z-sticky, 1100)"
|
|
12923
|
+
}
|
|
12924
|
+
}
|
|
12925
|
+
),
|
|
12683
12926
|
/* @__PURE__ */ (0, import_jsx_runtime62.jsx)("ol", { className: "sr-only", children: graphEdges.map((edge) => {
|
|
12684
12927
|
const from = nodeById.get(edge.from);
|
|
12685
12928
|
const to = nodeById.get(edge.to);
|
|
@@ -12704,8 +12947,7 @@ var PaymentRoutingCanvas = React62.forwardRef(
|
|
|
12704
12947
|
onJump: (id) => {
|
|
12705
12948
|
const target = localNodes.find((node) => node.title === id);
|
|
12706
12949
|
if (!target) return;
|
|
12707
|
-
|
|
12708
|
-
setPanelOpen(true);
|
|
12950
|
+
openNodePanel(target);
|
|
12709
12951
|
setPan({ x: PLANE_PAD - target.x, y: -target.y });
|
|
12710
12952
|
}
|
|
12711
12953
|
}
|