@almadar/ui 5.146.3 → 5.148.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 +363 -35
- package/dist/avl/index.js +363 -35
- package/dist/{cn-BdGFhYe3.d.cts → cn-BAn68sNO.d.cts} +92 -2
- package/dist/{cn-DNkqAWZK.d.ts → cn-CWxxLkri.d.ts} +92 -2
- package/dist/components/index.cjs +364 -36
- package/dist/components/index.d.cts +99 -175
- package/dist/components/index.d.ts +99 -175
- package/dist/components/index.js +364 -36
- package/dist/lib/index.cjs +104 -0
- package/dist/lib/index.d.cts +2 -1
- package/dist/lib/index.d.ts +2 -1
- package/dist/lib/index.js +104 -1
- package/dist/providers/index.cjs +363 -35
- package/dist/providers/index.js +363 -35
- package/dist/runtime/index.cjs +363 -35
- package/dist/runtime/index.js +363 -35
- package/package.json +6 -6
- package/themes/bloomberg-dense.css +266 -229
- package/themes/retro.css +30 -30
package/dist/runtime/index.js
CHANGED
|
@@ -11866,7 +11866,10 @@ var init_LearningCanvas = __esm({
|
|
|
11866
11866
|
ctx.fillRect(0, 0, width, height);
|
|
11867
11867
|
}
|
|
11868
11868
|
for (const shape of shapes) {
|
|
11869
|
-
drawShape(ctx, shape, width, height);
|
|
11869
|
+
if (shape.type !== "text") drawShape(ctx, shape, width, height);
|
|
11870
|
+
}
|
|
11871
|
+
for (const shape of shapes) {
|
|
11872
|
+
if (shape.type === "text") drawShape(ctx, shape, width, height);
|
|
11870
11873
|
}
|
|
11871
11874
|
}, [width, height, backgroundColor, shapes]);
|
|
11872
11875
|
useEffect(() => {
|
|
@@ -13429,7 +13432,7 @@ var init_AlgorithmCanvas = __esm({
|
|
|
13429
13432
|
DEFAULT_CELL_COLOR = "#e5e7eb";
|
|
13430
13433
|
DEFAULT_POINTER_COLOR = "#dc2626";
|
|
13431
13434
|
POINTER_BAND = 34;
|
|
13432
|
-
TOP_PAD =
|
|
13435
|
+
TOP_PAD = 26;
|
|
13433
13436
|
AlgorithmCanvas = ({
|
|
13434
13437
|
className,
|
|
13435
13438
|
width = 600,
|
|
@@ -24840,6 +24843,7 @@ var init_FilterGroup = __esm({
|
|
|
24840
24843
|
init_Badge();
|
|
24841
24844
|
init_Stack();
|
|
24842
24845
|
init_Icon();
|
|
24846
|
+
init_RangeSlider();
|
|
24843
24847
|
init_useEventBus();
|
|
24844
24848
|
init_useQuerySingleton();
|
|
24845
24849
|
resolveFilterType = (filter) => filter.filterType ?? filter.type;
|
|
@@ -25034,6 +25038,35 @@ var init_FilterGroup = __esm({
|
|
|
25034
25038
|
onClear: () => handleFilterSelect(`${filter.field}_to`, null)
|
|
25035
25039
|
}
|
|
25036
25040
|
)
|
|
25041
|
+
] }) : resolveFilterType(filter) === "numberrange" || resolveFilterType(filter) === "number-range" ? /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-2", children: [
|
|
25042
|
+
/* @__PURE__ */ jsx(
|
|
25043
|
+
RangeSlider,
|
|
25044
|
+
{
|
|
25045
|
+
min: filter.min ?? 0,
|
|
25046
|
+
max: filter.max ?? 100,
|
|
25047
|
+
step: filter.step ?? 1,
|
|
25048
|
+
value: Number(
|
|
25049
|
+
selectedValues[`${filter.field}_min`] ?? filter.min ?? 0
|
|
25050
|
+
),
|
|
25051
|
+
onChange: (v) => handleFilterSelect(`${filter.field}_min`, String(v)),
|
|
25052
|
+
showTooltip: true,
|
|
25053
|
+
"aria-label": t("filterGroup.from")
|
|
25054
|
+
}
|
|
25055
|
+
),
|
|
25056
|
+
/* @__PURE__ */ jsx(
|
|
25057
|
+
RangeSlider,
|
|
25058
|
+
{
|
|
25059
|
+
min: filter.min ?? 0,
|
|
25060
|
+
max: filter.max ?? 100,
|
|
25061
|
+
step: filter.step ?? 1,
|
|
25062
|
+
value: Number(
|
|
25063
|
+
selectedValues[`${filter.field}_max`] ?? filter.max ?? 100
|
|
25064
|
+
),
|
|
25065
|
+
onChange: (v) => handleFilterSelect(`${filter.field}_max`, String(v)),
|
|
25066
|
+
showTooltip: true,
|
|
25067
|
+
"aria-label": t("filterGroup.to")
|
|
25068
|
+
}
|
|
25069
|
+
)
|
|
25037
25070
|
] }) : resolveFilterType(filter) === "text" ? /* @__PURE__ */ jsx(
|
|
25038
25071
|
Input,
|
|
25039
25072
|
{
|
|
@@ -25116,6 +25149,36 @@ var init_FilterGroup = __esm({
|
|
|
25116
25149
|
className: "text-sm min-w-[100px]"
|
|
25117
25150
|
}
|
|
25118
25151
|
)
|
|
25152
|
+
] }) : resolveFilterType(filter) === "numberrange" || resolveFilterType(filter) === "number-range" ? /* @__PURE__ */ jsxs(HStack, { gap: "xs", align: "center", children: [
|
|
25153
|
+
/* @__PURE__ */ jsx(
|
|
25154
|
+
RangeSlider,
|
|
25155
|
+
{
|
|
25156
|
+
min: filter.min ?? 0,
|
|
25157
|
+
max: filter.max ?? 100,
|
|
25158
|
+
step: filter.step ?? 1,
|
|
25159
|
+
value: Number(
|
|
25160
|
+
selectedValues[`${filter.field}_min`] ?? filter.min ?? 0
|
|
25161
|
+
),
|
|
25162
|
+
onChange: (v) => handleFilterSelect(`${filter.field}_min`, String(v)),
|
|
25163
|
+
className: "min-w-[100px]",
|
|
25164
|
+
"aria-label": t("filterGroup.from")
|
|
25165
|
+
}
|
|
25166
|
+
),
|
|
25167
|
+
/* @__PURE__ */ jsx("span", { className: "text-muted-foreground", children: "-" }),
|
|
25168
|
+
/* @__PURE__ */ jsx(
|
|
25169
|
+
RangeSlider,
|
|
25170
|
+
{
|
|
25171
|
+
min: filter.min ?? 0,
|
|
25172
|
+
max: filter.max ?? 100,
|
|
25173
|
+
step: filter.step ?? 1,
|
|
25174
|
+
value: Number(
|
|
25175
|
+
selectedValues[`${filter.field}_max`] ?? filter.max ?? 100
|
|
25176
|
+
),
|
|
25177
|
+
onChange: (v) => handleFilterSelect(`${filter.field}_max`, String(v)),
|
|
25178
|
+
className: "min-w-[100px]",
|
|
25179
|
+
"aria-label": t("filterGroup.to")
|
|
25180
|
+
}
|
|
25181
|
+
)
|
|
25119
25182
|
] }) : resolveFilterType(filter) === "text" ? /* @__PURE__ */ jsx(
|
|
25120
25183
|
Input,
|
|
25121
25184
|
{
|
|
@@ -25234,6 +25297,38 @@ var init_FilterGroup = __esm({
|
|
|
25234
25297
|
className: "min-w-[130px]"
|
|
25235
25298
|
}
|
|
25236
25299
|
)
|
|
25300
|
+
] }) : resolveFilterType(filter) === "numberrange" || resolveFilterType(filter) === "number-range" ? /* @__PURE__ */ jsxs(HStack, { gap: "xs", align: "center", children: [
|
|
25301
|
+
/* @__PURE__ */ jsx(
|
|
25302
|
+
RangeSlider,
|
|
25303
|
+
{
|
|
25304
|
+
min: filter.min ?? 0,
|
|
25305
|
+
max: filter.max ?? 100,
|
|
25306
|
+
step: filter.step ?? 1,
|
|
25307
|
+
value: Number(
|
|
25308
|
+
selectedValues[`${filter.field}_min`] ?? filter.min ?? 0
|
|
25309
|
+
),
|
|
25310
|
+
onChange: (v) => handleFilterSelect(`${filter.field}_min`, String(v)),
|
|
25311
|
+
showTooltip: true,
|
|
25312
|
+
className: "min-w-[130px]",
|
|
25313
|
+
"aria-label": t("filterGroup.from")
|
|
25314
|
+
}
|
|
25315
|
+
),
|
|
25316
|
+
/* @__PURE__ */ jsx("span", { className: "text-muted-foreground", children: "-" }),
|
|
25317
|
+
/* @__PURE__ */ jsx(
|
|
25318
|
+
RangeSlider,
|
|
25319
|
+
{
|
|
25320
|
+
min: filter.min ?? 0,
|
|
25321
|
+
max: filter.max ?? 100,
|
|
25322
|
+
step: filter.step ?? 1,
|
|
25323
|
+
value: Number(
|
|
25324
|
+
selectedValues[`${filter.field}_max`] ?? filter.max ?? 100
|
|
25325
|
+
),
|
|
25326
|
+
onChange: (v) => handleFilterSelect(`${filter.field}_max`, String(v)),
|
|
25327
|
+
showTooltip: true,
|
|
25328
|
+
className: "min-w-[130px]",
|
|
25329
|
+
"aria-label": t("filterGroup.to")
|
|
25330
|
+
}
|
|
25331
|
+
)
|
|
25237
25332
|
] }) : resolveFilterType(filter) === "text" ? /* @__PURE__ */ jsx(
|
|
25238
25333
|
Input,
|
|
25239
25334
|
{
|
|
@@ -27133,7 +27228,12 @@ function daysAgo(n) {
|
|
|
27133
27228
|
d.setDate(d.getDate() - n);
|
|
27134
27229
|
return d;
|
|
27135
27230
|
}
|
|
27136
|
-
|
|
27231
|
+
function resolvePresetRange(preset) {
|
|
27232
|
+
if (typeof preset.range === "function") return preset.range();
|
|
27233
|
+
if (preset.range) return preset.range;
|
|
27234
|
+
return TOKEN_RANGES[preset.value]?.() ?? null;
|
|
27235
|
+
}
|
|
27236
|
+
var TOKEN_RANGES, DEFAULT_PRESETS, DateRangePicker;
|
|
27137
27237
|
var init_DateRangePicker = __esm({
|
|
27138
27238
|
"components/core/molecules/DateRangePicker.tsx"() {
|
|
27139
27239
|
"use client";
|
|
@@ -27143,32 +27243,19 @@ var init_DateRangePicker = __esm({
|
|
|
27143
27243
|
init_Stack();
|
|
27144
27244
|
init_Typography();
|
|
27145
27245
|
init_useEventBus();
|
|
27246
|
+
TOKEN_RANGES = {
|
|
27247
|
+
"7d": () => ({ from: toISODate(daysAgo(7)), to: toISODate(/* @__PURE__ */ new Date()) }),
|
|
27248
|
+
"30d": () => ({ from: toISODate(daysAgo(30)), to: toISODate(/* @__PURE__ */ new Date()) }),
|
|
27249
|
+
month: () => ({ from: toISODate(startOfMonth(/* @__PURE__ */ new Date())), to: toISODate(/* @__PURE__ */ new Date()) }),
|
|
27250
|
+
quarter: () => ({ from: toISODate(startOfQuarter(/* @__PURE__ */ new Date())), to: toISODate(/* @__PURE__ */ new Date()) }),
|
|
27251
|
+
ytd: () => ({ from: toISODate(startOfYear(/* @__PURE__ */ new Date())), to: toISODate(/* @__PURE__ */ new Date()) })
|
|
27252
|
+
};
|
|
27146
27253
|
DEFAULT_PRESETS = [
|
|
27147
|
-
{
|
|
27148
|
-
|
|
27149
|
-
|
|
27150
|
-
|
|
27151
|
-
}
|
|
27152
|
-
{
|
|
27153
|
-
label: "Last 30 days",
|
|
27154
|
-
value: "30d",
|
|
27155
|
-
range: () => ({ from: toISODate(daysAgo(30)), to: toISODate(/* @__PURE__ */ new Date()) })
|
|
27156
|
-
},
|
|
27157
|
-
{
|
|
27158
|
-
label: "This Month",
|
|
27159
|
-
value: "month",
|
|
27160
|
-
range: () => ({ from: toISODate(startOfMonth(/* @__PURE__ */ new Date())), to: toISODate(/* @__PURE__ */ new Date()) })
|
|
27161
|
-
},
|
|
27162
|
-
{
|
|
27163
|
-
label: "This Quarter",
|
|
27164
|
-
value: "quarter",
|
|
27165
|
-
range: () => ({ from: toISODate(startOfQuarter(/* @__PURE__ */ new Date())), to: toISODate(/* @__PURE__ */ new Date()) })
|
|
27166
|
-
},
|
|
27167
|
-
{
|
|
27168
|
-
label: "YTD",
|
|
27169
|
-
value: "ytd",
|
|
27170
|
-
range: () => ({ from: toISODate(startOfYear(/* @__PURE__ */ new Date())), to: toISODate(/* @__PURE__ */ new Date()) })
|
|
27171
|
-
}
|
|
27254
|
+
{ label: "Last 7 days", value: "7d" },
|
|
27255
|
+
{ label: "Last 30 days", value: "30d" },
|
|
27256
|
+
{ label: "This Month", value: "month" },
|
|
27257
|
+
{ label: "This Quarter", value: "quarter" },
|
|
27258
|
+
{ label: "YTD", value: "ytd" }
|
|
27172
27259
|
];
|
|
27173
27260
|
DateRangePicker = ({
|
|
27174
27261
|
from: fromProp,
|
|
@@ -27209,7 +27296,8 @@ var init_DateRangePicker = __esm({
|
|
|
27209
27296
|
);
|
|
27210
27297
|
const handlePreset = useCallback(
|
|
27211
27298
|
(preset) => {
|
|
27212
|
-
const range = preset
|
|
27299
|
+
const range = resolvePresetRange(preset);
|
|
27300
|
+
if (range === null) return;
|
|
27213
27301
|
setFrom(range.from);
|
|
27214
27302
|
setTo(range.to);
|
|
27215
27303
|
setActivePreset(preset.value);
|
|
@@ -27217,8 +27305,12 @@ var init_DateRangePicker = __esm({
|
|
|
27217
27305
|
},
|
|
27218
27306
|
[emit]
|
|
27219
27307
|
);
|
|
27308
|
+
const renderablePresets = useMemo(
|
|
27309
|
+
() => presets.filter((p) => p.range !== void 0 || TOKEN_RANGES[p.value] !== void 0),
|
|
27310
|
+
[presets]
|
|
27311
|
+
);
|
|
27220
27312
|
const presetButtons = useMemo(
|
|
27221
|
-
() =>
|
|
27313
|
+
() => renderablePresets.map((preset) => /* @__PURE__ */ jsx(
|
|
27222
27314
|
Button,
|
|
27223
27315
|
{
|
|
27224
27316
|
variant: activePreset === preset.value ? "primary" : "ghost",
|
|
@@ -27228,7 +27320,7 @@ var init_DateRangePicker = __esm({
|
|
|
27228
27320
|
},
|
|
27229
27321
|
preset.value
|
|
27230
27322
|
)),
|
|
27231
|
-
[
|
|
27323
|
+
[renderablePresets, activePreset, handlePreset]
|
|
27232
27324
|
);
|
|
27233
27325
|
return /* @__PURE__ */ jsxs(VStack, { gap: "sm", className: cn(className), children: [
|
|
27234
27326
|
/* @__PURE__ */ jsxs(HStack, { gap: "md", align: "end", children: [
|
|
@@ -27255,7 +27347,7 @@ var init_DateRangePicker = __esm({
|
|
|
27255
27347
|
)
|
|
27256
27348
|
] })
|
|
27257
27349
|
] }),
|
|
27258
|
-
|
|
27350
|
+
renderablePresets.length > 0 && /* @__PURE__ */ jsx(HStack, { gap: "xs", wrap: true, children: presetButtons })
|
|
27259
27351
|
] });
|
|
27260
27352
|
};
|
|
27261
27353
|
DateRangePicker.displayName = "DateRangePicker";
|
|
@@ -27697,6 +27789,208 @@ var init_PhysicsCanvas = __esm({
|
|
|
27697
27789
|
};
|
|
27698
27790
|
}
|
|
27699
27791
|
});
|
|
27792
|
+
|
|
27793
|
+
// lib/graphViewLayouts.ts
|
|
27794
|
+
function buildAdjacency(nodeIds, edges) {
|
|
27795
|
+
const known = new Set(nodeIds);
|
|
27796
|
+
const out = /* @__PURE__ */ new Map();
|
|
27797
|
+
const inMap = /* @__PURE__ */ new Map();
|
|
27798
|
+
for (const id of nodeIds) {
|
|
27799
|
+
out.set(id, []);
|
|
27800
|
+
inMap.set(id, []);
|
|
27801
|
+
}
|
|
27802
|
+
for (const edge of edges) {
|
|
27803
|
+
if (!known.has(edge.source) || !known.has(edge.target)) continue;
|
|
27804
|
+
out.get(edge.source)?.push(edge.target);
|
|
27805
|
+
inMap.get(edge.target)?.push(edge.source);
|
|
27806
|
+
}
|
|
27807
|
+
return { out, in: inMap };
|
|
27808
|
+
}
|
|
27809
|
+
function findRoots(nodeIds, adjacency) {
|
|
27810
|
+
return nodeIds.filter((id) => (adjacency.in.get(id)?.length ?? 0) === 0);
|
|
27811
|
+
}
|
|
27812
|
+
function assignLayers(nodeIds, adjacency, roots) {
|
|
27813
|
+
const layer = new Map(nodeIds.map((id) => [id, 0]));
|
|
27814
|
+
const onStack = /* @__PURE__ */ new Set();
|
|
27815
|
+
const visit = (id) => {
|
|
27816
|
+
onStack.add(id);
|
|
27817
|
+
const currentLayer = layer.get(id) ?? 0;
|
|
27818
|
+
for (const next of adjacency.out.get(id) ?? []) {
|
|
27819
|
+
if (onStack.has(next)) continue;
|
|
27820
|
+
const candidate = currentLayer + 1;
|
|
27821
|
+
if (candidate > (layer.get(next) ?? 0)) {
|
|
27822
|
+
layer.set(next, candidate);
|
|
27823
|
+
}
|
|
27824
|
+
visit(next);
|
|
27825
|
+
}
|
|
27826
|
+
onStack.delete(id);
|
|
27827
|
+
};
|
|
27828
|
+
for (const root of roots) visit(root);
|
|
27829
|
+
return layer;
|
|
27830
|
+
}
|
|
27831
|
+
function computeVisitOrder(nodeIds, adjacency, roots) {
|
|
27832
|
+
const order = /* @__PURE__ */ new Map();
|
|
27833
|
+
const visited = /* @__PURE__ */ new Set();
|
|
27834
|
+
let counter = 0;
|
|
27835
|
+
const visit = (id) => {
|
|
27836
|
+
if (visited.has(id)) return;
|
|
27837
|
+
visited.add(id);
|
|
27838
|
+
order.set(id, counter++);
|
|
27839
|
+
for (const next of adjacency.out.get(id) ?? []) visit(next);
|
|
27840
|
+
};
|
|
27841
|
+
for (const root of roots) visit(root);
|
|
27842
|
+
for (const id of nodeIds) {
|
|
27843
|
+
if (!visited.has(id)) order.set(id, counter++);
|
|
27844
|
+
}
|
|
27845
|
+
return order;
|
|
27846
|
+
}
|
|
27847
|
+
function bfsDepthAndOrder(nodeIds, adjacency, roots) {
|
|
27848
|
+
const depth = new Map(nodeIds.map((id) => [id, 0]));
|
|
27849
|
+
const visitOrder = /* @__PURE__ */ new Map();
|
|
27850
|
+
const visited = /* @__PURE__ */ new Set();
|
|
27851
|
+
const queue = [];
|
|
27852
|
+
let counter = 0;
|
|
27853
|
+
for (const root of roots) {
|
|
27854
|
+
if (visited.has(root)) continue;
|
|
27855
|
+
visited.add(root);
|
|
27856
|
+
depth.set(root, 0);
|
|
27857
|
+
visitOrder.set(root, counter++);
|
|
27858
|
+
queue.push(root);
|
|
27859
|
+
}
|
|
27860
|
+
let head = 0;
|
|
27861
|
+
while (head < queue.length) {
|
|
27862
|
+
const id = queue[head++];
|
|
27863
|
+
const d = depth.get(id) ?? 0;
|
|
27864
|
+
for (const next of adjacency.out.get(id) ?? []) {
|
|
27865
|
+
if (visited.has(next)) continue;
|
|
27866
|
+
visited.add(next);
|
|
27867
|
+
depth.set(next, d + 1);
|
|
27868
|
+
visitOrder.set(next, counter++);
|
|
27869
|
+
queue.push(next);
|
|
27870
|
+
}
|
|
27871
|
+
}
|
|
27872
|
+
for (const id of nodeIds) {
|
|
27873
|
+
if (!visited.has(id)) visitOrder.set(id, counter++);
|
|
27874
|
+
}
|
|
27875
|
+
return { depth, visitOrder };
|
|
27876
|
+
}
|
|
27877
|
+
function edgeWalkOrder(nodeIds, adjacency) {
|
|
27878
|
+
const visited = /* @__PURE__ */ new Set();
|
|
27879
|
+
const result = [];
|
|
27880
|
+
for (const start of nodeIds) {
|
|
27881
|
+
if (visited.has(start)) continue;
|
|
27882
|
+
let current = start;
|
|
27883
|
+
while (current !== void 0 && !visited.has(current)) {
|
|
27884
|
+
visited.add(current);
|
|
27885
|
+
result.push(current);
|
|
27886
|
+
const outs = adjacency.out.get(current) ?? [];
|
|
27887
|
+
current = outs.find((next) => !visited.has(next));
|
|
27888
|
+
}
|
|
27889
|
+
}
|
|
27890
|
+
return result;
|
|
27891
|
+
}
|
|
27892
|
+
function groupByTier(nodeIds, tierOf, maxTier) {
|
|
27893
|
+
const groups = Array.from({ length: maxTier + 1 }, () => []);
|
|
27894
|
+
for (const id of nodeIds) {
|
|
27895
|
+
groups[tierOf.get(id) ?? 0].push(id);
|
|
27896
|
+
}
|
|
27897
|
+
return groups;
|
|
27898
|
+
}
|
|
27899
|
+
function distributeAxis(count, start, end) {
|
|
27900
|
+
if (count <= 0) return [];
|
|
27901
|
+
const slot = (end - start) / count;
|
|
27902
|
+
return Array.from({ length: count }, (_, i) => start + slot * (i + 0.5));
|
|
27903
|
+
}
|
|
27904
|
+
function orderByParentPositionThenInput(group, adjacency, positioned, inputIndex) {
|
|
27905
|
+
const withKey = group.map((id) => {
|
|
27906
|
+
const parentValues = (adjacency.in.get(id) ?? []).map((p) => positioned.get(p)).filter((v) => v !== void 0);
|
|
27907
|
+
const avg = parentValues.length > 0 ? parentValues.reduce((a, b) => a + b, 0) / parentValues.length : Number.POSITIVE_INFINITY;
|
|
27908
|
+
return { id, avg, idx: inputIndex.get(id) ?? 0 };
|
|
27909
|
+
});
|
|
27910
|
+
withKey.sort((a, b) => a.avg !== b.avg ? a.avg - b.avg : a.idx - b.idx);
|
|
27911
|
+
return withKey.map((k) => k.id);
|
|
27912
|
+
}
|
|
27913
|
+
function layoutFlow(nodeIds, adjacency, roots, width, height, margin) {
|
|
27914
|
+
const inputIndex = new Map(nodeIds.map((id, i) => [id, i]));
|
|
27915
|
+
const layers = assignLayers(nodeIds, adjacency, roots);
|
|
27916
|
+
const maxLayer = Math.max(...Array.from(layers.values()));
|
|
27917
|
+
const layerGroups = groupByTier(nodeIds, layers, maxLayer);
|
|
27918
|
+
const positions = /* @__PURE__ */ new Map();
|
|
27919
|
+
const yById = /* @__PURE__ */ new Map();
|
|
27920
|
+
for (let l = 0; l <= maxLayer; l++) {
|
|
27921
|
+
const x = margin + l * (width - 2 * margin) / Math.max(1, maxLayer);
|
|
27922
|
+
const ordered2 = orderByParentPositionThenInput(layerGroups[l], adjacency, yById, inputIndex);
|
|
27923
|
+
const ys = distributeAxis(ordered2.length, margin, height - margin);
|
|
27924
|
+
ordered2.forEach((id, i) => {
|
|
27925
|
+
positions.set(id, { id, x, y: ys[i] });
|
|
27926
|
+
yById.set(id, ys[i]);
|
|
27927
|
+
});
|
|
27928
|
+
}
|
|
27929
|
+
return nodeIds.map((id) => positions.get(id));
|
|
27930
|
+
}
|
|
27931
|
+
function layoutTree(nodeIds, adjacency, roots, width, height, margin) {
|
|
27932
|
+
const effectiveRoots = roots.length > 0 ? roots : [nodeIds[0]];
|
|
27933
|
+
const layers = assignLayers(nodeIds, adjacency, effectiveRoots);
|
|
27934
|
+
const maxLayer = Math.max(...Array.from(layers.values()));
|
|
27935
|
+
const visitOrder = computeVisitOrder(nodeIds, adjacency, effectiveRoots);
|
|
27936
|
+
const layerGroups = groupByTier(nodeIds, layers, maxLayer);
|
|
27937
|
+
const positions = /* @__PURE__ */ new Map();
|
|
27938
|
+
for (let l = 0; l <= maxLayer; l++) {
|
|
27939
|
+
const ordered2 = [...layerGroups[l]].sort(
|
|
27940
|
+
(a, b) => (visitOrder.get(a) ?? 0) - (visitOrder.get(b) ?? 0)
|
|
27941
|
+
);
|
|
27942
|
+
const y = margin + l * (height - 2 * margin) / Math.max(1, maxLayer);
|
|
27943
|
+
const xs = distributeAxis(ordered2.length, margin, width - margin);
|
|
27944
|
+
ordered2.forEach((id, i) => positions.set(id, { id, x: xs[i], y }));
|
|
27945
|
+
}
|
|
27946
|
+
return nodeIds.map((id) => positions.get(id));
|
|
27947
|
+
}
|
|
27948
|
+
function layoutRadial(nodeIds, adjacency, roots, width, height, margin) {
|
|
27949
|
+
const cx = width / 2;
|
|
27950
|
+
const cy = height / 2;
|
|
27951
|
+
const maxRadius = Math.min(width, height) / 2 - margin;
|
|
27952
|
+
if (roots.length === 0) {
|
|
27953
|
+
const order = edgeWalkOrder(nodeIds, adjacency);
|
|
27954
|
+
const k = order.length;
|
|
27955
|
+
const positions2 = /* @__PURE__ */ new Map();
|
|
27956
|
+
order.forEach((id, i) => {
|
|
27957
|
+
const angle = i / k * 2 * Math.PI;
|
|
27958
|
+
positions2.set(id, { id, x: cx + maxRadius * Math.cos(angle), y: cy + maxRadius * Math.sin(angle) });
|
|
27959
|
+
});
|
|
27960
|
+
return nodeIds.map((id) => positions2.get(id));
|
|
27961
|
+
}
|
|
27962
|
+
const { depth, visitOrder } = bfsDepthAndOrder(nodeIds, adjacency, roots);
|
|
27963
|
+
const maxDepth = Math.max(...Array.from(depth.values()));
|
|
27964
|
+
const ringGroups = groupByTier(nodeIds, depth, maxDepth);
|
|
27965
|
+
const positions = /* @__PURE__ */ new Map();
|
|
27966
|
+
for (let d = 0; d <= maxDepth; d++) {
|
|
27967
|
+
const ordered2 = [...ringGroups[d]].sort(
|
|
27968
|
+
(a, b) => (visitOrder.get(a) ?? 0) - (visitOrder.get(b) ?? 0)
|
|
27969
|
+
);
|
|
27970
|
+
const radius = d * maxRadius / Math.max(1, maxDepth);
|
|
27971
|
+
const k = ordered2.length;
|
|
27972
|
+
ordered2.forEach((id, i) => {
|
|
27973
|
+
const angle = i / k * 2 * Math.PI;
|
|
27974
|
+
positions.set(id, { id, x: cx + radius * Math.cos(angle), y: cy + radius * Math.sin(angle) });
|
|
27975
|
+
});
|
|
27976
|
+
}
|
|
27977
|
+
return nodeIds.map((id) => positions.get(id));
|
|
27978
|
+
}
|
|
27979
|
+
function computeStaticLayout(mode, input) {
|
|
27980
|
+
const { nodeIds, edges, width, height } = input;
|
|
27981
|
+
const margin = input.margin ?? 40;
|
|
27982
|
+
if (nodeIds.length === 0) return [];
|
|
27983
|
+
if (nodeIds.length === 1) return [{ id: nodeIds[0], x: width / 2, y: height / 2 }];
|
|
27984
|
+
const adjacency = buildAdjacency(nodeIds, edges);
|
|
27985
|
+
const roots = findRoots(nodeIds, adjacency);
|
|
27986
|
+
if (mode === "flow") return layoutFlow(nodeIds, adjacency, roots, width, height, margin);
|
|
27987
|
+
if (mode === "tree") return layoutTree(nodeIds, adjacency, roots, width, height, margin);
|
|
27988
|
+
return layoutRadial(nodeIds, adjacency, roots, width, height, margin);
|
|
27989
|
+
}
|
|
27990
|
+
var init_graphViewLayouts = __esm({
|
|
27991
|
+
"lib/graphViewLayouts.ts"() {
|
|
27992
|
+
}
|
|
27993
|
+
});
|
|
27700
27994
|
function resolveNodeColor(node, groups) {
|
|
27701
27995
|
if (node.color) return node.color;
|
|
27702
27996
|
if (node.group) {
|
|
@@ -27711,6 +28005,7 @@ var init_GraphView = __esm({
|
|
|
27711
28005
|
"use client";
|
|
27712
28006
|
init_cn();
|
|
27713
28007
|
init_atoms();
|
|
28008
|
+
init_graphViewLayouts();
|
|
27714
28009
|
GROUP_COLORS = [
|
|
27715
28010
|
"#3b82f6",
|
|
27716
28011
|
// blue-500
|
|
@@ -27741,11 +28036,13 @@ var init_GraphView = __esm({
|
|
|
27741
28036
|
height: propHeight,
|
|
27742
28037
|
className,
|
|
27743
28038
|
showLabels = true,
|
|
27744
|
-
zoomToFit = true
|
|
28039
|
+
zoomToFit = true,
|
|
28040
|
+
layout = "force"
|
|
27745
28041
|
}) => {
|
|
27746
28042
|
const { t } = useTranslate();
|
|
27747
28043
|
const containerRef = useRef(null);
|
|
27748
28044
|
const animRef = useRef(0);
|
|
28045
|
+
const arrowMarkerId = useId();
|
|
27749
28046
|
const [simNodes, setSimNodes] = useState([]);
|
|
27750
28047
|
const [settled, setSettled] = useState(false);
|
|
27751
28048
|
const [hoveredId, setHoveredId] = useState(null);
|
|
@@ -27802,6 +28099,22 @@ var init_GraphView = __esm({
|
|
|
27802
28099
|
fy: 0
|
|
27803
28100
|
};
|
|
27804
28101
|
});
|
|
28102
|
+
if (layout !== "force") {
|
|
28103
|
+
const points = computeStaticLayout(layout, {
|
|
28104
|
+
nodeIds: nodes.map((n) => n.id),
|
|
28105
|
+
edges,
|
|
28106
|
+
width: w,
|
|
28107
|
+
height: h
|
|
28108
|
+
});
|
|
28109
|
+
const pointById = new Map(points.map((p) => [p.id, p]));
|
|
28110
|
+
const laidOut = initialNodes.map((node) => {
|
|
28111
|
+
const point = pointById.get(node.id);
|
|
28112
|
+
return point ? { ...node, x: point.x, y: point.y } : node;
|
|
28113
|
+
});
|
|
28114
|
+
setSimNodes(laidOut);
|
|
28115
|
+
setSettled(true);
|
|
28116
|
+
return;
|
|
28117
|
+
}
|
|
27805
28118
|
let iterations = 0;
|
|
27806
28119
|
const maxIterations = 120;
|
|
27807
28120
|
let currentNodes = initialNodes;
|
|
@@ -27870,7 +28183,7 @@ var init_GraphView = __esm({
|
|
|
27870
28183
|
return () => {
|
|
27871
28184
|
cancelAnimationFrame(animRef.current);
|
|
27872
28185
|
};
|
|
27873
|
-
}, [nodes, edges, w, h, groups]);
|
|
28186
|
+
}, [nodes, edges, w, h, groups, layout]);
|
|
27874
28187
|
const viewBox = useMemo(() => {
|
|
27875
28188
|
if (!zoomToFit || !settled || simNodes.length === 0) {
|
|
27876
28189
|
return `0 0 ${w} ${h}`;
|
|
@@ -27945,6 +28258,19 @@ var init_GraphView = __esm({
|
|
|
27945
28258
|
viewBox,
|
|
27946
28259
|
preserveAspectRatio: "xMidYMid meet",
|
|
27947
28260
|
children: [
|
|
28261
|
+
layout !== "force" && /* @__PURE__ */ jsx("defs", { children: /* @__PURE__ */ jsx(
|
|
28262
|
+
"marker",
|
|
28263
|
+
{
|
|
28264
|
+
id: arrowMarkerId,
|
|
28265
|
+
viewBox: "0 0 10 10",
|
|
28266
|
+
refX: "9",
|
|
28267
|
+
refY: "5",
|
|
28268
|
+
markerWidth: "6",
|
|
28269
|
+
markerHeight: "6",
|
|
28270
|
+
orient: "auto-start-reverse",
|
|
28271
|
+
children: /* @__PURE__ */ jsx("path", { d: "M0,0 L10,5 L0,10 z", fill: "currentColor" })
|
|
28272
|
+
}
|
|
28273
|
+
) }),
|
|
27948
28274
|
edges.map((edge, idx) => {
|
|
27949
28275
|
const source = nodeMap.get(edge.source);
|
|
27950
28276
|
const target = nodeMap.get(edge.target);
|
|
@@ -27959,8 +28285,10 @@ var init_GraphView = __esm({
|
|
|
27959
28285
|
x2: target.x,
|
|
27960
28286
|
y2: target.y,
|
|
27961
28287
|
stroke: edge.color ?? DEFAULT_EDGE_COLOR,
|
|
28288
|
+
color: edge.color ?? DEFAULT_EDGE_COLOR,
|
|
27962
28289
|
strokeWidth: 1.5,
|
|
27963
|
-
opacity: isHighlighted ? 0.8 : 0.15
|
|
28290
|
+
opacity: isHighlighted ? 0.8 : 0.15,
|
|
28291
|
+
markerEnd: layout !== "force" ? `url(#${arrowMarkerId})` : void 0
|
|
27964
28292
|
}
|
|
27965
28293
|
),
|
|
27966
28294
|
showLabels && edge.label && /* @__PURE__ */ jsx(
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@almadar/ui",
|
|
3
|
-
"version": "5.
|
|
3
|
+
"version": "5.148.0",
|
|
4
4
|
"description": "React UI components, hooks, and providers for Almadar",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"sideEffects": [
|
|
@@ -118,12 +118,12 @@
|
|
|
118
118
|
"access": "public"
|
|
119
119
|
},
|
|
120
120
|
"dependencies": {
|
|
121
|
-
"@almadar/core": "^10.
|
|
122
|
-
"@almadar/evaluator": "^2.
|
|
121
|
+
"@almadar/core": "^10.58.0",
|
|
122
|
+
"@almadar/evaluator": "^2.41.0",
|
|
123
123
|
"@almadar/logger": "^1.11.0",
|
|
124
|
-
"@almadar/runtime": "^6.
|
|
125
|
-
"@almadar/std": "^16.
|
|
126
|
-
"@almadar/syntax": "^1.
|
|
124
|
+
"@almadar/runtime": "^6.53.0",
|
|
125
|
+
"@almadar/std": "^16.172.0",
|
|
126
|
+
"@almadar/syntax": "^1.15.0",
|
|
127
127
|
"@dnd-kit/core": "^6.3.1",
|
|
128
128
|
"@dnd-kit/sortable": "^10.0.0",
|
|
129
129
|
"@dnd-kit/utilities": "^3.2.2",
|