@inf-monkeys-tech/monkeys-design 1.0.38 → 1.0.39
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/components/agent-workbench/index.js +9 -0
- package/dist/components/agent-workbench/index.js.map +1 -1
- package/dist/components/agent-workbench/index.mjs +9 -0
- package/dist/components/agent-workbench/index.mjs.map +1 -1
- package/dist/components/base/index.js +9 -0
- package/dist/components/base/index.js.map +1 -1
- package/dist/components/base/index.mjs +9 -0
- package/dist/components/base/index.mjs.map +1 -1
- package/dist/components/data-explorer/index.js +9 -0
- package/dist/components/data-explorer/index.js.map +1 -1
- package/dist/components/data-explorer/index.mjs +9 -0
- package/dist/components/data-explorer/index.mjs.map +1 -1
- package/dist/components/layout/index.js +9 -0
- package/dist/components/layout/index.js.map +1 -1
- package/dist/components/layout/index.mjs +9 -0
- package/dist/components/layout/index.mjs.map +1 -1
- package/dist/components/runtime/index.js +9 -0
- package/dist/components/runtime/index.js.map +1 -1
- package/dist/components/runtime/index.mjs +9 -0
- package/dist/components/runtime/index.mjs.map +1 -1
- package/dist/components/toast/index.d.mts +1 -1
- package/dist/components/toast/index.d.ts +1 -1
- package/dist/components/toast/index.js +9 -0
- package/dist/components/toast/index.js.map +1 -1
- package/dist/components/toast/index.mjs +9 -0
- package/dist/components/toast/index.mjs.map +1 -1
- package/dist/components/toolbar/index.js +9 -0
- package/dist/components/toolbar/index.js.map +1 -1
- package/dist/components/toolbar/index.mjs +9 -0
- package/dist/components/toolbar/index.mjs.map +1 -1
- package/dist/components/workbench/index.d.mts +218 -6
- package/dist/components/workbench/index.d.ts +218 -6
- package/dist/components/workbench/index.js +1088 -97
- package/dist/components/workbench/index.js.map +1 -1
- package/dist/components/workbench/index.mjs +1089 -99
- package/dist/components/workbench/index.mjs.map +1 -1
- package/dist/index.d.mts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +838 -100
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +838 -101
- package/dist/index.mjs.map +1 -1
- package/dist/locale/index.d.mts +20 -2
- package/dist/locale/index.d.ts +20 -2
- package/dist/locale/index.js +22 -0
- package/dist/locale/index.js.map +1 -1
- package/dist/locale/index.mjs +22 -0
- package/dist/locale/index.mjs.map +1 -1
- package/dist/provider/index.d.mts +2 -2
- package/dist/provider/index.d.ts +2 -2
- package/dist/provider/index.js +22 -0
- package/dist/provider/index.js.map +1 -1
- package/dist/provider/index.mjs +22 -0
- package/dist/provider/index.mjs.map +1 -1
- package/dist/styles.css +1 -1
- package/dist/{types-b8d18b1454c2.d.mts → types-453d18eab188.d.mts} +10 -0
- package/dist/{types-b8d18b1454c2.d.ts → types-453d18eab188.d.ts} +10 -0
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -3072,6 +3072,15 @@ var enUS = {
|
|
|
3072
3072
|
}
|
|
3073
3073
|
},
|
|
3074
3074
|
workbench: {
|
|
3075
|
+
collection: {
|
|
3076
|
+
label: "Collection",
|
|
3077
|
+
loading: "Loading items",
|
|
3078
|
+
empty: "No items",
|
|
3079
|
+
loadError: "Unable to load items",
|
|
3080
|
+
refreshError: "Unable to refresh items",
|
|
3081
|
+
retry: "Retry",
|
|
3082
|
+
loadingMore: "Loading more items"
|
|
3083
|
+
},
|
|
3075
3084
|
interactiveTable: {
|
|
3076
3085
|
columnActions: "Column actions",
|
|
3077
3086
|
freezeColumn: "Freeze to left",
|
|
@@ -3343,6 +3352,15 @@ var zhCN = {
|
|
|
3343
3352
|
}
|
|
3344
3353
|
},
|
|
3345
3354
|
workbench: {
|
|
3355
|
+
collection: {
|
|
3356
|
+
label: "\u5185\u5BB9\u96C6\u5408",
|
|
3357
|
+
loading: "\u6B63\u5728\u52A0\u8F7D\u5185\u5BB9",
|
|
3358
|
+
empty: "\u6682\u65E0\u5185\u5BB9",
|
|
3359
|
+
loadError: "\u65E0\u6CD5\u52A0\u8F7D\u5185\u5BB9",
|
|
3360
|
+
refreshError: "\u65E0\u6CD5\u5237\u65B0\u5185\u5BB9",
|
|
3361
|
+
retry: "\u91CD\u8BD5",
|
|
3362
|
+
loadingMore: "\u6B63\u5728\u52A0\u8F7D\u66F4\u591A\u5185\u5BB9"
|
|
3363
|
+
},
|
|
3346
3364
|
interactiveTable: {
|
|
3347
3365
|
columnActions: "\u5217\u64CD\u4F5C",
|
|
3348
3366
|
freezeColumn: "\u56FA\u5B9A\u5230\u5DE6\u4FA7",
|
|
@@ -3634,6 +3652,10 @@ function mergeMonkeysLocaleMessages(base, override) {
|
|
|
3634
3652
|
}
|
|
3635
3653
|
},
|
|
3636
3654
|
workbench: {
|
|
3655
|
+
collection: {
|
|
3656
|
+
...base.workbench.collection,
|
|
3657
|
+
...override.workbench?.collection
|
|
3658
|
+
},
|
|
3637
3659
|
interactiveTable: {
|
|
3638
3660
|
...base.workbench.interactiveTable,
|
|
3639
3661
|
...override.workbench?.interactiveTable
|
|
@@ -22010,6 +22032,7 @@ var DEFAULT_MASONRY_GAP_PX = 12;
|
|
|
22010
22032
|
var DEFAULT_MASONRY_ROW_HEIGHT_PX = 8;
|
|
22011
22033
|
var DEFAULT_MASONRY_COLUMN_WIDTH_PX = 280;
|
|
22012
22034
|
var DEFAULT_MASONRY_ITEM_HEIGHT_PX = 240;
|
|
22035
|
+
var useIsomorphicLayoutEffect = typeof window === "undefined" ? React2.useEffect : React2.useLayoutEffect;
|
|
22013
22036
|
function clamp3(value, min5, max5) {
|
|
22014
22037
|
return Math.min(Math.max(value, min5), max5);
|
|
22015
22038
|
}
|
|
@@ -22114,9 +22137,12 @@ function WorkbenchMasonryLayout({
|
|
|
22114
22137
|
getItemKey = (item, index) => item?.id ?? item?.key ?? index,
|
|
22115
22138
|
getItemSize,
|
|
22116
22139
|
columnWidth = DEFAULT_MASONRY_COLUMN_WIDTH_PX,
|
|
22140
|
+
columnCount: requestedColumnCount,
|
|
22117
22141
|
gap = DEFAULT_MASONRY_GAP_PX,
|
|
22118
22142
|
rowHeight = DEFAULT_MASONRY_ROW_HEIGHT_PX,
|
|
22119
22143
|
placementStrategy = "shelf",
|
|
22144
|
+
containerProps,
|
|
22145
|
+
getItemProps,
|
|
22120
22146
|
className
|
|
22121
22147
|
}) {
|
|
22122
22148
|
const containerRef = React2.useRef(null);
|
|
@@ -22147,8 +22173,9 @@ function WorkbenchMasonryLayout({
|
|
|
22147
22173
|
}, []);
|
|
22148
22174
|
React2.useEffect(() => {
|
|
22149
22175
|
setMeasuredHeights((prev) => {
|
|
22176
|
+
const currentItemKeys = new Set(itemKeys);
|
|
22150
22177
|
const next = Object.fromEntries(
|
|
22151
|
-
Object.entries(prev).filter(([key]) =>
|
|
22178
|
+
Object.entries(prev).filter(([key]) => currentItemKeys.has(key))
|
|
22152
22179
|
);
|
|
22153
22180
|
return areMeasurementMapsEqual(prev, next) ? prev : next;
|
|
22154
22181
|
});
|
|
@@ -22159,7 +22186,8 @@ function WorkbenchMasonryLayout({
|
|
|
22159
22186
|
containerRef.current
|
|
22160
22187
|
);
|
|
22161
22188
|
const isDensePlacement = placementStrategy === "dense";
|
|
22162
|
-
const
|
|
22189
|
+
const normalizedRequestedColumnCount = Number.isFinite(requestedColumnCount) && Number(requestedColumnCount) > 0 ? clamp3(Math.round(Number(requestedColumnCount)), 1, 24) : void 0;
|
|
22190
|
+
const columnCount = normalizedRequestedColumnCount || getMasonryColumnCount({
|
|
22163
22191
|
containerWidth,
|
|
22164
22192
|
itemCount: items.length,
|
|
22165
22193
|
targetColumnWidth: resolvedTargetColumnWidth,
|
|
@@ -22205,7 +22233,7 @@ function WorkbenchMasonryLayout({
|
|
|
22205
22233
|
resolvedColumnWidth,
|
|
22206
22234
|
rowHeight
|
|
22207
22235
|
]);
|
|
22208
|
-
|
|
22236
|
+
useIsomorphicLayoutEffect(() => {
|
|
22209
22237
|
const nextMeasurements = {};
|
|
22210
22238
|
itemNodesRef.current.forEach((node, key) => {
|
|
22211
22239
|
const nextHeight = Math.ceil(node.getBoundingClientRect().height);
|
|
@@ -22267,10 +22295,21 @@ function WorkbenchMasonryLayout({
|
|
|
22267
22295
|
const positionedItems = layoutItems.map(({ key, item, columnSpan, rowSpan, size }) => {
|
|
22268
22296
|
const resolvedSpan = clamp3(columnSpan, 1, columnCount);
|
|
22269
22297
|
let startColumn = nextColumnIndex;
|
|
22270
|
-
if (
|
|
22271
|
-
|
|
22298
|
+
if (placementStrategy === "shortest") {
|
|
22299
|
+
let shortestBottom = Number.POSITIVE_INFINITY;
|
|
22300
|
+
for (let candidate = 0; candidate <= columnCount - resolvedSpan; candidate += 1) {
|
|
22301
|
+
const candidateBottom = Math.max(...columnBottoms.slice(candidate, candidate + resolvedSpan));
|
|
22302
|
+
if (candidateBottom < shortestBottom) {
|
|
22303
|
+
shortestBottom = candidateBottom;
|
|
22304
|
+
startColumn = candidate;
|
|
22305
|
+
}
|
|
22306
|
+
}
|
|
22307
|
+
} else {
|
|
22308
|
+
if (startColumn + resolvedSpan > columnCount) {
|
|
22309
|
+
startColumn = 0;
|
|
22310
|
+
}
|
|
22311
|
+
startColumn = Math.min(startColumn, columnCount - resolvedSpan);
|
|
22272
22312
|
}
|
|
22273
|
-
startColumn = Math.min(startColumn, columnCount - resolvedSpan);
|
|
22274
22313
|
const itemWidth = resolvedColumnWidth * resolvedSpan + gap * Math.max(resolvedSpan - 1, 0);
|
|
22275
22314
|
const itemHeight = getResolvedItemHeight({
|
|
22276
22315
|
size,
|
|
@@ -22283,9 +22322,11 @@ function WorkbenchMasonryLayout({
|
|
|
22283
22322
|
columnBottoms[columnIndex] = bottom + gap;
|
|
22284
22323
|
}
|
|
22285
22324
|
maxBottom = Math.max(maxBottom, bottom);
|
|
22286
|
-
|
|
22287
|
-
|
|
22288
|
-
nextColumnIndex
|
|
22325
|
+
if (placementStrategy !== "shortest") {
|
|
22326
|
+
nextColumnIndex = startColumn + resolvedSpan;
|
|
22327
|
+
if (nextColumnIndex >= columnCount) {
|
|
22328
|
+
nextColumnIndex = 0;
|
|
22329
|
+
}
|
|
22289
22330
|
}
|
|
22290
22331
|
return {
|
|
22291
22332
|
key,
|
|
@@ -22308,33 +22349,38 @@ function WorkbenchMasonryLayout({
|
|
|
22308
22349
|
"div",
|
|
22309
22350
|
{
|
|
22310
22351
|
ref: containerRef,
|
|
22311
|
-
|
|
22312
|
-
|
|
22352
|
+
...containerProps,
|
|
22353
|
+
className: cn("relative w-full", className, containerProps?.className),
|
|
22354
|
+
style: { ...containerProps?.style, height: `${orderedLayout.containerHeight}px` },
|
|
22313
22355
|
children: orderedLayout.positionedItems.map(({ key, item, columnSpan, rowSpan, size, itemWidth, left, top }) => {
|
|
22314
22356
|
const unresolvedSingleColumnWidth = containerWidth <= 0 && columnCount === 1;
|
|
22315
22357
|
const itemWidthValue = unresolvedSingleColumnWidth ? "100%" : `${itemWidth}px`;
|
|
22358
|
+
const layoutContext = {
|
|
22359
|
+
columnCount,
|
|
22360
|
+
columnSpan,
|
|
22361
|
+
columnWidth: resolvedColumnWidth,
|
|
22362
|
+
containerWidth,
|
|
22363
|
+
gap,
|
|
22364
|
+
itemWidth,
|
|
22365
|
+
placementStrategy,
|
|
22366
|
+
rowSpan,
|
|
22367
|
+
rowHeight,
|
|
22368
|
+
size
|
|
22369
|
+
};
|
|
22370
|
+
const itemProps = getItemProps?.(item, layoutContext);
|
|
22316
22371
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
22317
22372
|
"div",
|
|
22318
22373
|
{
|
|
22319
|
-
|
|
22374
|
+
...itemProps,
|
|
22375
|
+
className: cn("absolute min-w-0", itemProps?.className),
|
|
22320
22376
|
style: {
|
|
22377
|
+
...itemProps?.style,
|
|
22321
22378
|
left: unresolvedSingleColumnWidth ? 0 : `${left}px`,
|
|
22322
22379
|
top: `${top}px`,
|
|
22323
22380
|
width: itemWidthValue,
|
|
22324
22381
|
maxWidth: itemWidthValue
|
|
22325
22382
|
},
|
|
22326
|
-
children: /* @__PURE__ */ jsxRuntime.jsx("div", { ref: (node) => registerItemNode(key, node), className: "min-w-0", children: renderItem(item,
|
|
22327
|
-
columnCount,
|
|
22328
|
-
columnSpan,
|
|
22329
|
-
columnWidth: resolvedColumnWidth,
|
|
22330
|
-
containerWidth,
|
|
22331
|
-
gap,
|
|
22332
|
-
itemWidth,
|
|
22333
|
-
placementStrategy,
|
|
22334
|
-
rowSpan,
|
|
22335
|
-
rowHeight,
|
|
22336
|
-
size
|
|
22337
|
-
}) })
|
|
22383
|
+
children: /* @__PURE__ */ jsxRuntime.jsx("div", { ref: (node) => registerItemNode(key, node), role: "presentation", className: "min-w-0", children: renderItem(item, layoutContext) })
|
|
22338
22384
|
},
|
|
22339
22385
|
key
|
|
22340
22386
|
);
|
|
@@ -22346,35 +22392,717 @@ function WorkbenchMasonryLayout({
|
|
|
22346
22392
|
"div",
|
|
22347
22393
|
{
|
|
22348
22394
|
ref: containerRef,
|
|
22349
|
-
|
|
22395
|
+
...containerProps,
|
|
22396
|
+
className: cn("grid w-full items-start", className, containerProps?.className),
|
|
22350
22397
|
style: {
|
|
22398
|
+
...containerProps?.style,
|
|
22351
22399
|
gap: `${gap}px`,
|
|
22352
22400
|
gridAutoFlow: "row dense",
|
|
22353
22401
|
gridAutoRows: `${rowHeight}px`,
|
|
22354
22402
|
gridTemplateColumns: `repeat(${columnCount}, minmax(0, 1fr))`
|
|
22355
22403
|
},
|
|
22356
|
-
children: layoutItems.map(({ key, item, columnSpan, rowSpan, size }) =>
|
|
22357
|
-
|
|
22404
|
+
children: layoutItems.map(({ key, item, columnSpan, rowSpan, size }) => {
|
|
22405
|
+
const layoutContext = {
|
|
22406
|
+
columnCount,
|
|
22407
|
+
columnSpan,
|
|
22408
|
+
columnWidth: resolvedColumnWidth,
|
|
22409
|
+
containerWidth,
|
|
22410
|
+
gap,
|
|
22411
|
+
placementStrategy,
|
|
22412
|
+
rowSpan,
|
|
22413
|
+
rowHeight,
|
|
22414
|
+
size
|
|
22415
|
+
};
|
|
22416
|
+
const itemProps = getItemProps?.(item, layoutContext);
|
|
22417
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
22418
|
+
"div",
|
|
22419
|
+
{
|
|
22420
|
+
...itemProps,
|
|
22421
|
+
className: cn("min-w-0", itemProps?.className),
|
|
22422
|
+
style: {
|
|
22423
|
+
...itemProps?.style,
|
|
22424
|
+
gridColumn: `span ${columnSpan}`,
|
|
22425
|
+
gridRow: `span ${rowSpan}`
|
|
22426
|
+
},
|
|
22427
|
+
children: /* @__PURE__ */ jsxRuntime.jsx("div", { ref: (node) => registerItemNode(key, node), role: "presentation", className: "min-w-0", children: renderItem(item, layoutContext) })
|
|
22428
|
+
},
|
|
22429
|
+
key
|
|
22430
|
+
);
|
|
22431
|
+
})
|
|
22432
|
+
}
|
|
22433
|
+
);
|
|
22434
|
+
}
|
|
22435
|
+
var DEFAULT_GAP_PX = 12;
|
|
22436
|
+
var DEFAULT_ROW_HEIGHT_PX = 8;
|
|
22437
|
+
var DEFAULT_CARD_WIDTH_PX = 280;
|
|
22438
|
+
var BREAKPOINT_TABLET_PX = 640;
|
|
22439
|
+
var BREAKPOINT_DESKTOP_PX = 1024;
|
|
22440
|
+
var MAX_COLUMN_COUNT = 24;
|
|
22441
|
+
function clamp4(value, min5, max5) {
|
|
22442
|
+
return Math.min(Math.max(value, min5), max5);
|
|
22443
|
+
}
|
|
22444
|
+
function resolveRenderableSlot(slot, context) {
|
|
22445
|
+
return typeof slot === "function" ? slot(context) : slot;
|
|
22446
|
+
}
|
|
22447
|
+
function resolveLengthToPixels2(value, fallback, node) {
|
|
22448
|
+
if (typeof value === "number" && Number.isFinite(value) && value > 0) return value;
|
|
22449
|
+
if (typeof value !== "string") return fallback;
|
|
22450
|
+
const normalized = value.trim().toLowerCase();
|
|
22451
|
+
if (!normalized) return fallback;
|
|
22452
|
+
if (/^\d+(\.\d+)?(px)?$/.test(normalized)) {
|
|
22453
|
+
const parsed = Number.parseFloat(normalized);
|
|
22454
|
+
return Number.isFinite(parsed) && parsed > 0 ? parsed : fallback;
|
|
22455
|
+
}
|
|
22456
|
+
if (normalized.endsWith("rem")) {
|
|
22457
|
+
const parsed = Number.parseFloat(normalized);
|
|
22458
|
+
const rootFontSize = typeof window === "undefined" ? 16 : Number.parseFloat(window.getComputedStyle(node || document.documentElement).fontSize) || 16;
|
|
22459
|
+
return Number.isFinite(parsed) && parsed > 0 ? parsed * rootFontSize : fallback;
|
|
22460
|
+
}
|
|
22461
|
+
return fallback;
|
|
22462
|
+
}
|
|
22463
|
+
function normalizeColumns(value) {
|
|
22464
|
+
if (typeof value !== "number" || !Number.isFinite(value) || value <= 0) return void 0;
|
|
22465
|
+
return clamp4(Math.round(value), 1, MAX_COLUMN_COUNT);
|
|
22466
|
+
}
|
|
22467
|
+
function resolveResponsiveColumns(columns, containerWidth) {
|
|
22468
|
+
if (columns === "auto" || columns === void 0) return void 0;
|
|
22469
|
+
if (typeof columns === "number") return normalizeColumns(columns);
|
|
22470
|
+
const mobile = normalizeColumns(columns.mobile);
|
|
22471
|
+
const tablet = normalizeColumns(columns.tablet);
|
|
22472
|
+
const desktop = normalizeColumns(columns.desktop);
|
|
22473
|
+
if (containerWidth >= BREAKPOINT_DESKTOP_PX) return desktop ?? tablet ?? mobile;
|
|
22474
|
+
if (containerWidth >= BREAKPOINT_TABLET_PX) return tablet ?? mobile ?? desktop;
|
|
22475
|
+
return mobile ?? tablet ?? desktop;
|
|
22476
|
+
}
|
|
22477
|
+
function resolveColumnCount({
|
|
22478
|
+
containerWidth,
|
|
22479
|
+
itemCount,
|
|
22480
|
+
gap,
|
|
22481
|
+
columns,
|
|
22482
|
+
minCardWidth,
|
|
22483
|
+
idealCardWidth,
|
|
22484
|
+
maxCardWidth,
|
|
22485
|
+
node
|
|
22486
|
+
}) {
|
|
22487
|
+
const fixedColumns = resolveResponsiveColumns(columns, containerWidth);
|
|
22488
|
+
if (fixedColumns) return fixedColumns;
|
|
22489
|
+
if (!containerWidth) return 1;
|
|
22490
|
+
const idealWidth = resolveLengthToPixels2(idealCardWidth, DEFAULT_CARD_WIDTH_PX, node);
|
|
22491
|
+
const minWidth = resolveLengthToPixels2(minCardWidth, idealWidth * 0.78, node);
|
|
22492
|
+
const maxWidth = Math.max(
|
|
22493
|
+
minWidth,
|
|
22494
|
+
resolveLengthToPixels2(maxCardWidth, idealWidth * 1.35, node)
|
|
22495
|
+
);
|
|
22496
|
+
const safeItemCount = Math.max(itemCount, 1);
|
|
22497
|
+
const maxCandidate = Math.max(
|
|
22498
|
+
1,
|
|
22499
|
+
Math.min(
|
|
22500
|
+
safeItemCount,
|
|
22501
|
+
Math.ceil((containerWidth + gap) / (Math.max(minWidth * 0.75, 1) + gap))
|
|
22502
|
+
)
|
|
22503
|
+
);
|
|
22504
|
+
let bestCount = 1;
|
|
22505
|
+
let bestScore = Number.POSITIVE_INFINITY;
|
|
22506
|
+
for (let candidate = 1; candidate <= maxCandidate; candidate += 1) {
|
|
22507
|
+
const width = (containerWidth - gap * Math.max(candidate - 1, 0)) / candidate;
|
|
22508
|
+
if (!Number.isFinite(width) || width <= 0) continue;
|
|
22509
|
+
const score = Math.abs(width - idealWidth) + Math.max(0, minWidth - width) * 3 + Math.max(0, width - maxWidth) * 2;
|
|
22510
|
+
if (score < bestScore) {
|
|
22511
|
+
bestScore = score;
|
|
22512
|
+
bestCount = candidate;
|
|
22513
|
+
}
|
|
22514
|
+
}
|
|
22515
|
+
return bestCount;
|
|
22516
|
+
}
|
|
22517
|
+
function normalizeGap(value) {
|
|
22518
|
+
return typeof value === "number" && Number.isFinite(value) && value >= 0 ? value : DEFAULT_GAP_PX;
|
|
22519
|
+
}
|
|
22520
|
+
function normalizeRowHeight(value) {
|
|
22521
|
+
return typeof value === "number" && Number.isFinite(value) && value > 0 ? value : DEFAULT_ROW_HEIGHT_PX;
|
|
22522
|
+
}
|
|
22523
|
+
function normalizeThreshold(value) {
|
|
22524
|
+
return typeof value === "number" && Number.isFinite(value) ? clamp4(value, 0, 1) : 0;
|
|
22525
|
+
}
|
|
22526
|
+
function normalizeItemSize(size, aspectRatio, columnWidth) {
|
|
22527
|
+
const normalizedAspectRatio = Number.isFinite(aspectRatio) && Number(aspectRatio) > 0 ? Number(aspectRatio) : void 0;
|
|
22528
|
+
const normalizedHeight = size?.height ?? (normalizedAspectRatio ? Math.max(1, columnWidth / normalizedAspectRatio) : void 0);
|
|
22529
|
+
return {
|
|
22530
|
+
...size,
|
|
22531
|
+
height: normalizedHeight
|
|
22532
|
+
};
|
|
22533
|
+
}
|
|
22534
|
+
function getDefaultItemKey(item, index) {
|
|
22535
|
+
if (item && typeof item === "object") {
|
|
22536
|
+
const candidate = item;
|
|
22537
|
+
if (typeof candidate.id === "string" || typeof candidate.id === "number") return candidate.id;
|
|
22538
|
+
if (typeof candidate.key === "string" || typeof candidate.key === "number") return candidate.key;
|
|
22539
|
+
}
|
|
22540
|
+
return index;
|
|
22541
|
+
}
|
|
22542
|
+
function getScrollStorageKey(key) {
|
|
22543
|
+
return `@inf-monkeys-tech/monkeys-design:workbench-collection:${key}`;
|
|
22544
|
+
}
|
|
22545
|
+
function getParentScrollOwner(node) {
|
|
22546
|
+
let current = node?.parentElement ?? null;
|
|
22547
|
+
while (current) {
|
|
22548
|
+
if (typeof window === "undefined") return current;
|
|
22549
|
+
const overflowY = window.getComputedStyle(current).overflowY;
|
|
22550
|
+
if (overflowY === "auto" || overflowY === "scroll") return current;
|
|
22551
|
+
current = current.parentElement;
|
|
22552
|
+
}
|
|
22553
|
+
return null;
|
|
22554
|
+
}
|
|
22555
|
+
function setsEqual(left, right) {
|
|
22556
|
+
if (left.size !== right.size) return false;
|
|
22557
|
+
for (const value of left) {
|
|
22558
|
+
if (!right.has(value)) return false;
|
|
22559
|
+
}
|
|
22560
|
+
return true;
|
|
22561
|
+
}
|
|
22562
|
+
function isInteractiveEventTarget(target, currentTarget) {
|
|
22563
|
+
if (typeof Element === "undefined" || !(target instanceof Element) || target === currentTarget) return false;
|
|
22564
|
+
const control = target.closest(
|
|
22565
|
+
'a, button, input, select, textarea, summary, [contenteditable="true"], [data-collection-action]'
|
|
22566
|
+
);
|
|
22567
|
+
return Boolean(control && currentTarget.contains(control));
|
|
22568
|
+
}
|
|
22569
|
+
function warnOnDuplicateKeys(keys) {
|
|
22570
|
+
if (typeof process !== "undefined" && process.env?.NODE_ENV === "production") return;
|
|
22571
|
+
const seen = /* @__PURE__ */ new Set();
|
|
22572
|
+
const duplicates = /* @__PURE__ */ new Set();
|
|
22573
|
+
keys.forEach((key) => {
|
|
22574
|
+
const stringKey = String(key);
|
|
22575
|
+
if (seen.has(stringKey)) duplicates.add(stringKey);
|
|
22576
|
+
seen.add(stringKey);
|
|
22577
|
+
});
|
|
22578
|
+
if (duplicates.size) {
|
|
22579
|
+
console.warn(`WorkbenchCollection received duplicate item keys: ${Array.from(duplicates).join(", ")}`);
|
|
22580
|
+
}
|
|
22581
|
+
}
|
|
22582
|
+
function WorkbenchCollection({
|
|
22583
|
+
items,
|
|
22584
|
+
config,
|
|
22585
|
+
renderItem,
|
|
22586
|
+
slots,
|
|
22587
|
+
callbacks,
|
|
22588
|
+
className,
|
|
22589
|
+
classNames,
|
|
22590
|
+
style,
|
|
22591
|
+
ariaLabel
|
|
22592
|
+
}) {
|
|
22593
|
+
const componentAttributes = useMonkeysComponentAttributes();
|
|
22594
|
+
const localeMessages = useMonkeysLocaleMessages().workbench.collection;
|
|
22595
|
+
const componentId = React2.useId().replace(/:/g, "");
|
|
22596
|
+
const rootRef = React2.useRef(null);
|
|
22597
|
+
const itemsRef = React2.useRef(null);
|
|
22598
|
+
const loadMoreRef = React2.useRef(null);
|
|
22599
|
+
const lastSelectedIndexRef = React2.useRef(null);
|
|
22600
|
+
const loadMoreLockedRef = React2.useRef(false);
|
|
22601
|
+
const layoutReadyRef = React2.useRef(false);
|
|
22602
|
+
const [containerWidth, setContainerWidth] = React2.useState(0);
|
|
22603
|
+
const [itemsNode, setItemsNode] = React2.useState(null);
|
|
22604
|
+
const [internalSelectedKeys, setInternalSelectedKeys] = React2.useState(
|
|
22605
|
+
() => new Set(config.selection?.defaultSelectedKeys ?? [])
|
|
22606
|
+
);
|
|
22607
|
+
const callbacksRef = React2.useRef(callbacks);
|
|
22608
|
+
callbacksRef.current = callbacks;
|
|
22609
|
+
const registerItemsNode = React2.useCallback((node) => {
|
|
22610
|
+
itemsRef.current = node;
|
|
22611
|
+
setItemsNode(node);
|
|
22612
|
+
}, []);
|
|
22613
|
+
const mode = config.layout.mode;
|
|
22614
|
+
if (mode !== "grid" && mode !== "masonry" && mode !== "dense" && mode !== "rail") {
|
|
22615
|
+
throw new TypeError(`WorkbenchCollection layout.mode "${String(mode)}" is not supported.`);
|
|
22616
|
+
}
|
|
22617
|
+
const gap = normalizeGap(config.layout.gap);
|
|
22618
|
+
const rowHeight = normalizeRowHeight(config.layout.rowHeight);
|
|
22619
|
+
const getItemKey = config.getItemKey ?? getDefaultItemKey;
|
|
22620
|
+
const normalizedItems = React2.useMemo(() => items.map((item, index) => {
|
|
22621
|
+
const key = getItemKey(item, index);
|
|
22622
|
+
return { item, index, key, stringKey: String(key) };
|
|
22623
|
+
}), [getItemKey, items]);
|
|
22624
|
+
const keys = React2.useMemo(
|
|
22625
|
+
() => normalizedItems.map(({ key }) => key),
|
|
22626
|
+
[normalizedItems]
|
|
22627
|
+
);
|
|
22628
|
+
const keysSignature = normalizedItems.map(({ stringKey }) => stringKey).join("");
|
|
22629
|
+
React2.useEffect(() => warnOnDuplicateKeys(keys), [keys, keysSignature]);
|
|
22630
|
+
const selectionMode = config.selection?.mode ?? "none";
|
|
22631
|
+
const controlledSelection = config.selection?.selectedKeys !== void 0;
|
|
22632
|
+
const selectedKeys = React2.useMemo(
|
|
22633
|
+
() => selectionMode === "none" ? /* @__PURE__ */ new Set() : controlledSelection ? new Set(config.selection?.selectedKeys ?? []) : internalSelectedKeys,
|
|
22634
|
+
[config.selection?.selectedKeys, controlledSelection, internalSelectedKeys, selectionMode]
|
|
22635
|
+
);
|
|
22636
|
+
React2.useEffect(() => {
|
|
22637
|
+
if (controlledSelection) return;
|
|
22638
|
+
const availableKeys = new Set(keys);
|
|
22639
|
+
setInternalSelectedKeys((previous) => {
|
|
22640
|
+
const next = new Set(Array.from(previous).filter((key) => availableKeys.has(key)));
|
|
22641
|
+
return setsEqual(previous, next) ? previous : next;
|
|
22642
|
+
});
|
|
22643
|
+
}, [controlledSelection, keys, keysSignature]);
|
|
22644
|
+
React2.useEffect(() => {
|
|
22645
|
+
const node = itemsNode;
|
|
22646
|
+
if (!node) return void 0;
|
|
22647
|
+
const updateWidth = () => {
|
|
22648
|
+
const nextWidth = Math.round(node.getBoundingClientRect().width);
|
|
22649
|
+
setContainerWidth((previous) => previous === nextWidth ? previous : nextWidth);
|
|
22650
|
+
};
|
|
22651
|
+
updateWidth();
|
|
22652
|
+
if (typeof ResizeObserver === "function") {
|
|
22653
|
+
const observer = new ResizeObserver(updateWidth);
|
|
22654
|
+
observer.observe(node);
|
|
22655
|
+
return () => observer.disconnect();
|
|
22656
|
+
}
|
|
22657
|
+
if (typeof window === "undefined") return void 0;
|
|
22658
|
+
window.addEventListener("resize", updateWidth);
|
|
22659
|
+
return () => window.removeEventListener("resize", updateWidth);
|
|
22660
|
+
}, [itemsNode]);
|
|
22661
|
+
const columnCount = resolveColumnCount({
|
|
22662
|
+
containerWidth,
|
|
22663
|
+
itemCount: normalizedItems.length,
|
|
22664
|
+
gap,
|
|
22665
|
+
columns: config.layout.columns,
|
|
22666
|
+
minCardWidth: config.layout.minCardWidth,
|
|
22667
|
+
idealCardWidth: config.layout.idealCardWidth ?? config.layout.columnWidth,
|
|
22668
|
+
maxCardWidth: config.layout.maxCardWidth,
|
|
22669
|
+
node: itemsRef.current
|
|
22670
|
+
});
|
|
22671
|
+
const columnWidth = containerWidth > 0 ? Math.max(0, (containerWidth - gap * Math.max(columnCount - 1, 0)) / columnCount) : resolveLengthToPixels2(
|
|
22672
|
+
config.layout.cardWidth ?? config.layout.columnWidth ?? config.layout.idealCardWidth,
|
|
22673
|
+
DEFAULT_CARD_WIDTH_PX,
|
|
22674
|
+
itemsRef.current
|
|
22675
|
+
);
|
|
22676
|
+
const placementStrategy = config.layout.placementStrategy ?? (mode === "dense" ? "dense" : mode === "masonry" ? "shortest" : "shelf");
|
|
22677
|
+
const labels = React2.useMemo(() => ({
|
|
22678
|
+
collection: config.labels?.collection ?? localeMessages.label,
|
|
22679
|
+
loading: config.labels?.loading ?? localeMessages.loading,
|
|
22680
|
+
empty: config.labels?.empty ?? localeMessages.empty,
|
|
22681
|
+
loadError: config.labels?.loadError ?? localeMessages.loadError,
|
|
22682
|
+
refreshError: config.labels?.refreshError ?? localeMessages.refreshError,
|
|
22683
|
+
retry: config.labels?.retry ?? localeMessages.retry,
|
|
22684
|
+
loadingMore: config.labels?.loadingMore ?? localeMessages.loadingMore
|
|
22685
|
+
}), [config.labels, localeMessages]);
|
|
22686
|
+
const virtualizationError = React2.useMemo(() => {
|
|
22687
|
+
const virtualization = config.virtualization;
|
|
22688
|
+
if (virtualization?.enabled !== true || virtualization.fallback !== "error") return null;
|
|
22689
|
+
if (!virtualization.adapter) {
|
|
22690
|
+
return new Error("WorkbenchCollection virtualization requires an adapter.");
|
|
22691
|
+
}
|
|
22692
|
+
if (virtualization.adapter.supports?.(mode) === false) {
|
|
22693
|
+
return new Error(`WorkbenchCollection virtualization adapter does not support mode "${mode}".`);
|
|
22694
|
+
}
|
|
22695
|
+
return null;
|
|
22696
|
+
}, [config.virtualization, mode]);
|
|
22697
|
+
const layoutSnapshot = React2.useMemo(() => ({
|
|
22698
|
+
mode,
|
|
22699
|
+
columnCount,
|
|
22700
|
+
columnWidth,
|
|
22701
|
+
containerWidth,
|
|
22702
|
+
gap,
|
|
22703
|
+
itemCount: normalizedItems.length
|
|
22704
|
+
}), [columnCount, columnWidth, containerWidth, gap, mode, normalizedItems.length]);
|
|
22705
|
+
React2.useEffect(() => {
|
|
22706
|
+
callbacksRef.current?.onLayoutChange?.(layoutSnapshot);
|
|
22707
|
+
if (containerWidth > 0 && !layoutReadyRef.current) {
|
|
22708
|
+
layoutReadyRef.current = true;
|
|
22709
|
+
callbacksRef.current?.onLayoutReady?.(layoutSnapshot);
|
|
22710
|
+
}
|
|
22711
|
+
}, [layoutSnapshot, containerWidth]);
|
|
22712
|
+
React2.useEffect(() => {
|
|
22713
|
+
layoutReadyRef.current = false;
|
|
22714
|
+
}, [mode]);
|
|
22715
|
+
const resolveScrollOwner = React2.useCallback(() => {
|
|
22716
|
+
const requestedOwner = config.layout.scrollOwner;
|
|
22717
|
+
if (requestedOwner && requestedOwner !== "self" && requestedOwner !== "parent") return requestedOwner;
|
|
22718
|
+
if (requestedOwner === "parent") return getParentScrollOwner(rootRef.current);
|
|
22719
|
+
return rootRef.current;
|
|
22720
|
+
}, [config.layout.scrollOwner]);
|
|
22721
|
+
React2.useEffect(() => {
|
|
22722
|
+
const restorationKey = config.scrollRestorationKey?.trim();
|
|
22723
|
+
if (!restorationKey || typeof window === "undefined") return void 0;
|
|
22724
|
+
const owner = resolveScrollOwner();
|
|
22725
|
+
if (!owner) return void 0;
|
|
22726
|
+
const storageKey = getScrollStorageKey(restorationKey);
|
|
22727
|
+
try {
|
|
22728
|
+
const stored = Number.parseFloat(window.sessionStorage.getItem(storageKey) ?? "");
|
|
22729
|
+
if (Number.isFinite(stored) && stored >= 0) owner.scrollTop = stored;
|
|
22730
|
+
} catch {
|
|
22731
|
+
}
|
|
22732
|
+
const saveScrollPosition = () => {
|
|
22733
|
+
try {
|
|
22734
|
+
window.sessionStorage.setItem(storageKey, String(owner.scrollTop));
|
|
22735
|
+
} catch {
|
|
22736
|
+
}
|
|
22737
|
+
};
|
|
22738
|
+
owner.addEventListener("scroll", saveScrollPosition, { passive: true });
|
|
22739
|
+
return () => {
|
|
22740
|
+
saveScrollPosition();
|
|
22741
|
+
owner.removeEventListener("scroll", saveScrollPosition);
|
|
22742
|
+
};
|
|
22743
|
+
}, [config.scrollRestorationKey, resolveScrollOwner]);
|
|
22744
|
+
const state = config.state;
|
|
22745
|
+
const loading = state?.loading === true;
|
|
22746
|
+
const loadingMore = state?.loadingMore === true;
|
|
22747
|
+
const hasMore = state?.hasMore === true;
|
|
22748
|
+
const canLoadMore = typeof callbacks?.onLoadMore === "function";
|
|
22749
|
+
const effectiveError = state?.error ?? virtualizationError;
|
|
22750
|
+
React2.useEffect(() => {
|
|
22751
|
+
if (!loadingMore || !hasMore) loadMoreLockedRef.current = false;
|
|
22752
|
+
}, [hasMore, loadingMore, normalizedItems.length, keysSignature]);
|
|
22753
|
+
React2.useEffect(() => {
|
|
22754
|
+
const sentinel = loadMoreRef.current;
|
|
22755
|
+
if (!sentinel || !canLoadMore || !hasMore || loadingMore) return void 0;
|
|
22756
|
+
if (typeof IntersectionObserver !== "function") return void 0;
|
|
22757
|
+
const owner = resolveScrollOwner();
|
|
22758
|
+
const observer = new IntersectionObserver((entries) => {
|
|
22759
|
+
if (!entries.some((entry) => entry.isIntersecting) || loadMoreLockedRef.current) return;
|
|
22760
|
+
loadMoreLockedRef.current = true;
|
|
22761
|
+
try {
|
|
22762
|
+
const result = callbacksRef.current?.onLoadMore?.();
|
|
22763
|
+
if (result && typeof result.then === "function") {
|
|
22764
|
+
void result.catch(() => {
|
|
22765
|
+
loadMoreLockedRef.current = false;
|
|
22766
|
+
});
|
|
22767
|
+
}
|
|
22768
|
+
} catch (error) {
|
|
22769
|
+
loadMoreLockedRef.current = false;
|
|
22770
|
+
throw error;
|
|
22771
|
+
}
|
|
22772
|
+
}, {
|
|
22773
|
+
root: owner === rootRef.current ? owner : owner || null,
|
|
22774
|
+
rootMargin: config.loading?.rootMargin ?? "240px",
|
|
22775
|
+
threshold: normalizeThreshold(config.loading?.threshold)
|
|
22776
|
+
});
|
|
22777
|
+
observer.observe(sentinel);
|
|
22778
|
+
return () => observer.disconnect();
|
|
22779
|
+
}, [canLoadMore, config.loading?.rootMargin, config.loading?.threshold, hasMore, keysSignature, loadingMore, normalizedItems.length, resolveScrollOwner]);
|
|
22780
|
+
const groups = React2.useMemo(() => {
|
|
22781
|
+
if (!config.grouping) {
|
|
22782
|
+
return [{ key: "__all__", stringKey: "__all__", items: normalizedItems }];
|
|
22783
|
+
}
|
|
22784
|
+
const grouped = /* @__PURE__ */ new Map();
|
|
22785
|
+
normalizedItems.forEach((entry) => {
|
|
22786
|
+
const groupKey = config.grouping?.getGroupKey(entry.item, entry.index) ?? "__all__";
|
|
22787
|
+
const stringKey = String(groupKey);
|
|
22788
|
+
const existing = grouped.get(stringKey);
|
|
22789
|
+
if (existing) {
|
|
22790
|
+
existing.items.push(entry);
|
|
22791
|
+
return;
|
|
22792
|
+
}
|
|
22793
|
+
grouped.set(stringKey, {
|
|
22794
|
+
key: groupKey,
|
|
22795
|
+
stringKey,
|
|
22796
|
+
label: config.grouping?.getGroupLabel?.(groupKey, entry.item),
|
|
22797
|
+
items: [entry]
|
|
22798
|
+
});
|
|
22799
|
+
});
|
|
22800
|
+
return Array.from(grouped.values());
|
|
22801
|
+
}, [config.grouping, normalizedItems]);
|
|
22802
|
+
const setSelection = React2.useCallback((entry, behavior = config.selection?.behavior ?? (selectionMode === "multiple" ? "toggle" : "replace")) => {
|
|
22803
|
+
if (selectionMode === "none" || config.selection?.isItemDisabled?.(entry.item, entry.index)) return;
|
|
22804
|
+
const current = new Set(selectedKeys);
|
|
22805
|
+
const next = /* @__PURE__ */ new Set();
|
|
22806
|
+
if (selectionMode === "single") {
|
|
22807
|
+
if (!(behavior === "toggle" && current.has(entry.key))) next.add(entry.key);
|
|
22808
|
+
} else if (behavior === "range" && lastSelectedIndexRef.current !== null) {
|
|
22809
|
+
current.forEach((key) => next.add(key));
|
|
22810
|
+
const start = Math.min(lastSelectedIndexRef.current, entry.index);
|
|
22811
|
+
const end = Math.max(lastSelectedIndexRef.current, entry.index);
|
|
22812
|
+
normalizedItems.slice(start, end + 1).forEach((candidate) => {
|
|
22813
|
+
if (!config.selection?.isItemDisabled?.(candidate.item, candidate.index)) next.add(candidate.key);
|
|
22814
|
+
});
|
|
22815
|
+
} else if (behavior === "replace") {
|
|
22816
|
+
next.add(entry.key);
|
|
22817
|
+
} else {
|
|
22818
|
+
current.forEach((key) => next.add(key));
|
|
22819
|
+
if (next.has(entry.key)) next.delete(entry.key);
|
|
22820
|
+
else next.add(entry.key);
|
|
22821
|
+
}
|
|
22822
|
+
lastSelectedIndexRef.current = entry.index;
|
|
22823
|
+
if (!controlledSelection) setInternalSelectedKeys(next);
|
|
22824
|
+
callbacks?.onSelectionChange?.(next, { item: entry.item, key: entry.key, behavior });
|
|
22825
|
+
}, [callbacks, config.selection, controlledSelection, normalizedItems, selectedKeys, selectionMode]);
|
|
22826
|
+
const createItemContext = React2.useCallback((entry, layout) => {
|
|
22827
|
+
const disabled = config.selection?.isItemDisabled?.(entry.item, entry.index) ?? false;
|
|
22828
|
+
const context = {
|
|
22829
|
+
item: entry.item,
|
|
22830
|
+
index: entry.index,
|
|
22831
|
+
key: entry.key,
|
|
22832
|
+
status: config.getItemStatus?.(entry.item, entry.index) ?? "idle",
|
|
22833
|
+
disabled,
|
|
22834
|
+
selected: selectedKeys.has(entry.key),
|
|
22835
|
+
selectionMode,
|
|
22836
|
+
layout,
|
|
22837
|
+
select: (behavior) => setSelection(entry, behavior),
|
|
22838
|
+
preview: () => callbacks?.onItemPreview?.(entry.item, context),
|
|
22839
|
+
detail: () => callbacks?.onItemDetail?.(entry.item, context),
|
|
22840
|
+
renderSlot: (name) => {
|
|
22841
|
+
return slots?.item?.[name]?.(entry.item, context);
|
|
22842
|
+
},
|
|
22843
|
+
notifyMediaLoad: () => callbacks?.onMediaLoad?.(entry.item, context),
|
|
22844
|
+
notifyMediaError: (error) => callbacks?.onMediaError?.(entry.item, context, error)
|
|
22845
|
+
};
|
|
22846
|
+
return context;
|
|
22847
|
+
}, [callbacks, config.getItemStatus, config.selection, selectedKeys, selectionMode, setSelection, slots?.item]);
|
|
22848
|
+
const getItemInteractionProps = React2.useCallback((entry, context) => {
|
|
22849
|
+
const handleKeyboard = (event) => {
|
|
22850
|
+
if (event.target !== event.currentTarget || event.key !== "Enter" && event.key !== " ") return;
|
|
22851
|
+
event.preventDefault();
|
|
22852
|
+
if (selectionMode !== "none") context.select(event.shiftKey ? "range" : void 0);
|
|
22853
|
+
else callbacks?.onItemClick?.(entry.item, context, event);
|
|
22854
|
+
};
|
|
22855
|
+
return {
|
|
22856
|
+
id: `${componentId}-item-${entry.index}`,
|
|
22857
|
+
"data-monkeys-collection-item": "",
|
|
22858
|
+
"data-item-key": entry.stringKey,
|
|
22859
|
+
"data-selected": context.selected || void 0,
|
|
22860
|
+
"data-disabled": context.disabled || void 0,
|
|
22861
|
+
"data-status": context.status,
|
|
22862
|
+
role: selectionMode === "none" ? "listitem" : "option",
|
|
22863
|
+
"aria-selected": selectionMode === "none" ? void 0 : context.selected,
|
|
22864
|
+
"aria-disabled": context.disabled || void 0,
|
|
22865
|
+
tabIndex: callbacks?.onItemClick || selectionMode !== "none" ? 0 : void 0,
|
|
22866
|
+
draggable: callbacks?.onItemDragStart ? true : void 0,
|
|
22867
|
+
className: cn(
|
|
22868
|
+
"min-w-0 outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2",
|
|
22869
|
+
config.appearance?.hover === "lift" && "transition-transform hover:-translate-y-0.5 motion-reduce:transform-none",
|
|
22870
|
+
config.appearance?.selection === "ring" && context.selected && "ring-2 ring-primary",
|
|
22871
|
+
config.appearance?.selection === "outline" && context.selected && "outline outline-2 outline-primary",
|
|
22872
|
+
classNames?.item
|
|
22873
|
+
),
|
|
22874
|
+
onClick: (event) => {
|
|
22875
|
+
if (isInteractiveEventTarget(event.target, event.currentTarget)) return;
|
|
22876
|
+
if (selectionMode !== "none") context.select(event.shiftKey ? "range" : void 0);
|
|
22877
|
+
callbacks?.onItemClick?.(entry.item, context, event);
|
|
22878
|
+
},
|
|
22879
|
+
onDoubleClick: (event) => {
|
|
22880
|
+
if (isInteractiveEventTarget(event.target, event.currentTarget)) return;
|
|
22881
|
+
callbacks?.onItemDoubleClick?.(entry.item, context, event);
|
|
22882
|
+
},
|
|
22883
|
+
onKeyDown: handleKeyboard,
|
|
22884
|
+
onDragStart: (event) => callbacks?.onItemDragStart?.(entry.item, context, event),
|
|
22885
|
+
onDragOver: callbacks?.onItemDrop ? (event) => event.preventDefault() : void 0,
|
|
22886
|
+
onDrop: (event) => callbacks?.onItemDrop?.(entry.item, context, event)
|
|
22887
|
+
};
|
|
22888
|
+
}, [callbacks, classNames?.item, componentId, config.appearance, selectionMode]);
|
|
22889
|
+
const renderEntry = React2.useCallback((entry, layout, includeShell = true) => {
|
|
22890
|
+
const context = createItemContext(entry, layout);
|
|
22891
|
+
if (!includeShell) return renderItem(entry.item, context);
|
|
22892
|
+
return /* @__PURE__ */ jsxRuntime.jsx("div", { ...getItemInteractionProps(entry, context), children: renderItem(entry.item, context) });
|
|
22893
|
+
}, [createItemContext, getItemInteractionProps, renderItem]);
|
|
22894
|
+
const baseLayoutContext = React2.useMemo(() => ({
|
|
22895
|
+
mode,
|
|
22896
|
+
columnCount,
|
|
22897
|
+
columnWidth,
|
|
22898
|
+
containerWidth,
|
|
22899
|
+
gap,
|
|
22900
|
+
placementStrategy,
|
|
22901
|
+
rowHeight
|
|
22902
|
+
}), [columnCount, columnWidth, containerWidth, gap, mode, placementStrategy, rowHeight]);
|
|
22903
|
+
const renderGroupItems = (group) => {
|
|
22904
|
+
const virtualization = config.virtualization;
|
|
22905
|
+
const adapter = virtualization?.adapter;
|
|
22906
|
+
const virtualizationRequested = virtualization?.enabled === true;
|
|
22907
|
+
if (virtualizationRequested && (!adapter || adapter.supports?.(mode) === false)) {
|
|
22908
|
+
if (virtualization?.fallback === "error") {
|
|
22909
|
+
return null;
|
|
22910
|
+
}
|
|
22911
|
+
}
|
|
22912
|
+
if (virtualizationRequested && adapter && adapter.supports?.(mode) !== false) {
|
|
22913
|
+
return adapter.render({
|
|
22914
|
+
items: group.items.map(({ item }) => item),
|
|
22915
|
+
keys: group.items.map(({ key }) => key),
|
|
22916
|
+
layout: config.layout,
|
|
22917
|
+
scrollOwner: resolveScrollOwner(),
|
|
22918
|
+
renderItem: (item, localIndex, layout) => {
|
|
22919
|
+
const entry = group.items[localIndex];
|
|
22920
|
+
return entry ? renderEntry(entry, layout) : null;
|
|
22921
|
+
}
|
|
22922
|
+
});
|
|
22923
|
+
}
|
|
22924
|
+
if (mode === "masonry" || mode === "dense") {
|
|
22925
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
22926
|
+
WorkbenchMasonryLayout,
|
|
22358
22927
|
{
|
|
22359
|
-
|
|
22360
|
-
|
|
22361
|
-
|
|
22362
|
-
|
|
22928
|
+
items: group.items,
|
|
22929
|
+
columnCount,
|
|
22930
|
+
columnWidth: config.layout.cardWidth ?? config.layout.columnWidth ?? config.layout.idealCardWidth,
|
|
22931
|
+
gap,
|
|
22932
|
+
rowHeight,
|
|
22933
|
+
placementStrategy: mode === "dense" ? "dense" : placementStrategy,
|
|
22934
|
+
className: classNames?.layout,
|
|
22935
|
+
containerProps: {
|
|
22936
|
+
role: selectionMode === "none" ? "list" : "listbox",
|
|
22937
|
+
"aria-label": ariaLabel ?? labels.collection,
|
|
22938
|
+
"aria-multiselectable": selectionMode === "multiple" || void 0
|
|
22363
22939
|
},
|
|
22364
|
-
|
|
22365
|
-
|
|
22366
|
-
|
|
22367
|
-
|
|
22368
|
-
|
|
22369
|
-
|
|
22370
|
-
|
|
22371
|
-
|
|
22372
|
-
|
|
22373
|
-
|
|
22374
|
-
|
|
22940
|
+
getItemProps: (entry, masonryLayout) => {
|
|
22941
|
+
const context = createItemContext(entry, { ...masonryLayout, mode });
|
|
22942
|
+
return getItemInteractionProps(entry, context);
|
|
22943
|
+
},
|
|
22944
|
+
getItemKey: (entry) => entry.key,
|
|
22945
|
+
getItemSize: (entry, masonryLayout) => {
|
|
22946
|
+
const layout = {
|
|
22947
|
+
...masonryLayout,
|
|
22948
|
+
mode
|
|
22949
|
+
};
|
|
22950
|
+
const customSize = config.layout.getItemSize?.(entry.item, layout);
|
|
22951
|
+
const aspectRatio = config.layout.getItemAspectRatio?.(entry.item, entry.index);
|
|
22952
|
+
return normalizeItemSize(customSize, aspectRatio, masonryLayout.columnWidth);
|
|
22953
|
+
},
|
|
22954
|
+
renderItem: (entry, masonryLayout) => renderEntry(entry, {
|
|
22955
|
+
...masonryLayout,
|
|
22956
|
+
mode
|
|
22957
|
+
}, false)
|
|
22958
|
+
}
|
|
22959
|
+
);
|
|
22960
|
+
}
|
|
22961
|
+
if (mode === "rail") {
|
|
22962
|
+
const cardWidth = config.layout.cardWidth ?? config.layout.idealCardWidth ?? DEFAULT_CARD_WIDTH_PX;
|
|
22963
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
22964
|
+
"div",
|
|
22965
|
+
{
|
|
22966
|
+
role: selectionMode === "none" ? "list" : "listbox",
|
|
22967
|
+
"aria-label": ariaLabel ?? labels.collection,
|
|
22968
|
+
"aria-multiselectable": selectionMode === "multiple" || void 0,
|
|
22969
|
+
className: cn("grid min-w-0 grid-flow-col items-start overflow-x-auto", classNames?.layout),
|
|
22970
|
+
style: { gap, gridAutoColumns: typeof cardWidth === "number" ? `${cardWidth}px` : cardWidth },
|
|
22971
|
+
children: group.items.map((entry) => /* @__PURE__ */ jsxRuntime.jsx(React2.Fragment, { children: renderEntry(entry, baseLayoutContext) }, entry.stringKey))
|
|
22972
|
+
}
|
|
22973
|
+
);
|
|
22974
|
+
}
|
|
22975
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
22976
|
+
"div",
|
|
22977
|
+
{
|
|
22978
|
+
role: selectionMode === "none" ? "list" : "listbox",
|
|
22979
|
+
"aria-label": ariaLabel ?? labels.collection,
|
|
22980
|
+
"aria-multiselectable": selectionMode === "multiple" || void 0,
|
|
22981
|
+
className: cn("grid min-w-0 items-start", classNames?.layout),
|
|
22982
|
+
style: {
|
|
22983
|
+
gap,
|
|
22984
|
+
gridTemplateColumns: `repeat(${columnCount}, minmax(0, 1fr))`
|
|
22375
22985
|
},
|
|
22376
|
-
|
|
22377
|
-
|
|
22986
|
+
children: group.items.map((entry) => {
|
|
22987
|
+
const customSize = config.layout.getItemSize?.(entry.item, baseLayoutContext);
|
|
22988
|
+
const span = clamp4(Math.round(Number(customSize?.columnSpan) || 1), 1, columnCount);
|
|
22989
|
+
const aspectRatio = config.layout.getItemAspectRatio?.(entry.item, entry.index);
|
|
22990
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
22991
|
+
"div",
|
|
22992
|
+
{
|
|
22993
|
+
...getItemInteractionProps(
|
|
22994
|
+
entry,
|
|
22995
|
+
createItemContext(entry, { ...baseLayoutContext, columnSpan: span, size: customSize })
|
|
22996
|
+
),
|
|
22997
|
+
style: {
|
|
22998
|
+
gridColumn: span > 1 ? `span ${span}` : void 0,
|
|
22999
|
+
aspectRatio: Number.isFinite(aspectRatio) && Number(aspectRatio) > 0 ? String(aspectRatio) : void 0
|
|
23000
|
+
},
|
|
23001
|
+
children: renderEntry(entry, { ...baseLayoutContext, columnSpan: span, size: customSize }, false)
|
|
23002
|
+
},
|
|
23003
|
+
entry.stringKey
|
|
23004
|
+
);
|
|
23005
|
+
})
|
|
23006
|
+
}
|
|
23007
|
+
);
|
|
23008
|
+
};
|
|
23009
|
+
const slotContext = {
|
|
23010
|
+
items,
|
|
23011
|
+
error: effectiveError,
|
|
23012
|
+
loading,
|
|
23013
|
+
loadingMore,
|
|
23014
|
+
selectedKeys,
|
|
23015
|
+
retry: () => callbacks?.onRetry?.()
|
|
23016
|
+
};
|
|
23017
|
+
const header = resolveRenderableSlot(slots?.header, slotContext);
|
|
23018
|
+
const toolbar = resolveRenderableSlot(slots?.toolbar, slotContext);
|
|
23019
|
+
const selectionToolbar = selectedKeys.size > 0 ? resolveRenderableSlot(slots?.selectionToolbar, slotContext) : null;
|
|
23020
|
+
const beforeItems = resolveRenderableSlot(slots?.beforeItems, slotContext);
|
|
23021
|
+
const footer = resolveRenderableSlot(slots?.footer, slotContext);
|
|
23022
|
+
const showInitialLoading = loading && items.length === 0;
|
|
23023
|
+
const showInitialError = Boolean(effectiveError) && items.length === 0 && !showInitialLoading;
|
|
23024
|
+
const showEmpty = !showInitialLoading && !showInitialError && (state?.empty === true || items.length === 0);
|
|
23025
|
+
const loadingSlot = resolveRenderableSlot(slots?.loading, slotContext);
|
|
23026
|
+
const errorSlot = resolveRenderableSlot(slots?.error, slotContext);
|
|
23027
|
+
const emptySlot = resolveRenderableSlot(slots?.empty, slotContext);
|
|
23028
|
+
const loadMoreSlot = resolveRenderableSlot(slots?.loadMore, slotContext);
|
|
23029
|
+
const selfScrollable = config.layout.scrollOwner === "self" || config.layout.scrollOwner === void 0 && (config.layout.fillHeight || config.layout.maxHeight);
|
|
23030
|
+
const rootStyle = {
|
|
23031
|
+
...style,
|
|
23032
|
+
padding: config.layout.padding ?? style?.padding,
|
|
23033
|
+
height: config.layout.fillHeight ? "100%" : style?.height,
|
|
23034
|
+
maxHeight: config.layout.maxHeight ?? style?.maxHeight,
|
|
23035
|
+
overflow: selfScrollable ? "auto" : style?.overflow
|
|
23036
|
+
};
|
|
23037
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
23038
|
+
"section",
|
|
23039
|
+
{
|
|
23040
|
+
ref: rootRef,
|
|
23041
|
+
...componentAttributes,
|
|
23042
|
+
"data-monkeys-component": "workbench-collection",
|
|
23043
|
+
"data-layout-mode": mode,
|
|
23044
|
+
"data-density": config.appearance?.density,
|
|
23045
|
+
"data-radius": config.appearance?.radius,
|
|
23046
|
+
"data-media-fit": config.appearance?.mediaFit,
|
|
23047
|
+
"aria-label": ariaLabel ?? labels.collection,
|
|
23048
|
+
"aria-busy": loading || loadingMore || void 0,
|
|
23049
|
+
className: cn("min-h-0 min-w-0", config.layout.fillHeight && "h-full", classNames?.root, className),
|
|
23050
|
+
style: rootStyle,
|
|
23051
|
+
children: [
|
|
23052
|
+
hasRenderableNode(header) ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: classNames?.header, children: header }) : null,
|
|
23053
|
+
hasRenderableNode(toolbar) ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: classNames?.toolbar, children: toolbar }) : null,
|
|
23054
|
+
hasRenderableNode(selectionToolbar) ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: classNames?.selectionToolbar, children: selectionToolbar }) : null,
|
|
23055
|
+
hasRenderableNode(beforeItems) ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: classNames?.beforeItems, children: beforeItems }) : null,
|
|
23056
|
+
showInitialLoading ? hasRenderableNode(loadingSlot) ? loadingSlot : /* @__PURE__ */ jsxRuntime.jsx(BaseLoadingState, { title: labels.loading }) : showInitialError ? hasRenderableNode(errorSlot) ? errorSlot : /* @__PURE__ */ jsxRuntime.jsx(
|
|
23057
|
+
BaseNotice,
|
|
23058
|
+
{
|
|
23059
|
+
tone: "danger",
|
|
23060
|
+
role: "alert",
|
|
23061
|
+
"aria-live": "assertive",
|
|
23062
|
+
title: labels.loadError,
|
|
23063
|
+
actions: callbacks?.onRetry ? /* @__PURE__ */ jsxRuntime.jsx(BaseButton, { size: "sm", label: labels.retry, onClick: callbacks.onRetry }) : void 0
|
|
23064
|
+
}
|
|
23065
|
+
) : showEmpty ? hasRenderableNode(emptySlot) ? emptySlot : /* @__PURE__ */ jsxRuntime.jsx(BaseEmptyState, { title: labels.empty }) : /* @__PURE__ */ jsxRuntime.jsx(
|
|
23066
|
+
"div",
|
|
23067
|
+
{
|
|
23068
|
+
ref: registerItemsNode,
|
|
23069
|
+
className: cn("min-w-0", classNames?.items),
|
|
23070
|
+
children: groups.map((group, groupIndex) => {
|
|
23071
|
+
const groupContext = {
|
|
23072
|
+
key: group.key,
|
|
23073
|
+
label: group.label,
|
|
23074
|
+
items: group.items.map(({ item }) => item),
|
|
23075
|
+
groupIndex
|
|
23076
|
+
};
|
|
23077
|
+
const heading = config.grouping ? slots?.groupHeading?.(groupContext, slotContext) ?? group.label : null;
|
|
23078
|
+
const headingId = `${componentId}-group-${groupIndex}`;
|
|
23079
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
23080
|
+
"div",
|
|
23081
|
+
{
|
|
23082
|
+
"data-collection-group": group.stringKey,
|
|
23083
|
+
className: classNames?.group,
|
|
23084
|
+
children: [
|
|
23085
|
+
hasRenderableNode(heading) ? /* @__PURE__ */ jsxRuntime.jsx("div", { id: headingId, role: "heading", "aria-level": 2, className: classNames?.groupHeading, children: heading }) : null,
|
|
23086
|
+
renderGroupItems(group)
|
|
23087
|
+
]
|
|
23088
|
+
},
|
|
23089
|
+
group.stringKey
|
|
23090
|
+
);
|
|
23091
|
+
})
|
|
23092
|
+
}
|
|
23093
|
+
),
|
|
23094
|
+
items.length > 0 && effectiveError ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: classNames?.status, children: hasRenderableNode(errorSlot) ? errorSlot : /* @__PURE__ */ jsxRuntime.jsx(
|
|
23095
|
+
BaseNotice,
|
|
23096
|
+
{
|
|
23097
|
+
tone: "danger",
|
|
23098
|
+
role: "alert",
|
|
23099
|
+
title: labels.refreshError,
|
|
23100
|
+
actions: callbacks?.onRetry ? /* @__PURE__ */ jsxRuntime.jsx(BaseButton, { size: "sm", label: labels.retry, onClick: callbacks.onRetry }) : void 0
|
|
23101
|
+
}
|
|
23102
|
+
) }) : null,
|
|
23103
|
+
items.length > 0 && (hasMore || loadingMore) ? /* @__PURE__ */ jsxRuntime.jsx("div", { ref: loadMoreRef, className: classNames?.loadMore, "data-collection-load-more": "", children: hasRenderableNode(loadMoreSlot) ? loadMoreSlot : loadingMore ? /* @__PURE__ */ jsxRuntime.jsx(BaseLoadingState, { title: labels.loadingMore }) : null }) : null,
|
|
23104
|
+
hasRenderableNode(footer) ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: classNames?.footer, children: footer }) : null
|
|
23105
|
+
]
|
|
22378
23106
|
}
|
|
22379
23107
|
);
|
|
22380
23108
|
}
|
|
@@ -22815,45 +23543,54 @@ function WorkbenchGalleryView({
|
|
|
22815
23543
|
);
|
|
22816
23544
|
if (isMasonry) {
|
|
22817
23545
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
22818
|
-
|
|
23546
|
+
WorkbenchCollection,
|
|
22819
23547
|
{
|
|
22820
23548
|
items: rows,
|
|
22821
|
-
className,
|
|
22822
|
-
|
|
22823
|
-
|
|
22824
|
-
|
|
22825
|
-
|
|
22826
|
-
|
|
22827
|
-
|
|
22828
|
-
|
|
22829
|
-
|
|
22830
|
-
|
|
22831
|
-
|
|
22832
|
-
|
|
22833
|
-
|
|
22834
|
-
|
|
22835
|
-
|
|
22836
|
-
|
|
22837
|
-
|
|
22838
|
-
|
|
22839
|
-
|
|
22840
|
-
|
|
22841
|
-
|
|
22842
|
-
|
|
22843
|
-
|
|
22844
|
-
|
|
22845
|
-
|
|
22846
|
-
|
|
22847
|
-
|
|
22848
|
-
|
|
22849
|
-
|
|
22850
|
-
|
|
22851
|
-
|
|
22852
|
-
|
|
22853
|
-
|
|
22854
|
-
|
|
23549
|
+
classNames: { layout: className },
|
|
23550
|
+
config: {
|
|
23551
|
+
getItemKey: (row, rowIndex) => row?.id || row?.linkKey || rowIndex,
|
|
23552
|
+
layout: {
|
|
23553
|
+
mode: masonryPlacementStrategy === "dense" ? "dense" : "masonry",
|
|
23554
|
+
gap: GALLERY_GRID_GAP_PX,
|
|
23555
|
+
idealCardWidth: resolvedMasonryColumnWidth,
|
|
23556
|
+
placementStrategy: masonryPlacementStrategy,
|
|
23557
|
+
getItemSize: (row, layout) => {
|
|
23558
|
+
const defaultSize = getDefaultGalleryMasonryItemSize({
|
|
23559
|
+
row,
|
|
23560
|
+
columns,
|
|
23561
|
+
galleryFieldKey,
|
|
23562
|
+
galleryDensity,
|
|
23563
|
+
galleryBentoColumns,
|
|
23564
|
+
galleryDetailVisibility,
|
|
23565
|
+
galleryDetailLimit,
|
|
23566
|
+
getFieldValue: resolvedGetFieldValue,
|
|
23567
|
+
isMediaColumn: resolvedIsMediaColumn,
|
|
23568
|
+
isTitleCandidate: resolvedIsTitleCandidate,
|
|
23569
|
+
isSummaryCandidate: resolvedIsSummaryCandidate,
|
|
23570
|
+
getDisplayText: resolvedGetDisplayText,
|
|
23571
|
+
isImageField: resolvedIsImageField,
|
|
23572
|
+
isAudioField: resolvedIsAudioField,
|
|
23573
|
+
cardVariant,
|
|
23574
|
+
renderPreview,
|
|
23575
|
+
renderLeadingVisual,
|
|
23576
|
+
hiddenDetailFieldKeys,
|
|
23577
|
+
layout,
|
|
23578
|
+
resolveRecordVisual
|
|
23579
|
+
});
|
|
23580
|
+
if (typeof getMasonryItemSize !== "function") return defaultSize;
|
|
23581
|
+
const customSize = getMasonryItemSize(row, {
|
|
23582
|
+
...layout,
|
|
23583
|
+
placementStrategy: layout.placementStrategy === "dense" ? "dense" : "shelf",
|
|
23584
|
+
defaultSize
|
|
23585
|
+
}) || {};
|
|
23586
|
+
return {
|
|
23587
|
+
...defaultSize,
|
|
23588
|
+
...customSize
|
|
23589
|
+
};
|
|
23590
|
+
}
|
|
23591
|
+
}
|
|
22855
23592
|
},
|
|
22856
|
-
renderItem: (row) => renderGalleryCard(row,
|
|
23593
|
+
renderItem: (row, context) => renderGalleryCard(row, context.index)
|
|
22857
23594
|
}
|
|
22858
23595
|
);
|
|
22859
23596
|
}
|
|
@@ -23371,7 +24108,7 @@ var getDomain = (values, min5, max5) => {
|
|
|
23371
24108
|
return lower < upper ? [lower, upper] : [upper, lower];
|
|
23372
24109
|
};
|
|
23373
24110
|
var scale = (value, domain, start, end) => start + (value - domain[0]) / (domain[1] - domain[0]) * (end - start);
|
|
23374
|
-
var
|
|
24111
|
+
var clamp5 = (value, min5, max5) => Math.min(max5, Math.max(min5, value));
|
|
23375
24112
|
var activatePoint = (event, point, onPointSelect) => {
|
|
23376
24113
|
if (!onPointSelect || event.key !== "Enter" && event.key !== " ") return;
|
|
23377
24114
|
event.preventDefault();
|
|
@@ -23453,9 +24190,9 @@ function WorkbenchScatterPlot({
|
|
|
23453
24190
|
xThreshold === void 0 ? null : /* @__PURE__ */ jsxRuntime.jsx(
|
|
23454
24191
|
"line",
|
|
23455
24192
|
{
|
|
23456
|
-
x1:
|
|
24193
|
+
x1: clamp5(xThreshold, plotLeft, plotRight),
|
|
23457
24194
|
y1: plotTop,
|
|
23458
|
-
x2:
|
|
24195
|
+
x2: clamp5(xThreshold, plotLeft, plotRight),
|
|
23459
24196
|
y2: plotBottom,
|
|
23460
24197
|
className: "stroke-muted-foreground/50",
|
|
23461
24198
|
strokeDasharray: "5 5"
|
|
@@ -23465,9 +24202,9 @@ function WorkbenchScatterPlot({
|
|
|
23465
24202
|
"line",
|
|
23466
24203
|
{
|
|
23467
24204
|
x1: plotLeft,
|
|
23468
|
-
y1:
|
|
24205
|
+
y1: clamp5(yThreshold, plotTop, plotBottom),
|
|
23469
24206
|
x2: plotRight,
|
|
23470
|
-
y2:
|
|
24207
|
+
y2: clamp5(yThreshold, plotTop, plotBottom),
|
|
23471
24208
|
className: "stroke-muted-foreground/50",
|
|
23472
24209
|
strokeDasharray: "5 5"
|
|
23473
24210
|
}
|
|
@@ -23494,17 +24231,17 @@ function WorkbenchScatterPlot({
|
|
|
23494
24231
|
}
|
|
23495
24232
|
),
|
|
23496
24233
|
validPoints.map((point) => {
|
|
23497
|
-
const x =
|
|
24234
|
+
const x = clamp5(
|
|
23498
24235
|
scale(point.x, xDomain, plotLeft, plotRight),
|
|
23499
24236
|
plotLeft,
|
|
23500
24237
|
plotRight
|
|
23501
24238
|
);
|
|
23502
|
-
const y =
|
|
24239
|
+
const y = clamp5(
|
|
23503
24240
|
scale(point.y, yDomain, plotBottom, plotTop),
|
|
23504
24241
|
plotTop,
|
|
23505
24242
|
plotBottom
|
|
23506
24243
|
);
|
|
23507
|
-
const radius = point.size === void 0 ? 9 :
|
|
24244
|
+
const radius = point.size === void 0 ? 9 : clamp5(scale(point.size, sizeDomain, 7, 18), 7, 18);
|
|
23508
24245
|
const selected = selectedPointId === point.id;
|
|
23509
24246
|
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
23510
24247
|
"g",
|
|
@@ -24036,7 +24773,7 @@ var getDomain2 = (values, min5, max5) => {
|
|
|
24036
24773
|
return lower < upper ? [lower, upper] : [upper, lower];
|
|
24037
24774
|
};
|
|
24038
24775
|
var scale2 = (value, domain, start, end) => start + (value - domain[0]) / (domain[1] - domain[0]) * (end - start);
|
|
24039
|
-
var
|
|
24776
|
+
var clamp6 = (value, min5, max5) => Math.min(max5, Math.max(min5, value));
|
|
24040
24777
|
var toneVariable = {
|
|
24041
24778
|
primary: "--radar-series-one",
|
|
24042
24779
|
secondary: "--radar-series-two",
|
|
@@ -24099,7 +24836,7 @@ function WorkbenchRadarMatrix({
|
|
|
24099
24836
|
const plotRight = width;
|
|
24100
24837
|
const plotTop = 0;
|
|
24101
24838
|
const plotBottom = height;
|
|
24102
|
-
const xThreshold =
|
|
24839
|
+
const xThreshold = clamp6(
|
|
24103
24840
|
scale2(
|
|
24104
24841
|
Number.isFinite(thresholds?.x) ? Number(thresholds?.x) : (xDomain[0] + xDomain[1]) / 2,
|
|
24105
24842
|
xDomain,
|
|
@@ -24109,7 +24846,7 @@ function WorkbenchRadarMatrix({
|
|
|
24109
24846
|
plotLeft,
|
|
24110
24847
|
plotRight
|
|
24111
24848
|
);
|
|
24112
|
-
const yThreshold =
|
|
24849
|
+
const yThreshold = clamp6(
|
|
24113
24850
|
scale2(
|
|
24114
24851
|
Number.isFinite(thresholds?.y) ? Number(thresholds?.y) : (yDomain[0] + yDomain[1]) / 2,
|
|
24115
24852
|
yDomain,
|
|
@@ -24217,13 +24954,13 @@ function WorkbenchRadarMatrix({
|
|
|
24217
24954
|
] }, quadrant.id);
|
|
24218
24955
|
}),
|
|
24219
24956
|
validPoints.map((point, index) => {
|
|
24220
|
-
const x =
|
|
24221
|
-
const y =
|
|
24957
|
+
const x = clamp6(scale2(point.x, xDomain, 40, width - 40), 40, width - 40);
|
|
24958
|
+
const y = clamp6(scale2(point.y, yDomain, height - 48, 54), 54, height - 48);
|
|
24222
24959
|
const tone = point.tone || (index % 2 === 0 ? "primary" : "accent");
|
|
24223
24960
|
const selected = selectedPointId === point.id;
|
|
24224
24961
|
const labelled = labelledPointIds.has(point.id);
|
|
24225
|
-
const radius = labelled ?
|
|
24226
|
-
const fontSize = labelled ?
|
|
24962
|
+
const radius = labelled ? clamp6(scale2(point.size ?? 1, sizeDomain, 5, 9), 5, 9) : 3.5;
|
|
24963
|
+
const fontSize = labelled ? clamp6(scale2(point.size ?? 1, sizeDomain, 14, 31), 14, 31) : 0;
|
|
24227
24964
|
const pointStyle = {
|
|
24228
24965
|
fill: toneColor(tone),
|
|
24229
24966
|
stroke: "hsl(var(--foreground) / 0.74)"
|
|
@@ -24325,8 +25062,8 @@ function WorkbenchRadarMatrix({
|
|
|
24325
25062
|
validPoints.map((point, index) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
24326
25063
|
"circle",
|
|
24327
25064
|
{
|
|
24328
|
-
cx:
|
|
24329
|
-
cy:
|
|
25065
|
+
cx: clamp6(scale2(point.x, xDomain, 40, width - 40), 40, width - 40),
|
|
25066
|
+
cy: clamp6(scale2(point.y, yDomain, height - 48, 54), 54, height - 48),
|
|
24330
25067
|
r: "8",
|
|
24331
25068
|
style: { fill: toneColor(point.tone || (index % 2 === 0 ? "primary" : "accent")) }
|
|
24332
25069
|
},
|
|
@@ -27811,7 +28548,7 @@ var DEFAULT_ZOOM_STEP = 1.18;
|
|
|
27811
28548
|
var DEFAULT_STAGE_PADDING = 16;
|
|
27812
28549
|
var MAX_SAFE_SCALE = 1e6;
|
|
27813
28550
|
var MIN_SAFE_SCALE = 1e-6;
|
|
27814
|
-
var
|
|
28551
|
+
var clamp7 = (value, min5, max5) => Math.min(max5, Math.max(min5, value));
|
|
27815
28552
|
var isNoDragTarget = (target) => target instanceof Element && Boolean(target.closest('[data-no-drag="true"]'));
|
|
27816
28553
|
function ResetIcon() {
|
|
27817
28554
|
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
@@ -27935,7 +28672,7 @@ function DataExplorerImagePreview({
|
|
|
27935
28672
|
availableWidth / size.width,
|
|
27936
28673
|
availableHeight / size.height
|
|
27937
28674
|
);
|
|
27938
|
-
const nextScale =
|
|
28675
|
+
const nextScale = clamp7(
|
|
27939
28676
|
fitScale,
|
|
27940
28677
|
normalizedMinScale,
|
|
27941
28678
|
normalizedMaxScale
|
|
@@ -27989,7 +28726,7 @@ function DataExplorerImagePreview({
|
|
|
27989
28726
|
if (!Number.isFinite(factor) || factor === 1) return;
|
|
27990
28727
|
if (!Number.isFinite(stageX) || !Number.isFinite(stageY)) return;
|
|
27991
28728
|
setView((current) => {
|
|
27992
|
-
const nextScale =
|
|
28729
|
+
const nextScale = clamp7(
|
|
27993
28730
|
current.scale * factor,
|
|
27994
28731
|
normalizedMinScale,
|
|
27995
28732
|
normalizedMaxScale
|
|
@@ -29961,6 +30698,7 @@ exports.ToastProvider = MonkeysToastProvider;
|
|
|
29961
30698
|
exports.Toaster = MonkeysToaster;
|
|
29962
30699
|
exports.UserAccountMenu = UserAccountMenu;
|
|
29963
30700
|
exports.WorkbenchAssetGallery = WorkbenchAssetGallery;
|
|
30701
|
+
exports.WorkbenchCollection = WorkbenchCollection;
|
|
29964
30702
|
exports.WorkbenchContentPane = WorkbenchContentPane;
|
|
29965
30703
|
exports.WorkbenchContentToolbar = WorkbenchContentToolbar;
|
|
29966
30704
|
exports.WorkbenchDetailSidebar = WorkbenchDetailSidebar;
|