@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/providers/index.js
CHANGED
|
@@ -43,6 +43,7 @@ import { DndContext, pointerWithin, rectIntersection, closestCorners, useSensors
|
|
|
43
43
|
import { useSortable, arrayMove, sortableKeyboardCoordinates, SortableContext, rectSortingStrategy, verticalListSortingStrategy } from '@dnd-kit/sortable';
|
|
44
44
|
import { CSS } from '@dnd-kit/utilities';
|
|
45
45
|
import { useNodeId, ReactFlowProvider, Handle, Position } from '@xyflow/react';
|
|
46
|
+
import { forceSimulation, forceLink, forceManyBody, forceCollide, forceX, forceY } from 'd3-force';
|
|
46
47
|
import { isDrawHostPattern, getPatternDefinition, getComponentForPattern as getComponentForPattern$1 } from '@almadar/core/patterns';
|
|
47
48
|
|
|
48
49
|
var __defProp = Object.defineProperty;
|
|
@@ -35360,7 +35361,10 @@ function resolveColor3(color, el) {
|
|
|
35360
35361
|
const resolved = getComputedStyle(el).getPropertyValue(m[1]).trim();
|
|
35361
35362
|
return resolved || (m[2]?.trim() ?? "#888888");
|
|
35362
35363
|
}
|
|
35363
|
-
|
|
35364
|
+
function truncateLabel(label) {
|
|
35365
|
+
return label.length > MAX_LABEL_CHARS ? label.slice(0, MAX_LABEL_CHARS - 1) + "\u2026" : label;
|
|
35366
|
+
}
|
|
35367
|
+
var GROUP_COLORS2, labelMeasureCtx, MAX_LABEL_CHARS, GraphCanvas;
|
|
35364
35368
|
var init_GraphCanvas = __esm({
|
|
35365
35369
|
"components/core/molecules/GraphCanvas.tsx"() {
|
|
35366
35370
|
"use client";
|
|
@@ -35381,6 +35385,7 @@ var init_GraphCanvas = __esm({
|
|
|
35381
35385
|
"var(--color-accent)"
|
|
35382
35386
|
];
|
|
35383
35387
|
labelMeasureCtx = null;
|
|
35388
|
+
MAX_LABEL_CHARS = 22;
|
|
35384
35389
|
GraphCanvas = ({
|
|
35385
35390
|
title,
|
|
35386
35391
|
nodes: propNodes = [],
|
|
@@ -35485,9 +35490,13 @@ var init_GraphCanvas = __esm({
|
|
|
35485
35490
|
useEffect(() => {
|
|
35486
35491
|
const canvas = canvasRef.current;
|
|
35487
35492
|
if (!canvas || propNodes.length === 0) return;
|
|
35488
|
-
const
|
|
35489
|
-
const
|
|
35493
|
+
const viewW = logicalW;
|
|
35494
|
+
const viewH = height;
|
|
35495
|
+
const layoutScale = Math.max(1, Math.min(3, Math.sqrt(propNodes.length / 12)));
|
|
35496
|
+
const w = viewW * layoutScale;
|
|
35497
|
+
const h = viewH * layoutScale;
|
|
35490
35498
|
const labelFont = resolveColor3("var(--font-family)", canvas) || "system-ui";
|
|
35499
|
+
const clamp01 = (v) => Math.min(1, Math.max(0, v));
|
|
35491
35500
|
const prevPos = /* @__PURE__ */ new Map();
|
|
35492
35501
|
for (const pn of nodesRef.current) if (pn.x != null && pn.y != null) prevPos.set(pn.id, { x: pn.x, y: pn.y });
|
|
35493
35502
|
const simNodes = propNodes.map((n, idx) => {
|
|
@@ -35512,7 +35521,7 @@ var init_GraphCanvas = __esm({
|
|
|
35512
35521
|
y = h * 0.2 + rand() * h * 0.6;
|
|
35513
35522
|
}
|
|
35514
35523
|
}
|
|
35515
|
-
return { ...n, x, y, vx: 0, vy: 0
|
|
35524
|
+
return { ...n, x, y, vx: 0, vy: 0 };
|
|
35516
35525
|
});
|
|
35517
35526
|
nodesRef.current = simNodes;
|
|
35518
35527
|
const prevIds = /* @__PURE__ */ new Set([...prevPos.keys()]);
|
|
@@ -35521,105 +35530,52 @@ var init_GraphCanvas = __esm({
|
|
|
35521
35530
|
const overlap = prevIds.size === 0 ? 0 : kept / Math.max(prevIds.size, newIdList.length);
|
|
35522
35531
|
const fullRelayout = !laidOutRef.current || overlap < 0.5;
|
|
35523
35532
|
if (layout === "force") {
|
|
35524
|
-
|
|
35525
|
-
|
|
35526
|
-
|
|
35527
|
-
|
|
35528
|
-
|
|
35529
|
-
|
|
35530
|
-
const nodes = nodesRef.current;
|
|
35531
|
-
const centerX = w / 2;
|
|
35532
|
-
const centerY = h / 2;
|
|
35533
|
-
const temp = Math.max(COOL, 1 - iter / maxIterations);
|
|
35534
|
-
for (const node of nodes) {
|
|
35535
|
-
node.fx = 0;
|
|
35536
|
-
node.fy = 0;
|
|
35537
|
-
}
|
|
35538
|
-
for (let i = 0; i < nodes.length; i++) {
|
|
35539
|
-
for (let j = i + 1; j < nodes.length; j++) {
|
|
35540
|
-
const dx = nodes[j].x - nodes[i].x;
|
|
35541
|
-
const dy = nodes[j].y - nodes[i].y;
|
|
35542
|
-
const dist = Math.sqrt(dx * dx + dy * dy) || 1;
|
|
35543
|
-
const force = repulsion / (dist * dist) * temp;
|
|
35544
|
-
const fx = dx / dist * force;
|
|
35545
|
-
const fy = dy / dist * force;
|
|
35546
|
-
nodes[i].fx -= fx;
|
|
35547
|
-
nodes[i].fy -= fy;
|
|
35548
|
-
nodes[j].fx += fx;
|
|
35549
|
-
nodes[j].fy += fy;
|
|
35550
|
-
}
|
|
35551
|
-
}
|
|
35552
|
-
const nodeById = new Map(nodes.map((n) => [n.id, n]));
|
|
35553
|
-
const spring = (a, b, rest, k) => {
|
|
35554
|
-
const dx = b.x - a.x;
|
|
35555
|
-
const dy = b.y - a.y;
|
|
35556
|
-
const dist = Math.sqrt(dx * dx + dy * dy) || 1;
|
|
35557
|
-
const force = (dist - rest) * k * temp;
|
|
35558
|
-
const fx = dx / dist * force;
|
|
35559
|
-
const fy = dy / dist * force;
|
|
35560
|
-
a.fx += fx;
|
|
35561
|
-
a.fy += fy;
|
|
35562
|
-
b.fx -= fx;
|
|
35563
|
-
b.fy -= fy;
|
|
35564
|
-
};
|
|
35533
|
+
if (fullRelayout) {
|
|
35534
|
+
const LABEL_GAP = 12;
|
|
35535
|
+
const LABEL_H = 16;
|
|
35536
|
+
for (const n of simNodes) n.labelW = showLabels && n.label ? measureLabelWidth(truncateLabel(n.label), labelFont) : 0;
|
|
35537
|
+
const SIMILARITY_NEIGHBORS = 5;
|
|
35538
|
+
const SIMILARITY_MIN_WEIGHT = 0.25;
|
|
35565
35539
|
const drawnPairs = /* @__PURE__ */ new Set();
|
|
35566
|
-
for (const edge of propEdges)
|
|
35567
|
-
|
|
35568
|
-
|
|
35569
|
-
if (!source || !target) continue;
|
|
35570
|
-
drawnPairs.add(edgeKeyOf(edge.source, edge.target));
|
|
35571
|
-
const w2 = Math.min(1, Math.max(0, edge.weight ?? 1));
|
|
35572
|
-
spring(source, target, linkDistance * (0.35 + (1 - w2) * 0.3), 0.14);
|
|
35573
|
-
}
|
|
35540
|
+
for (const edge of propEdges) drawnPairs.add(edgeKeyOf(edge.source, edge.target));
|
|
35541
|
+
const similarityNeighbors = /* @__PURE__ */ new Map();
|
|
35542
|
+
const bySource = /* @__PURE__ */ new Map();
|
|
35574
35543
|
for (const pair of propSimilarity) {
|
|
35544
|
+
if (pair.weight < SIMILARITY_MIN_WEIGHT) continue;
|
|
35575
35545
|
if (drawnPairs.has(edgeKeyOf(pair.source, pair.target))) continue;
|
|
35576
|
-
const
|
|
35577
|
-
|
|
35578
|
-
|
|
35579
|
-
const w2 = Math.min(1, Math.max(0, pair.weight));
|
|
35580
|
-
spring(source, target, linkDistance * (1.35 - 0.55 * w2), 0.015);
|
|
35546
|
+
const arr = bySource.get(pair.source) ?? [];
|
|
35547
|
+
arr.push(pair);
|
|
35548
|
+
bySource.set(pair.source, arr);
|
|
35581
35549
|
}
|
|
35582
|
-
const
|
|
35583
|
-
|
|
35584
|
-
|
|
35585
|
-
let c = centroids.get(g);
|
|
35586
|
-
if (!c) {
|
|
35587
|
-
c = { x: 0, y: 0, n: 0 };
|
|
35588
|
-
centroids.set(g, c);
|
|
35589
|
-
}
|
|
35590
|
-
c.x += node.x;
|
|
35591
|
-
c.y += node.y;
|
|
35592
|
-
c.n += 1;
|
|
35550
|
+
for (const [id, arr] of bySource) {
|
|
35551
|
+
arr.sort((a, b) => b.weight - a.weight);
|
|
35552
|
+
similarityNeighbors.set(id, new Set(arr.slice(0, SIMILARITY_NEIGHBORS).map((p) => p.target)));
|
|
35593
35553
|
}
|
|
35594
|
-
const
|
|
35595
|
-
|
|
35596
|
-
|
|
35597
|
-
|
|
35598
|
-
|
|
35599
|
-
|
|
35600
|
-
|
|
35601
|
-
|
|
35602
|
-
|
|
35603
|
-
|
|
35604
|
-
|
|
35605
|
-
|
|
35606
|
-
|
|
35607
|
-
|
|
35608
|
-
}
|
|
35609
|
-
}
|
|
35610
|
-
const damping = 0.9;
|
|
35611
|
-
for (const node of nodes) {
|
|
35612
|
-
node.vx = (node.vx + node.fx) * damping;
|
|
35613
|
-
node.vy = (node.vy + node.fy) * damping;
|
|
35614
|
-
node.x += node.vx;
|
|
35615
|
-
node.y += node.vy;
|
|
35616
|
-
node.x = Math.max(30, Math.min(w - 30, node.x));
|
|
35617
|
-
node.y = Math.max(30, Math.min(h - 30, node.y));
|
|
35554
|
+
const activeSimilarity = propSimilarity.filter((pair) => {
|
|
35555
|
+
if (drawnPairs.has(edgeKeyOf(pair.source, pair.target))) return false;
|
|
35556
|
+
const a = similarityNeighbors.get(pair.source);
|
|
35557
|
+
const b = similarityNeighbors.get(pair.target);
|
|
35558
|
+
return (a?.has(pair.target) ?? false) || (b?.has(pair.source) ?? false);
|
|
35559
|
+
});
|
|
35560
|
+
const groupTarget = /* @__PURE__ */ new Map();
|
|
35561
|
+
const multiCluster = groups.length > 1;
|
|
35562
|
+
if (multiCluster) {
|
|
35563
|
+
const ring = Math.min(w, h) * 0.34;
|
|
35564
|
+
groups.forEach((g, i) => {
|
|
35565
|
+
const a = i / groups.length * 2 * Math.PI;
|
|
35566
|
+
groupTarget.set(g, { x: w / 2 + ring * Math.cos(a), y: h / 2 + ring * Math.sin(a) });
|
|
35567
|
+
});
|
|
35618
35568
|
}
|
|
35569
|
+
const present = new Set(simNodes.map((n) => n.id));
|
|
35570
|
+
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) }));
|
|
35571
|
+
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) }));
|
|
35572
|
+
const collideRadius = (n) => Math.max(n.size || 8, (n.labelW ?? 0) / 2) + nodeSpacing / 2;
|
|
35573
|
+
const simulation = forceSimulation(simNodes).force("edge", forceLink(edgeLinks).id((d) => d.id).distance((l) => linkDistance * (0.35 + (1 - l.weight) * 0.3)).strength(0.9)).force("similarity", forceLink(simLinks).id((d) => d.id).distance((l) => linkDistance * (1.35 - 0.55 * l.weight)).strength(0.03)).force("charge", forceManyBody().strength(-repulsion * 0.5)).force("collide", forceCollide().radius(collideRadius).strength(0.9)).force("x", forceX((n) => groupTarget.get(n.group ?? "")?.x ?? w / 2).strength(multiCluster ? 0.05 : 0.02)).force("y", forceY((n) => groupTarget.get(n.group ?? "")?.y ?? h / 2).strength(multiCluster ? 0.05 : 0.02)).stop();
|
|
35574
|
+
for (let i = 0; i < 300; i++) simulation.tick();
|
|
35619
35575
|
const pad = nodeSpacing / 2;
|
|
35620
35576
|
const rectsOf = (n) => {
|
|
35621
35577
|
const r = n.size || 8;
|
|
35622
|
-
const lw = showLabels ? n.labelW ??
|
|
35578
|
+
const lw = showLabels ? n.labelW ?? 0 : 0;
|
|
35623
35579
|
return {
|
|
35624
35580
|
circle: [n.x - r - pad, n.y - r - pad, n.x + r + pad, n.y + r + pad],
|
|
35625
35581
|
label: [n.x - lw / 2 - pad, n.y + r + LABEL_GAP - 8, n.x + lw / 2 + pad, n.y + r + LABEL_GAP + LABEL_H]
|
|
@@ -35631,11 +35587,12 @@ var init_GraphCanvas = __esm({
|
|
|
35631
35587
|
if (ox <= 0 || oy <= 0) return null;
|
|
35632
35588
|
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 };
|
|
35633
35589
|
};
|
|
35634
|
-
for (let pass = 0; pass <
|
|
35635
|
-
|
|
35636
|
-
|
|
35637
|
-
|
|
35638
|
-
const
|
|
35590
|
+
for (let pass = 0; pass < 24; pass++) {
|
|
35591
|
+
let moved = false;
|
|
35592
|
+
for (let i = 0; i < simNodes.length; i++) {
|
|
35593
|
+
for (let j = i + 1; j < simNodes.length; j++) {
|
|
35594
|
+
const a = simNodes[i];
|
|
35595
|
+
const b = simNodes[j];
|
|
35639
35596
|
const ra = rectsOf(a);
|
|
35640
35597
|
const rb = rectsOf(b);
|
|
35641
35598
|
let best = null;
|
|
@@ -35644,25 +35601,35 @@ var init_GraphCanvas = __esm({
|
|
|
35644
35601
|
if (s && (!best || s.depth < best.depth)) best = s;
|
|
35645
35602
|
}
|
|
35646
35603
|
if (best) {
|
|
35604
|
+
moved = true;
|
|
35647
35605
|
const push = best.depth / 2;
|
|
35648
35606
|
if (best.axis === "x") {
|
|
35649
35607
|
a.x = Math.max(30, Math.min(w - 30, a.x - push * best.sign));
|
|
35650
35608
|
b.x = Math.max(30, Math.min(w - 30, b.x + push * best.sign));
|
|
35651
|
-
a.vx = 0;
|
|
35652
|
-
b.vx = 0;
|
|
35653
35609
|
} else {
|
|
35654
35610
|
a.y = Math.max(30, Math.min(h - 30, a.y - push * best.sign));
|
|
35655
35611
|
b.y = Math.max(30, Math.min(h - 30, b.y + push * best.sign));
|
|
35656
|
-
a.vy = 0;
|
|
35657
|
-
b.vy = 0;
|
|
35658
35612
|
}
|
|
35659
35613
|
}
|
|
35660
35614
|
}
|
|
35661
35615
|
}
|
|
35616
|
+
if (!moved) break;
|
|
35662
35617
|
}
|
|
35663
|
-
|
|
35664
|
-
|
|
35665
|
-
for (
|
|
35618
|
+
const fitPad = 40;
|
|
35619
|
+
let minX = Infinity, minY = Infinity, maxX = -Infinity, maxY = -Infinity;
|
|
35620
|
+
for (const node of nodesRef.current) {
|
|
35621
|
+
const r = node.size || 8;
|
|
35622
|
+
const lw = showLabels ? node.labelW ?? 0 : 0;
|
|
35623
|
+
minX = Math.min(minX, node.x - r, node.x - lw / 2);
|
|
35624
|
+
minY = Math.min(minY, node.y - r);
|
|
35625
|
+
maxX = Math.max(maxX, node.x + r, node.x + lw / 2);
|
|
35626
|
+
maxY = Math.max(maxY, node.y + r + LABEL_GAP + LABEL_H);
|
|
35627
|
+
}
|
|
35628
|
+
const bboxW = Math.max(1, maxX - minX + fitPad * 2);
|
|
35629
|
+
const bboxH = Math.max(1, maxY - minY + fitPad * 2);
|
|
35630
|
+
const nextZoom = Math.min(1, viewW / bboxW, viewH / bboxH);
|
|
35631
|
+
setZoom(nextZoom);
|
|
35632
|
+
setOffset({ x: fitPad - minX * nextZoom, y: fitPad - minY * nextZoom });
|
|
35666
35633
|
laidOutRef.current = true;
|
|
35667
35634
|
} else {
|
|
35668
35635
|
const centroids = /* @__PURE__ */ new Map();
|
|
@@ -35773,6 +35740,7 @@ var init_GraphCanvas = __esm({
|
|
|
35773
35740
|
}
|
|
35774
35741
|
ctx.stroke();
|
|
35775
35742
|
if (showLabels && node.label) {
|
|
35743
|
+
const displayLabel = truncateLabel(node.label);
|
|
35776
35744
|
ctx.font = `${isSelected || isHovered ? "600" : "500"} 12px ${fontFamily}`;
|
|
35777
35745
|
ctx.textAlign = "center";
|
|
35778
35746
|
ctx.textBaseline = "middle";
|
|
@@ -35780,9 +35748,9 @@ var init_GraphCanvas = __esm({
|
|
|
35780
35748
|
ctx.lineWidth = 3;
|
|
35781
35749
|
ctx.lineJoin = "round";
|
|
35782
35750
|
ctx.strokeStyle = bgColor;
|
|
35783
|
-
ctx.strokeText(
|
|
35751
|
+
ctx.strokeText(displayLabel, node.x, ly);
|
|
35784
35752
|
ctx.fillStyle = isSelected || isHovered ? fgColor : mutedColor;
|
|
35785
|
-
ctx.fillText(
|
|
35753
|
+
ctx.fillText(displayLabel, node.x, ly);
|
|
35786
35754
|
}
|
|
35787
35755
|
if (node.badge && node.badge > 1) {
|
|
35788
35756
|
const bx = node.x + radius * 0.7;
|
|
@@ -35930,6 +35898,20 @@ var init_GraphCanvas = __esm({
|
|
|
35930
35898
|
},
|
|
35931
35899
|
[toCoords, nodeAt, onNodeDoubleClick]
|
|
35932
35900
|
);
|
|
35901
|
+
const hoveredObj = hoveredNode ? nodesRef.current.find((n) => n.id === hoveredNode) : void 0;
|
|
35902
|
+
const canvasEl = canvasRef.current;
|
|
35903
|
+
const showLabelTooltip = Boolean(
|
|
35904
|
+
hoveredObj?.label && hoveredObj.label.length > MAX_LABEL_CHARS && hoveredObj.x != null && canvasEl
|
|
35905
|
+
);
|
|
35906
|
+
const labelTooltipStyle = (() => {
|
|
35907
|
+
if (!showLabelTooltip || !canvasEl || !hoveredObj || hoveredObj.x == null || hoveredObj.y == null) return void 0;
|
|
35908
|
+
const rect = canvasEl.getBoundingClientRect();
|
|
35909
|
+
return {
|
|
35910
|
+
left: rect.left + offset.x + hoveredObj.x * zoom,
|
|
35911
|
+
top: rect.top + offset.y + hoveredObj.y * zoom - 10,
|
|
35912
|
+
transform: "translate(-50%, -100%)"
|
|
35913
|
+
};
|
|
35914
|
+
})();
|
|
35933
35915
|
if (isLoading) {
|
|
35934
35916
|
return /* @__PURE__ */ jsx(LoadingState, { message: t("common.loading"), className });
|
|
35935
35917
|
}
|
|
@@ -35983,23 +35965,43 @@ var init_GraphCanvas = __esm({
|
|
|
35983
35965
|
]
|
|
35984
35966
|
}
|
|
35985
35967
|
),
|
|
35986
|
-
/* @__PURE__ */
|
|
35987
|
-
|
|
35988
|
-
|
|
35989
|
-
|
|
35990
|
-
|
|
35991
|
-
|
|
35992
|
-
|
|
35993
|
-
|
|
35994
|
-
|
|
35995
|
-
|
|
35996
|
-
|
|
35997
|
-
|
|
35998
|
-
|
|
35999
|
-
|
|
36000
|
-
|
|
36001
|
-
|
|
36002
|
-
|
|
35968
|
+
/* @__PURE__ */ jsxs(Box, { className: "w-full bg-background", children: [
|
|
35969
|
+
/* @__PURE__ */ jsx(
|
|
35970
|
+
"canvas",
|
|
35971
|
+
{
|
|
35972
|
+
ref: canvasRef,
|
|
35973
|
+
width: Math.round(logicalW * (typeof window !== "undefined" && window.devicePixelRatio || 1)),
|
|
35974
|
+
height: Math.round(height * (typeof window !== "undefined" && window.devicePixelRatio || 1)),
|
|
35975
|
+
className: "w-full cursor-grab active:cursor-grabbing touch-none",
|
|
35976
|
+
style: { height },
|
|
35977
|
+
onPointerDown: gestureHandlers.onPointerDown,
|
|
35978
|
+
onPointerMove: gestureHandlers.onPointerMove,
|
|
35979
|
+
onPointerUp: gestureHandlers.onPointerUp,
|
|
35980
|
+
onPointerCancel: gestureHandlers.onPointerCancel,
|
|
35981
|
+
onPointerLeave: handlePointerLeave,
|
|
35982
|
+
onWheel: gestureHandlers.onWheel,
|
|
35983
|
+
onDoubleClick: handleDoubleClick
|
|
35984
|
+
}
|
|
35985
|
+
),
|
|
35986
|
+
typeof window !== "undefined" && showLabelTooltip && labelTooltipStyle && createPortal(
|
|
35987
|
+
/* @__PURE__ */ jsx(
|
|
35988
|
+
"div",
|
|
35989
|
+
{
|
|
35990
|
+
className: cn(
|
|
35991
|
+
"fixed z-50 px-3 py-2 max-w-xs",
|
|
35992
|
+
"bg-primary text-primary-foreground",
|
|
35993
|
+
"shadow-elevation-popover rounded-sm",
|
|
35994
|
+
"text-sm pointer-events-none",
|
|
35995
|
+
"break-words whitespace-normal"
|
|
35996
|
+
),
|
|
35997
|
+
style: labelTooltipStyle,
|
|
35998
|
+
role: "tooltip",
|
|
35999
|
+
children: hoveredObj?.label
|
|
36000
|
+
}
|
|
36001
|
+
),
|
|
36002
|
+
document.body
|
|
36003
|
+
)
|
|
36004
|
+
] }),
|
|
36003
36005
|
groups.length > 1 && /* @__PURE__ */ jsx(HStack, { gap: "md", className: "px-4 py-2 border-t border-border", wrap: true, children: groups.map((group, idx) => /* @__PURE__ */ jsxs(HStack, { gap: "xs", align: "center", children: [
|
|
36004
36006
|
/* @__PURE__ */ jsx(
|
|
36005
36007
|
Box,
|