@almadar/ui 5.119.0 → 5.121.0
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/dist/avl/index.cjs +127 -125
- package/dist/avl/index.js +127 -125
- package/dist/components/index.cjs +127 -125
- package/dist/components/index.js +127 -125
- package/dist/providers/index.cjs +127 -125
- package/dist/providers/index.js +127 -125
- package/dist/runtime/index.cjs +127 -125
- package/dist/runtime/index.js +127 -125
- package/package.json +3 -1
package/dist/avl/index.cjs
CHANGED
|
@@ -40,6 +40,7 @@ var core = require('@almadar/core');
|
|
|
40
40
|
var core$1 = require('@dnd-kit/core');
|
|
41
41
|
var sortable = require('@dnd-kit/sortable');
|
|
42
42
|
var utilities = require('@dnd-kit/utilities');
|
|
43
|
+
var d3Force = require('d3-force');
|
|
43
44
|
var patterns = require('@almadar/core/patterns');
|
|
44
45
|
var OrbitalServerRuntime = require('@almadar/runtime/OrbitalServerRuntime');
|
|
45
46
|
var registry = require('@almadar/std/registry');
|
|
@@ -37275,7 +37276,10 @@ function resolveColor3(color, el) {
|
|
|
37275
37276
|
const resolved = getComputedStyle(el).getPropertyValue(m[1]).trim();
|
|
37276
37277
|
return resolved || (m[2]?.trim() ?? "#888888");
|
|
37277
37278
|
}
|
|
37278
|
-
|
|
37279
|
+
function truncateLabel(label) {
|
|
37280
|
+
return label.length > MAX_LABEL_CHARS ? label.slice(0, MAX_LABEL_CHARS - 1) + "\u2026" : label;
|
|
37281
|
+
}
|
|
37282
|
+
var GROUP_COLORS2, labelMeasureCtx, MAX_LABEL_CHARS, GraphCanvas;
|
|
37279
37283
|
var init_GraphCanvas = __esm({
|
|
37280
37284
|
"components/core/molecules/GraphCanvas.tsx"() {
|
|
37281
37285
|
"use client";
|
|
@@ -37296,6 +37300,7 @@ var init_GraphCanvas = __esm({
|
|
|
37296
37300
|
"var(--color-accent)"
|
|
37297
37301
|
];
|
|
37298
37302
|
labelMeasureCtx = null;
|
|
37303
|
+
MAX_LABEL_CHARS = 22;
|
|
37299
37304
|
GraphCanvas = ({
|
|
37300
37305
|
title,
|
|
37301
37306
|
nodes: propNodes = [],
|
|
@@ -37400,9 +37405,13 @@ var init_GraphCanvas = __esm({
|
|
|
37400
37405
|
React90.useEffect(() => {
|
|
37401
37406
|
const canvas = canvasRef.current;
|
|
37402
37407
|
if (!canvas || propNodes.length === 0) return;
|
|
37403
|
-
const
|
|
37404
|
-
const
|
|
37408
|
+
const viewW = logicalW;
|
|
37409
|
+
const viewH = height;
|
|
37410
|
+
const layoutScale = Math.max(1, Math.min(3, Math.sqrt(propNodes.length / 12)));
|
|
37411
|
+
const w = viewW * layoutScale;
|
|
37412
|
+
const h = viewH * layoutScale;
|
|
37405
37413
|
const labelFont = resolveColor3("var(--font-family)", canvas) || "system-ui";
|
|
37414
|
+
const clamp01 = (v) => Math.min(1, Math.max(0, v));
|
|
37406
37415
|
const prevPos = /* @__PURE__ */ new Map();
|
|
37407
37416
|
for (const pn of nodesRef.current) if (pn.x != null && pn.y != null) prevPos.set(pn.id, { x: pn.x, y: pn.y });
|
|
37408
37417
|
const simNodes = propNodes.map((n, idx) => {
|
|
@@ -37427,7 +37436,7 @@ var init_GraphCanvas = __esm({
|
|
|
37427
37436
|
y = h * 0.2 + rand() * h * 0.6;
|
|
37428
37437
|
}
|
|
37429
37438
|
}
|
|
37430
|
-
return { ...n, x, y, vx: 0, vy: 0
|
|
37439
|
+
return { ...n, x, y, vx: 0, vy: 0 };
|
|
37431
37440
|
});
|
|
37432
37441
|
nodesRef.current = simNodes;
|
|
37433
37442
|
const prevIds = /* @__PURE__ */ new Set([...prevPos.keys()]);
|
|
@@ -37436,105 +37445,52 @@ var init_GraphCanvas = __esm({
|
|
|
37436
37445
|
const overlap = prevIds.size === 0 ? 0 : kept / Math.max(prevIds.size, newIdList.length);
|
|
37437
37446
|
const fullRelayout = !laidOutRef.current || overlap < 0.5;
|
|
37438
37447
|
if (layout === "force") {
|
|
37439
|
-
|
|
37440
|
-
|
|
37441
|
-
|
|
37442
|
-
|
|
37443
|
-
|
|
37444
|
-
|
|
37445
|
-
const nodes = nodesRef.current;
|
|
37446
|
-
const centerX = w / 2;
|
|
37447
|
-
const centerY = h / 2;
|
|
37448
|
-
const temp = Math.max(COOL, 1 - iter / maxIterations);
|
|
37449
|
-
for (const node of nodes) {
|
|
37450
|
-
node.fx = 0;
|
|
37451
|
-
node.fy = 0;
|
|
37452
|
-
}
|
|
37453
|
-
for (let i = 0; i < nodes.length; i++) {
|
|
37454
|
-
for (let j = i + 1; j < nodes.length; j++) {
|
|
37455
|
-
const dx = nodes[j].x - nodes[i].x;
|
|
37456
|
-
const dy = nodes[j].y - nodes[i].y;
|
|
37457
|
-
const dist = Math.sqrt(dx * dx + dy * dy) || 1;
|
|
37458
|
-
const force = repulsion / (dist * dist) * temp;
|
|
37459
|
-
const fx = dx / dist * force;
|
|
37460
|
-
const fy = dy / dist * force;
|
|
37461
|
-
nodes[i].fx -= fx;
|
|
37462
|
-
nodes[i].fy -= fy;
|
|
37463
|
-
nodes[j].fx += fx;
|
|
37464
|
-
nodes[j].fy += fy;
|
|
37465
|
-
}
|
|
37466
|
-
}
|
|
37467
|
-
const nodeById = new Map(nodes.map((n) => [n.id, n]));
|
|
37468
|
-
const spring = (a, b, rest, k) => {
|
|
37469
|
-
const dx = b.x - a.x;
|
|
37470
|
-
const dy = b.y - a.y;
|
|
37471
|
-
const dist = Math.sqrt(dx * dx + dy * dy) || 1;
|
|
37472
|
-
const force = (dist - rest) * k * temp;
|
|
37473
|
-
const fx = dx / dist * force;
|
|
37474
|
-
const fy = dy / dist * force;
|
|
37475
|
-
a.fx += fx;
|
|
37476
|
-
a.fy += fy;
|
|
37477
|
-
b.fx -= fx;
|
|
37478
|
-
b.fy -= fy;
|
|
37479
|
-
};
|
|
37448
|
+
if (fullRelayout) {
|
|
37449
|
+
const LABEL_GAP = 12;
|
|
37450
|
+
const LABEL_H = 16;
|
|
37451
|
+
for (const n of simNodes) n.labelW = showLabels && n.label ? measureLabelWidth(truncateLabel(n.label), labelFont) : 0;
|
|
37452
|
+
const SIMILARITY_NEIGHBORS = 5;
|
|
37453
|
+
const SIMILARITY_MIN_WEIGHT = 0.25;
|
|
37480
37454
|
const drawnPairs = /* @__PURE__ */ new Set();
|
|
37481
|
-
for (const edge of propEdges)
|
|
37482
|
-
|
|
37483
|
-
|
|
37484
|
-
if (!source || !target) continue;
|
|
37485
|
-
drawnPairs.add(edgeKeyOf(edge.source, edge.target));
|
|
37486
|
-
const w2 = Math.min(1, Math.max(0, edge.weight ?? 1));
|
|
37487
|
-
spring(source, target, linkDistance * (0.35 + (1 - w2) * 0.3), 0.14);
|
|
37488
|
-
}
|
|
37455
|
+
for (const edge of propEdges) drawnPairs.add(edgeKeyOf(edge.source, edge.target));
|
|
37456
|
+
const similarityNeighbors = /* @__PURE__ */ new Map();
|
|
37457
|
+
const bySource = /* @__PURE__ */ new Map();
|
|
37489
37458
|
for (const pair of propSimilarity) {
|
|
37459
|
+
if (pair.weight < SIMILARITY_MIN_WEIGHT) continue;
|
|
37490
37460
|
if (drawnPairs.has(edgeKeyOf(pair.source, pair.target))) continue;
|
|
37491
|
-
const
|
|
37492
|
-
|
|
37493
|
-
|
|
37494
|
-
const w2 = Math.min(1, Math.max(0, pair.weight));
|
|
37495
|
-
spring(source, target, linkDistance * (1.35 - 0.55 * w2), 0.015);
|
|
37461
|
+
const arr = bySource.get(pair.source) ?? [];
|
|
37462
|
+
arr.push(pair);
|
|
37463
|
+
bySource.set(pair.source, arr);
|
|
37496
37464
|
}
|
|
37497
|
-
const
|
|
37498
|
-
|
|
37499
|
-
|
|
37500
|
-
let c = centroids.get(g);
|
|
37501
|
-
if (!c) {
|
|
37502
|
-
c = { x: 0, y: 0, n: 0 };
|
|
37503
|
-
centroids.set(g, c);
|
|
37504
|
-
}
|
|
37505
|
-
c.x += node.x;
|
|
37506
|
-
c.y += node.y;
|
|
37507
|
-
c.n += 1;
|
|
37465
|
+
for (const [id, arr] of bySource) {
|
|
37466
|
+
arr.sort((a, b) => b.weight - a.weight);
|
|
37467
|
+
similarityNeighbors.set(id, new Set(arr.slice(0, SIMILARITY_NEIGHBORS).map((p) => p.target)));
|
|
37508
37468
|
}
|
|
37509
|
-
const
|
|
37510
|
-
|
|
37511
|
-
|
|
37512
|
-
|
|
37513
|
-
|
|
37514
|
-
|
|
37515
|
-
|
|
37516
|
-
|
|
37517
|
-
|
|
37518
|
-
|
|
37519
|
-
|
|
37520
|
-
|
|
37521
|
-
|
|
37522
|
-
|
|
37523
|
-
}
|
|
37524
|
-
}
|
|
37525
|
-
const damping = 0.9;
|
|
37526
|
-
for (const node of nodes) {
|
|
37527
|
-
node.vx = (node.vx + node.fx) * damping;
|
|
37528
|
-
node.vy = (node.vy + node.fy) * damping;
|
|
37529
|
-
node.x += node.vx;
|
|
37530
|
-
node.y += node.vy;
|
|
37531
|
-
node.x = Math.max(30, Math.min(w - 30, node.x));
|
|
37532
|
-
node.y = Math.max(30, Math.min(h - 30, node.y));
|
|
37469
|
+
const activeSimilarity = propSimilarity.filter((pair) => {
|
|
37470
|
+
if (drawnPairs.has(edgeKeyOf(pair.source, pair.target))) return false;
|
|
37471
|
+
const a = similarityNeighbors.get(pair.source);
|
|
37472
|
+
const b = similarityNeighbors.get(pair.target);
|
|
37473
|
+
return (a?.has(pair.target) ?? false) || (b?.has(pair.source) ?? false);
|
|
37474
|
+
});
|
|
37475
|
+
const groupTarget = /* @__PURE__ */ new Map();
|
|
37476
|
+
const multiCluster = groups.length > 1;
|
|
37477
|
+
if (multiCluster) {
|
|
37478
|
+
const ring = Math.min(w, h) * 0.34;
|
|
37479
|
+
groups.forEach((g, i) => {
|
|
37480
|
+
const a = i / groups.length * 2 * Math.PI;
|
|
37481
|
+
groupTarget.set(g, { x: w / 2 + ring * Math.cos(a), y: h / 2 + ring * Math.sin(a) });
|
|
37482
|
+
});
|
|
37533
37483
|
}
|
|
37484
|
+
const present = new Set(simNodes.map((n) => n.id));
|
|
37485
|
+
const edgeLinks = propEdges.filter((e) => present.has(e.source) && present.has(e.target)).map((e) => ({ source: e.source, target: e.target, weight: clamp01(e.weight ?? 1) }));
|
|
37486
|
+
const simLinks = activeSimilarity.filter((p) => present.has(p.source) && present.has(p.target)).map((p) => ({ source: p.source, target: p.target, weight: clamp01(p.weight) }));
|
|
37487
|
+
const collideRadius = (n) => Math.max(n.size || 8, (n.labelW ?? 0) / 2) + nodeSpacing / 2;
|
|
37488
|
+
const simulation = d3Force.forceSimulation(simNodes).force("edge", d3Force.forceLink(edgeLinks).id((d) => d.id).distance((l) => linkDistance * (0.35 + (1 - l.weight) * 0.3)).strength(0.9)).force("similarity", d3Force.forceLink(simLinks).id((d) => d.id).distance((l) => linkDistance * (1.35 - 0.55 * l.weight)).strength(0.03)).force("charge", d3Force.forceManyBody().strength(-repulsion * 0.5)).force("collide", d3Force.forceCollide().radius(collideRadius).strength(0.9)).force("x", d3Force.forceX((n) => groupTarget.get(n.group ?? "")?.x ?? w / 2).strength(multiCluster ? 0.05 : 0.02)).force("y", d3Force.forceY((n) => groupTarget.get(n.group ?? "")?.y ?? h / 2).strength(multiCluster ? 0.05 : 0.02)).stop();
|
|
37489
|
+
for (let i = 0; i < 300; i++) simulation.tick();
|
|
37534
37490
|
const pad = nodeSpacing / 2;
|
|
37535
37491
|
const rectsOf = (n) => {
|
|
37536
37492
|
const r2 = n.size || 8;
|
|
37537
|
-
const lw = showLabels ? n.labelW ??
|
|
37493
|
+
const lw = showLabels ? n.labelW ?? 0 : 0;
|
|
37538
37494
|
return {
|
|
37539
37495
|
circle: [n.x - r2 - pad, n.y - r2 - pad, n.x + r2 + pad, n.y + r2 + pad],
|
|
37540
37496
|
label: [n.x - lw / 2 - pad, n.y + r2 + LABEL_GAP - 8, n.x + lw / 2 + pad, n.y + r2 + LABEL_GAP + LABEL_H]
|
|
@@ -37546,11 +37502,12 @@ var init_GraphCanvas = __esm({
|
|
|
37546
37502
|
if (ox <= 0 || oy <= 0) return null;
|
|
37547
37503
|
return ox <= oy ? { axis: "x", depth: ox, sign: r1[0] + r1[2] < r2[0] + r2[2] ? 1 : -1 } : { axis: "y", depth: oy, sign: r1[1] + r1[3] < r2[1] + r2[3] ? 1 : -1 };
|
|
37548
37504
|
};
|
|
37549
|
-
for (let pass = 0; pass <
|
|
37550
|
-
|
|
37551
|
-
|
|
37552
|
-
|
|
37553
|
-
const
|
|
37505
|
+
for (let pass = 0; pass < 24; pass++) {
|
|
37506
|
+
let moved = false;
|
|
37507
|
+
for (let i = 0; i < simNodes.length; i++) {
|
|
37508
|
+
for (let j = i + 1; j < simNodes.length; j++) {
|
|
37509
|
+
const a = simNodes[i];
|
|
37510
|
+
const b = simNodes[j];
|
|
37554
37511
|
const ra = rectsOf(a);
|
|
37555
37512
|
const rb = rectsOf(b);
|
|
37556
37513
|
let best = null;
|
|
@@ -37559,25 +37516,35 @@ var init_GraphCanvas = __esm({
|
|
|
37559
37516
|
if (s && (!best || s.depth < best.depth)) best = s;
|
|
37560
37517
|
}
|
|
37561
37518
|
if (best) {
|
|
37519
|
+
moved = true;
|
|
37562
37520
|
const push = best.depth / 2;
|
|
37563
37521
|
if (best.axis === "x") {
|
|
37564
37522
|
a.x = Math.max(30, Math.min(w - 30, a.x - push * best.sign));
|
|
37565
37523
|
b.x = Math.max(30, Math.min(w - 30, b.x + push * best.sign));
|
|
37566
|
-
a.vx = 0;
|
|
37567
|
-
b.vx = 0;
|
|
37568
37524
|
} else {
|
|
37569
37525
|
a.y = Math.max(30, Math.min(h - 30, a.y - push * best.sign));
|
|
37570
37526
|
b.y = Math.max(30, Math.min(h - 30, b.y + push * best.sign));
|
|
37571
|
-
a.vy = 0;
|
|
37572
|
-
b.vy = 0;
|
|
37573
37527
|
}
|
|
37574
37528
|
}
|
|
37575
37529
|
}
|
|
37576
37530
|
}
|
|
37531
|
+
if (!moved) break;
|
|
37577
37532
|
}
|
|
37578
|
-
|
|
37579
|
-
|
|
37580
|
-
for (
|
|
37533
|
+
const fitPad = 40;
|
|
37534
|
+
let minX = Infinity, minY = Infinity, maxX = -Infinity, maxY = -Infinity;
|
|
37535
|
+
for (const node of nodesRef.current) {
|
|
37536
|
+
const r2 = node.size || 8;
|
|
37537
|
+
const lw = showLabels ? node.labelW ?? 0 : 0;
|
|
37538
|
+
minX = Math.min(minX, node.x - r2, node.x - lw / 2);
|
|
37539
|
+
minY = Math.min(minY, node.y - r2);
|
|
37540
|
+
maxX = Math.max(maxX, node.x + r2, node.x + lw / 2);
|
|
37541
|
+
maxY = Math.max(maxY, node.y + r2 + LABEL_GAP + LABEL_H);
|
|
37542
|
+
}
|
|
37543
|
+
const bboxW = Math.max(1, maxX - minX + fitPad * 2);
|
|
37544
|
+
const bboxH = Math.max(1, maxY - minY + fitPad * 2);
|
|
37545
|
+
const nextZoom = Math.min(1, viewW / bboxW, viewH / bboxH);
|
|
37546
|
+
setZoom(nextZoom);
|
|
37547
|
+
setOffset({ x: fitPad - minX * nextZoom, y: fitPad - minY * nextZoom });
|
|
37581
37548
|
laidOutRef.current = true;
|
|
37582
37549
|
} else {
|
|
37583
37550
|
const centroids = /* @__PURE__ */ new Map();
|
|
@@ -37688,6 +37655,7 @@ var init_GraphCanvas = __esm({
|
|
|
37688
37655
|
}
|
|
37689
37656
|
ctx.stroke();
|
|
37690
37657
|
if (showLabels && node.label) {
|
|
37658
|
+
const displayLabel = truncateLabel(node.label);
|
|
37691
37659
|
ctx.font = `${isSelected || isHovered ? "600" : "500"} 12px ${fontFamily}`;
|
|
37692
37660
|
ctx.textAlign = "center";
|
|
37693
37661
|
ctx.textBaseline = "middle";
|
|
@@ -37695,9 +37663,9 @@ var init_GraphCanvas = __esm({
|
|
|
37695
37663
|
ctx.lineWidth = 3;
|
|
37696
37664
|
ctx.lineJoin = "round";
|
|
37697
37665
|
ctx.strokeStyle = bgColor;
|
|
37698
|
-
ctx.strokeText(
|
|
37666
|
+
ctx.strokeText(displayLabel, node.x, ly);
|
|
37699
37667
|
ctx.fillStyle = isSelected || isHovered ? fgColor : mutedColor;
|
|
37700
|
-
ctx.fillText(
|
|
37668
|
+
ctx.fillText(displayLabel, node.x, ly);
|
|
37701
37669
|
}
|
|
37702
37670
|
if (node.badge && node.badge > 1) {
|
|
37703
37671
|
const bx = node.x + radius * 0.7;
|
|
@@ -37845,6 +37813,20 @@ var init_GraphCanvas = __esm({
|
|
|
37845
37813
|
},
|
|
37846
37814
|
[toCoords, nodeAt, onNodeDoubleClick]
|
|
37847
37815
|
);
|
|
37816
|
+
const hoveredObj = hoveredNode ? nodesRef.current.find((n) => n.id === hoveredNode) : void 0;
|
|
37817
|
+
const canvasEl = canvasRef.current;
|
|
37818
|
+
const showLabelTooltip = Boolean(
|
|
37819
|
+
hoveredObj?.label && hoveredObj.label.length > MAX_LABEL_CHARS && hoveredObj.x != null && canvasEl
|
|
37820
|
+
);
|
|
37821
|
+
const labelTooltipStyle = (() => {
|
|
37822
|
+
if (!showLabelTooltip || !canvasEl || !hoveredObj || hoveredObj.x == null || hoveredObj.y == null) return void 0;
|
|
37823
|
+
const rect = canvasEl.getBoundingClientRect();
|
|
37824
|
+
return {
|
|
37825
|
+
left: rect.left + offset.x + hoveredObj.x * zoom,
|
|
37826
|
+
top: rect.top + offset.y + hoveredObj.y * zoom - 10,
|
|
37827
|
+
transform: "translate(-50%, -100%)"
|
|
37828
|
+
};
|
|
37829
|
+
})();
|
|
37848
37830
|
if (isLoading) {
|
|
37849
37831
|
return /* @__PURE__ */ jsxRuntime.jsx(LoadingState, { message: t("common.loading"), className });
|
|
37850
37832
|
}
|
|
@@ -37898,23 +37880,43 @@ var init_GraphCanvas = __esm({
|
|
|
37898
37880
|
]
|
|
37899
37881
|
}
|
|
37900
37882
|
),
|
|
37901
|
-
/* @__PURE__ */ jsxRuntime.
|
|
37902
|
-
|
|
37903
|
-
|
|
37904
|
-
|
|
37905
|
-
|
|
37906
|
-
|
|
37907
|
-
|
|
37908
|
-
|
|
37909
|
-
|
|
37910
|
-
|
|
37911
|
-
|
|
37912
|
-
|
|
37913
|
-
|
|
37914
|
-
|
|
37915
|
-
|
|
37916
|
-
|
|
37917
|
-
|
|
37883
|
+
/* @__PURE__ */ jsxRuntime.jsxs(Box, { className: "w-full bg-background", children: [
|
|
37884
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
37885
|
+
"canvas",
|
|
37886
|
+
{
|
|
37887
|
+
ref: canvasRef,
|
|
37888
|
+
width: Math.round(logicalW * (typeof window !== "undefined" && window.devicePixelRatio || 1)),
|
|
37889
|
+
height: Math.round(height * (typeof window !== "undefined" && window.devicePixelRatio || 1)),
|
|
37890
|
+
className: "w-full cursor-grab active:cursor-grabbing touch-none",
|
|
37891
|
+
style: { height },
|
|
37892
|
+
onPointerDown: gestureHandlers.onPointerDown,
|
|
37893
|
+
onPointerMove: gestureHandlers.onPointerMove,
|
|
37894
|
+
onPointerUp: gestureHandlers.onPointerUp,
|
|
37895
|
+
onPointerCancel: gestureHandlers.onPointerCancel,
|
|
37896
|
+
onPointerLeave: handlePointerLeave,
|
|
37897
|
+
onWheel: gestureHandlers.onWheel,
|
|
37898
|
+
onDoubleClick: handleDoubleClick
|
|
37899
|
+
}
|
|
37900
|
+
),
|
|
37901
|
+
typeof window !== "undefined" && showLabelTooltip && labelTooltipStyle && reactDom.createPortal(
|
|
37902
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
37903
|
+
"div",
|
|
37904
|
+
{
|
|
37905
|
+
className: cn(
|
|
37906
|
+
"fixed z-50 px-3 py-2 max-w-xs",
|
|
37907
|
+
"bg-primary text-primary-foreground",
|
|
37908
|
+
"shadow-elevation-popover rounded-sm",
|
|
37909
|
+
"text-sm pointer-events-none",
|
|
37910
|
+
"break-words whitespace-normal"
|
|
37911
|
+
),
|
|
37912
|
+
style: labelTooltipStyle,
|
|
37913
|
+
role: "tooltip",
|
|
37914
|
+
children: hoveredObj?.label
|
|
37915
|
+
}
|
|
37916
|
+
),
|
|
37917
|
+
document.body
|
|
37918
|
+
)
|
|
37919
|
+
] }),
|
|
37918
37920
|
groups.length > 1 && /* @__PURE__ */ jsxRuntime.jsx(HStack, { gap: "md", className: "px-4 py-2 border-t border-border", wrap: true, children: groups.map((group, idx) => /* @__PURE__ */ jsxRuntime.jsxs(HStack, { gap: "xs", align: "center", children: [
|
|
37919
37921
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
37920
37922
|
Box,
|