@inf-monkeys-tech/monkeys-design 0.4.31 → 0.4.33
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +6 -0
- package/dist/components/base/index.d.mts +2 -2
- package/dist/components/base/index.d.ts +2 -2
- package/dist/components/base/index.js +545 -26
- package/dist/components/base/index.js.map +1 -1
- package/dist/components/base/index.mjs +543 -28
- package/dist/components/base/index.mjs.map +1 -1
- package/dist/components/workbench/index.d.mts +752 -0
- package/dist/components/workbench/index.d.ts +752 -0
- package/dist/components/workbench/index.js +6650 -0
- package/dist/components/workbench/index.js.map +1 -0
- package/dist/components/workbench/index.mjs +6614 -0
- package/dist/components/workbench/index.mjs.map +1 -0
- package/dist/index.d.mts +3 -2
- package/dist/index.d.ts +3 -2
- package/dist/index.js +4197 -31
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +4180 -33
- package/dist/index.mjs.map +1 -1
- package/dist/{theme-CvbotXXr.d.ts → theme-CoG9vCPT.d.mts} +8 -3
- package/dist/{theme-6RDum855.d.mts → theme-Cuy60thu.d.ts} +8 -3
- package/dist/theme-system/index.d.mts +1 -1
- package/dist/theme-system/index.d.ts +1 -1
- package/dist/theme-system/index.js +398 -16
- package/dist/theme-system/index.js.map +1 -1
- package/dist/theme-system/index.mjs +399 -17
- package/dist/theme-system/index.mjs.map +1 -1
- package/dist/{types-BgEEUqSm.d.mts → types-CZALgtez.d.mts} +121 -1
- package/dist/{types-BgEEUqSm.d.ts → types-CZALgtez.d.ts} +121 -1
- package/package.json +7 -1
package/dist/index.js
CHANGED
|
@@ -4,6 +4,7 @@ var React = require('react');
|
|
|
4
4
|
var jsxRuntime = require('react/jsx-runtime');
|
|
5
5
|
var ContextMenu = require('@radix-ui/react-context-menu');
|
|
6
6
|
var DropdownMenu3 = require('@radix-ui/react-dropdown-menu');
|
|
7
|
+
var core = require('@dnd-kit/core');
|
|
7
8
|
var Tooltip = require('@radix-ui/react-tooltip');
|
|
8
9
|
|
|
9
10
|
function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
|
|
@@ -4548,7 +4549,7 @@ var require_lodash = __commonJS({
|
|
|
4548
4549
|
function valuesIn(object) {
|
|
4549
4550
|
return object == null ? [] : baseValues(object, keysIn(object));
|
|
4550
4551
|
}
|
|
4551
|
-
function
|
|
4552
|
+
function clamp5(number, lower, upper) {
|
|
4552
4553
|
if (upper === undefined2) {
|
|
4553
4554
|
upper = lower;
|
|
4554
4555
|
lower = undefined2;
|
|
@@ -5225,7 +5226,7 @@ var require_lodash = __commonJS({
|
|
|
5225
5226
|
lodash.camelCase = camelCase;
|
|
5226
5227
|
lodash.capitalize = capitalize;
|
|
5227
5228
|
lodash.ceil = ceil;
|
|
5228
|
-
lodash.clamp =
|
|
5229
|
+
lodash.clamp = clamp5;
|
|
5229
5230
|
lodash.clone = clone;
|
|
5230
5231
|
lodash.cloneDeep = cloneDeep;
|
|
5231
5232
|
lodash.cloneDeepWith = cloneDeepWith;
|
|
@@ -8580,7 +8581,41 @@ var baseSlots = {
|
|
|
8580
8581
|
tableEmptyActions: "mt-4 flex flex-wrap items-center justify-center gap-2",
|
|
8581
8582
|
tableLoadingRow: "border-b border-border/60",
|
|
8582
8583
|
tableLoadingCell: "px-3 py-2",
|
|
8583
|
-
tableLoadingSkeleton: "h-4 w-full rounded-md bg-muted/70"
|
|
8584
|
+
tableLoadingSkeleton: "h-4 w-full rounded-md bg-muted/70",
|
|
8585
|
+
layoutRoot: cn(
|
|
8586
|
+
"grid min-w-0 overflow-hidden grid-rows-[auto_minmax(0,1fr)_auto] gap-3 rounded-lg border border-border/70 bg-background p-3 text-foreground",
|
|
8587
|
+
motionBase
|
|
8588
|
+
),
|
|
8589
|
+
layoutRootFull: "h-full min-h-0",
|
|
8590
|
+
layoutHeader: "min-w-0",
|
|
8591
|
+
layoutBody: "grid min-h-0 min-w-0 overflow-hidden gap-3",
|
|
8592
|
+
layoutSidebar: "min-h-0 min-w-0 overflow-hidden",
|
|
8593
|
+
layoutMain: "min-h-0 min-w-0 overflow-hidden",
|
|
8594
|
+
layoutAside: "min-h-0 min-w-0 overflow-hidden",
|
|
8595
|
+
layoutFooter: "min-w-0",
|
|
8596
|
+
layoutPane: cn(
|
|
8597
|
+
"h-full max-h-full min-h-0 min-w-0 overflow-hidden rounded-lg bg-background text-foreground",
|
|
8598
|
+
motionBase
|
|
8599
|
+
),
|
|
8600
|
+
layoutPaneScrollable: "overflow-auto",
|
|
8601
|
+
layoutPaneBordered: "border border-border/70",
|
|
8602
|
+
layoutPaneMuted: "bg-muted/25",
|
|
8603
|
+
layoutPaneSoft: "bg-background/95 shadow-sm",
|
|
8604
|
+
layoutPaneTransparent: "bg-transparent shadow-none",
|
|
8605
|
+
layoutSplitRoot: "grid min-h-0 min-w-0 overflow-hidden",
|
|
8606
|
+
layoutSplitHorizontal: "grid-flow-col",
|
|
8607
|
+
layoutSplitVertical: "grid-flow-row",
|
|
8608
|
+
layoutSplitPane: "min-h-0 min-w-0 overflow-hidden",
|
|
8609
|
+
layoutSplitPrimary: "",
|
|
8610
|
+
layoutSplitSecondary: "",
|
|
8611
|
+
layoutResizeHandle: cn(
|
|
8612
|
+
"group/resize relative z-10 flex shrink-0 items-center justify-center bg-transparent text-muted-foreground hover:bg-border/60 active:bg-border/70 focus-visible:bg-border/60 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary/30",
|
|
8613
|
+
motionInteractive
|
|
8614
|
+
),
|
|
8615
|
+
layoutResizeHandleHorizontal: "w-2 cursor-col-resize",
|
|
8616
|
+
layoutResizeHandleVertical: "h-2 cursor-row-resize",
|
|
8617
|
+
layoutResizeHandleDisabled: "cursor-default opacity-60",
|
|
8618
|
+
layoutResizeHandleIndicator: "rounded-full bg-muted-foreground/45 group-hover/resize:bg-primary/70"
|
|
8584
8619
|
};
|
|
8585
8620
|
var densitySlots = {
|
|
8586
8621
|
compact: {
|
|
@@ -8654,7 +8689,12 @@ var densitySlots = {
|
|
|
8654
8689
|
tableCell: "px-2 py-1.5 text-xs",
|
|
8655
8690
|
tableHeadLabel: "text-[11px]",
|
|
8656
8691
|
tableHeadDescription: "text-[10px] leading-3",
|
|
8657
|
-
tableLoadingCell: "px-2 py-1.5"
|
|
8692
|
+
tableLoadingCell: "px-2 py-1.5",
|
|
8693
|
+
layoutRoot: "gap-2 p-2",
|
|
8694
|
+
layoutBody: "gap-2",
|
|
8695
|
+
layoutPane: "rounded-md text-xs",
|
|
8696
|
+
layoutResizeHandleHorizontal: "w-1.5",
|
|
8697
|
+
layoutResizeHandleVertical: "h-1.5"
|
|
8658
8698
|
},
|
|
8659
8699
|
default: {
|
|
8660
8700
|
buttonBase: "h-9"
|
|
@@ -8705,7 +8745,12 @@ var densitySlots = {
|
|
|
8705
8745
|
menuSubTrigger: "min-h-9 px-3 py-2",
|
|
8706
8746
|
tableHead: "h-12 px-4 py-3",
|
|
8707
8747
|
tableCell: "px-4 py-3",
|
|
8708
|
-
tableLoadingCell: "px-4 py-3"
|
|
8748
|
+
tableLoadingCell: "px-4 py-3",
|
|
8749
|
+
layoutRoot: "gap-4 p-4",
|
|
8750
|
+
layoutBody: "gap-4",
|
|
8751
|
+
layoutPane: "rounded-xl",
|
|
8752
|
+
layoutResizeHandleHorizontal: "w-2.5",
|
|
8753
|
+
layoutResizeHandleVertical: "h-2.5"
|
|
8709
8754
|
}
|
|
8710
8755
|
};
|
|
8711
8756
|
var radiusSlots = {
|
|
@@ -8749,7 +8794,9 @@ var radiusSlots = {
|
|
|
8749
8794
|
menuSubContent: "rounded-none",
|
|
8750
8795
|
tableContainer: "rounded-none",
|
|
8751
8796
|
tableEmptyIcon: "rounded-none",
|
|
8752
|
-
tableLoadingSkeleton: "rounded-none"
|
|
8797
|
+
tableLoadingSkeleton: "rounded-none",
|
|
8798
|
+
layoutRoot: "rounded-none",
|
|
8799
|
+
layoutPane: "rounded-none"
|
|
8753
8800
|
},
|
|
8754
8801
|
sm: {
|
|
8755
8802
|
buttonBase: "rounded-sm",
|
|
@@ -8791,7 +8838,9 @@ var radiusSlots = {
|
|
|
8791
8838
|
menuSubContent: "rounded-sm",
|
|
8792
8839
|
tableContainer: "rounded-sm",
|
|
8793
8840
|
tableEmptyIcon: "rounded-sm",
|
|
8794
|
-
tableLoadingSkeleton: "rounded-sm"
|
|
8841
|
+
tableLoadingSkeleton: "rounded-sm",
|
|
8842
|
+
layoutRoot: "rounded-sm",
|
|
8843
|
+
layoutPane: "rounded-sm"
|
|
8795
8844
|
},
|
|
8796
8845
|
md: {},
|
|
8797
8846
|
lg: {
|
|
@@ -8828,7 +8877,9 @@ var radiusSlots = {
|
|
|
8828
8877
|
menuSubContent: "rounded-lg",
|
|
8829
8878
|
tableContainer: "rounded-xl",
|
|
8830
8879
|
tableEmptyIcon: "rounded-xl",
|
|
8831
|
-
tableLoadingSkeleton: "rounded-lg"
|
|
8880
|
+
tableLoadingSkeleton: "rounded-lg",
|
|
8881
|
+
layoutRoot: "rounded-xl",
|
|
8882
|
+
layoutPane: "rounded-xl"
|
|
8832
8883
|
},
|
|
8833
8884
|
xl: {
|
|
8834
8885
|
buttonBase: "rounded-xl",
|
|
@@ -8866,7 +8917,9 @@ var radiusSlots = {
|
|
|
8866
8917
|
menuSubContent: "rounded-xl",
|
|
8867
8918
|
tableContainer: "rounded-2xl",
|
|
8868
8919
|
tableEmptyIcon: "rounded-2xl",
|
|
8869
|
-
tableLoadingSkeleton: "rounded-xl"
|
|
8920
|
+
tableLoadingSkeleton: "rounded-xl",
|
|
8921
|
+
layoutRoot: "rounded-2xl",
|
|
8922
|
+
layoutPane: "rounded-2xl"
|
|
8870
8923
|
},
|
|
8871
8924
|
full: {
|
|
8872
8925
|
buttonBase: "rounded-full",
|
|
@@ -8908,7 +8961,9 @@ var radiusSlots = {
|
|
|
8908
8961
|
menuSubContent: "rounded-2xl",
|
|
8909
8962
|
tableContainer: "rounded-2xl",
|
|
8910
8963
|
tableEmptyIcon: "rounded-full",
|
|
8911
|
-
tableLoadingSkeleton: "rounded-full"
|
|
8964
|
+
tableLoadingSkeleton: "rounded-full",
|
|
8965
|
+
layoutRoot: "rounded-2xl",
|
|
8966
|
+
layoutPane: "rounded-2xl"
|
|
8912
8967
|
}
|
|
8913
8968
|
};
|
|
8914
8969
|
var borderSlots = {
|
|
@@ -8950,7 +9005,10 @@ var borderSlots = {
|
|
|
8950
9005
|
tableFooterBarAttached: "border-t border-transparent",
|
|
8951
9006
|
tableRow: "border-transparent",
|
|
8952
9007
|
tableEmptyRow: "border-transparent",
|
|
8953
|
-
tableLoadingRow: "border-transparent"
|
|
9008
|
+
tableLoadingRow: "border-transparent",
|
|
9009
|
+
layoutRoot: "border-transparent",
|
|
9010
|
+
layoutPaneBordered: "border-transparent",
|
|
9011
|
+
layoutResizeHandle: "bg-transparent hover:bg-transparent active:bg-transparent focus-visible:bg-transparent"
|
|
8954
9012
|
},
|
|
8955
9013
|
subtle: {
|
|
8956
9014
|
buttonDefault: "border-border/60",
|
|
@@ -8990,7 +9048,9 @@ var borderSlots = {
|
|
|
8990
9048
|
tableFooterBarAttached: "border-t border-border/60",
|
|
8991
9049
|
tableRow: "border-border/50",
|
|
8992
9050
|
tableEmptyRow: "border-border/50",
|
|
8993
|
-
tableLoadingRow: "border-border/50"
|
|
9051
|
+
tableLoadingRow: "border-border/50",
|
|
9052
|
+
layoutRoot: "border-border/60",
|
|
9053
|
+
layoutPaneBordered: "border-border/60"
|
|
8994
9054
|
},
|
|
8995
9055
|
solid: {},
|
|
8996
9056
|
strong: {
|
|
@@ -9031,7 +9091,10 @@ var borderSlots = {
|
|
|
9031
9091
|
tableFooterBarAttached: "border-t border-foreground/20",
|
|
9032
9092
|
tableRow: "border-foreground/15",
|
|
9033
9093
|
tableEmptyRow: "border-foreground/15",
|
|
9034
|
-
tableLoadingRow: "border-foreground/15"
|
|
9094
|
+
tableLoadingRow: "border-foreground/15",
|
|
9095
|
+
layoutRoot: "border-foreground/20",
|
|
9096
|
+
layoutPaneBordered: "border-foreground/20",
|
|
9097
|
+
layoutResizeHandle: "hover:bg-foreground/15 active:bg-foreground/20 focus-visible:bg-foreground/15"
|
|
9035
9098
|
}
|
|
9036
9099
|
};
|
|
9037
9100
|
var backgroundSlots = {
|
|
@@ -9073,7 +9136,11 @@ var backgroundSlots = {
|
|
|
9073
9136
|
tableFooter: "bg-muted/35",
|
|
9074
9137
|
tableFooterBar: "bg-muted/30 shadow-none",
|
|
9075
9138
|
tableRowInteractive: "cursor-pointer hover:bg-muted/45",
|
|
9076
|
-
tableLoadingSkeleton: "bg-muted"
|
|
9139
|
+
tableLoadingSkeleton: "bg-muted",
|
|
9140
|
+
layoutRoot: "bg-card",
|
|
9141
|
+
layoutPane: "bg-card",
|
|
9142
|
+
layoutPaneMuted: "bg-muted/35",
|
|
9143
|
+
layoutResizeHandle: "hover:bg-border/70 active:bg-border/80 focus-visible:bg-border/70"
|
|
9077
9144
|
},
|
|
9078
9145
|
soft: {
|
|
9079
9146
|
buttonDefault: "bg-muted/30 hover:bg-muted/55",
|
|
@@ -9109,7 +9176,10 @@ var backgroundSlots = {
|
|
|
9109
9176
|
tableFooter: "bg-muted/25",
|
|
9110
9177
|
tableFooterBar: "bg-muted/25 shadow-none",
|
|
9111
9178
|
tableRowInteractive: "cursor-pointer hover:bg-muted/35",
|
|
9112
|
-
tableLoadingSkeleton: "bg-muted/65"
|
|
9179
|
+
tableLoadingSkeleton: "bg-muted/65",
|
|
9180
|
+
layoutRoot: "bg-background/95 shadow-sm",
|
|
9181
|
+
layoutPane: "bg-background/95 shadow-sm",
|
|
9182
|
+
layoutPaneSoft: "bg-background/95 shadow-md"
|
|
9113
9183
|
},
|
|
9114
9184
|
glass: {
|
|
9115
9185
|
buttonBase: "backdrop-blur-md",
|
|
@@ -9170,7 +9240,13 @@ var backgroundSlots = {
|
|
|
9170
9240
|
tableRow: "border-white/10",
|
|
9171
9241
|
tableRowInteractive: "cursor-pointer hover:bg-white/[0.08]",
|
|
9172
9242
|
tableHeadLabel: "text-foreground",
|
|
9173
|
-
tableLoadingSkeleton: "bg-white/[0.16]"
|
|
9243
|
+
tableLoadingSkeleton: "bg-white/[0.16]",
|
|
9244
|
+
layoutRoot: "border-white/10 bg-white/[0.05] shadow-none backdrop-blur-md",
|
|
9245
|
+
layoutPane: "border-white/10 bg-white/[0.06] shadow-none backdrop-blur-md",
|
|
9246
|
+
layoutPaneMuted: "bg-white/[0.08]",
|
|
9247
|
+
layoutPaneSoft: "bg-white/[0.10] shadow-none backdrop-blur-md",
|
|
9248
|
+
layoutResizeHandle: "text-foreground/65 hover:bg-white/10 active:bg-white/15 focus-visible:bg-white/10",
|
|
9249
|
+
layoutResizeHandleIndicator: "bg-white/45 group-hover/resize:bg-white/75"
|
|
9174
9250
|
},
|
|
9175
9251
|
dark: {
|
|
9176
9252
|
buttonBase: "border-white/15 text-white shadow-lg backdrop-blur",
|
|
@@ -9299,7 +9375,13 @@ var backgroundSlots = {
|
|
|
9299
9375
|
menuSubTrigger: "text-white focus:bg-white/[0.10] focus:text-white data-[highlighted]:bg-white/[0.10] data-[highlighted]:text-white data-[state=open]:bg-white/[0.12]",
|
|
9300
9376
|
menuSubTriggerIcon: "text-white/55",
|
|
9301
9377
|
menuSubContent: "border-white/10 bg-slate-950 text-white shadow-2xl",
|
|
9302
|
-
tableLoadingSkeleton: "bg-white/[0.14]"
|
|
9378
|
+
tableLoadingSkeleton: "bg-white/[0.14]",
|
|
9379
|
+
layoutRoot: "border-white/10 bg-slate-950 text-white shadow-none",
|
|
9380
|
+
layoutPane: "border-white/10 bg-slate-950 text-white shadow-none",
|
|
9381
|
+
layoutPaneMuted: "bg-white/[0.06]",
|
|
9382
|
+
layoutPaneSoft: "bg-white/[0.08] shadow-none",
|
|
9383
|
+
layoutResizeHandle: "text-white/65 hover:bg-white/10 active:bg-white/15 focus-visible:bg-white/10",
|
|
9384
|
+
layoutResizeHandleIndicator: "bg-white/45 group-hover/resize:bg-white/75"
|
|
9303
9385
|
}
|
|
9304
9386
|
};
|
|
9305
9387
|
var presetDefaults = {
|
|
@@ -11157,6 +11239,432 @@ var BaseInput = React.forwardRef(
|
|
|
11157
11239
|
);
|
|
11158
11240
|
}
|
|
11159
11241
|
);
|
|
11242
|
+
var DEFAULT_SPLIT_SIZE = 50;
|
|
11243
|
+
var DEFAULT_MIN_SIZE = 20;
|
|
11244
|
+
var DEFAULT_MAX_SIZE = 80;
|
|
11245
|
+
var DEFAULT_KEYBOARD_STEP = 2.5;
|
|
11246
|
+
function toCssSize(value, fallback) {
|
|
11247
|
+
if (typeof value === "number") {
|
|
11248
|
+
if (!Number.isFinite(value) || value < 0) {
|
|
11249
|
+
throw new Error("BaseLayout size and gap props must be finite, non-negative numbers.");
|
|
11250
|
+
}
|
|
11251
|
+
return `${value}px`;
|
|
11252
|
+
}
|
|
11253
|
+
return value ?? fallback;
|
|
11254
|
+
}
|
|
11255
|
+
function assertPercent(name, value) {
|
|
11256
|
+
if (!Number.isFinite(value)) {
|
|
11257
|
+
throw new Error(`BaseLayoutSplit ${name} must be a finite number.`);
|
|
11258
|
+
}
|
|
11259
|
+
if (value < 0 || value > 100) {
|
|
11260
|
+
throw new Error(`BaseLayoutSplit ${name} must be between 0 and 100.`);
|
|
11261
|
+
}
|
|
11262
|
+
return value;
|
|
11263
|
+
}
|
|
11264
|
+
function clamp(value, min5, max5) {
|
|
11265
|
+
return Math.min(Math.max(value, min5), max5);
|
|
11266
|
+
}
|
|
11267
|
+
function resolveSplitBounds({
|
|
11268
|
+
minSize = DEFAULT_MIN_SIZE,
|
|
11269
|
+
maxSize = DEFAULT_MAX_SIZE,
|
|
11270
|
+
keyboardStep = DEFAULT_KEYBOARD_STEP
|
|
11271
|
+
}) {
|
|
11272
|
+
const min5 = assertPercent("minSize", minSize);
|
|
11273
|
+
const max5 = assertPercent("maxSize", maxSize);
|
|
11274
|
+
if (min5 > max5) {
|
|
11275
|
+
throw new Error("BaseLayoutSplit minSize cannot be greater than maxSize.");
|
|
11276
|
+
}
|
|
11277
|
+
if (!Number.isFinite(keyboardStep) || keyboardStep <= 0) {
|
|
11278
|
+
throw new Error("BaseLayoutSplit keyboardStep must be a finite positive number.");
|
|
11279
|
+
}
|
|
11280
|
+
return { min: min5, max: max5, keyboardStep };
|
|
11281
|
+
}
|
|
11282
|
+
function resolveSplitSize(name, value, fallback, min5, max5) {
|
|
11283
|
+
return clamp(assertPercent(name, value ?? fallback), min5, max5);
|
|
11284
|
+
}
|
|
11285
|
+
function getSeparatorOrientation(orientation) {
|
|
11286
|
+
return orientation === "horizontal" ? "vertical" : "horizontal";
|
|
11287
|
+
}
|
|
11288
|
+
function BaseLayout({
|
|
11289
|
+
header,
|
|
11290
|
+
sidebar,
|
|
11291
|
+
aside,
|
|
11292
|
+
footer,
|
|
11293
|
+
children,
|
|
11294
|
+
sidebarSize,
|
|
11295
|
+
asideSize,
|
|
11296
|
+
gap,
|
|
11297
|
+
fullHeight,
|
|
11298
|
+
appearance,
|
|
11299
|
+
className,
|
|
11300
|
+
classNames,
|
|
11301
|
+
style,
|
|
11302
|
+
...layoutProps
|
|
11303
|
+
}) {
|
|
11304
|
+
const theme = resolveBaseAppearance(appearance);
|
|
11305
|
+
const hasHeader = hasRenderableNode(header);
|
|
11306
|
+
const hasSidebar = hasRenderableNode(sidebar);
|
|
11307
|
+
const hasAside = hasRenderableNode(aside);
|
|
11308
|
+
const hasFooter = hasRenderableNode(footer);
|
|
11309
|
+
const bodyColumns = [
|
|
11310
|
+
hasSidebar ? "var(--base-layout-sidebar-size)" : void 0,
|
|
11311
|
+
"minmax(0, 1fr)",
|
|
11312
|
+
hasAside ? "var(--base-layout-aside-size)" : void 0
|
|
11313
|
+
].filter(Boolean).join(" ");
|
|
11314
|
+
const layoutRows = [
|
|
11315
|
+
hasHeader ? "auto" : void 0,
|
|
11316
|
+
"minmax(0, 1fr)",
|
|
11317
|
+
hasFooter ? "auto" : void 0
|
|
11318
|
+
].filter(Boolean).join(" ");
|
|
11319
|
+
const resolvedGap = gap !== void 0 ? toCssSize(gap, "0px") : void 0;
|
|
11320
|
+
const layoutStyle = {
|
|
11321
|
+
...theme.styles.layout,
|
|
11322
|
+
"--base-layout-sidebar-size": toCssSize(sidebarSize, "16rem"),
|
|
11323
|
+
"--base-layout-aside-size": toCssSize(asideSize, "20rem"),
|
|
11324
|
+
gridTemplateRows: layoutRows,
|
|
11325
|
+
...resolvedGap !== void 0 ? { gap: resolvedGap } : {},
|
|
11326
|
+
...style
|
|
11327
|
+
};
|
|
11328
|
+
const bodyStyle = {
|
|
11329
|
+
...theme.styles.layoutBody,
|
|
11330
|
+
gridTemplateColumns: bodyColumns,
|
|
11331
|
+
...resolvedGap !== void 0 ? { gap: resolvedGap } : {}
|
|
11332
|
+
};
|
|
11333
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
11334
|
+
"div",
|
|
11335
|
+
{
|
|
11336
|
+
...layoutProps,
|
|
11337
|
+
className: cn(
|
|
11338
|
+
theme.slots.layoutRoot,
|
|
11339
|
+
fullHeight && theme.slots.layoutRootFull,
|
|
11340
|
+
classNames?.root,
|
|
11341
|
+
className
|
|
11342
|
+
),
|
|
11343
|
+
style: layoutStyle,
|
|
11344
|
+
children: [
|
|
11345
|
+
hasHeader ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
11346
|
+
"div",
|
|
11347
|
+
{
|
|
11348
|
+
className: cn(theme.slots.layoutHeader, classNames?.header),
|
|
11349
|
+
style: theme.styles.layoutHeader,
|
|
11350
|
+
children: header
|
|
11351
|
+
}
|
|
11352
|
+
) : null,
|
|
11353
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
11354
|
+
"div",
|
|
11355
|
+
{
|
|
11356
|
+
className: cn(theme.slots.layoutBody, classNames?.body),
|
|
11357
|
+
style: bodyStyle,
|
|
11358
|
+
children: [
|
|
11359
|
+
hasSidebar ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
11360
|
+
"aside",
|
|
11361
|
+
{
|
|
11362
|
+
className: cn(theme.slots.layoutSidebar, classNames?.sidebar),
|
|
11363
|
+
style: theme.styles.layoutSidebar,
|
|
11364
|
+
children: sidebar
|
|
11365
|
+
}
|
|
11366
|
+
) : null,
|
|
11367
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
11368
|
+
"main",
|
|
11369
|
+
{
|
|
11370
|
+
className: cn(theme.slots.layoutMain, classNames?.main),
|
|
11371
|
+
style: theme.styles.layoutMain,
|
|
11372
|
+
children
|
|
11373
|
+
}
|
|
11374
|
+
),
|
|
11375
|
+
hasAside ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
11376
|
+
"aside",
|
|
11377
|
+
{
|
|
11378
|
+
className: cn(theme.slots.layoutAside, classNames?.aside),
|
|
11379
|
+
style: theme.styles.layoutAside,
|
|
11380
|
+
children: aside
|
|
11381
|
+
}
|
|
11382
|
+
) : null
|
|
11383
|
+
]
|
|
11384
|
+
}
|
|
11385
|
+
),
|
|
11386
|
+
hasFooter ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
11387
|
+
"div",
|
|
11388
|
+
{
|
|
11389
|
+
className: cn(theme.slots.layoutFooter, classNames?.footer),
|
|
11390
|
+
style: theme.styles.layoutFooter,
|
|
11391
|
+
children: footer
|
|
11392
|
+
}
|
|
11393
|
+
) : null
|
|
11394
|
+
]
|
|
11395
|
+
}
|
|
11396
|
+
);
|
|
11397
|
+
}
|
|
11398
|
+
function BaseLayoutPane({
|
|
11399
|
+
as = "div",
|
|
11400
|
+
scrollable = false,
|
|
11401
|
+
bordered = true,
|
|
11402
|
+
surface = "default",
|
|
11403
|
+
children,
|
|
11404
|
+
appearance,
|
|
11405
|
+
className,
|
|
11406
|
+
classNames,
|
|
11407
|
+
style,
|
|
11408
|
+
...paneProps
|
|
11409
|
+
}) {
|
|
11410
|
+
const theme = resolveBaseAppearance(appearance);
|
|
11411
|
+
const Component = as;
|
|
11412
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
11413
|
+
Component,
|
|
11414
|
+
{
|
|
11415
|
+
...paneProps,
|
|
11416
|
+
className: cn(
|
|
11417
|
+
theme.slots.layoutPane,
|
|
11418
|
+
scrollable && theme.slots.layoutPaneScrollable,
|
|
11419
|
+
bordered && theme.slots.layoutPaneBordered,
|
|
11420
|
+
surface === "muted" && theme.slots.layoutPaneMuted,
|
|
11421
|
+
surface === "soft" && theme.slots.layoutPaneSoft,
|
|
11422
|
+
surface === "transparent" && theme.slots.layoutPaneTransparent,
|
|
11423
|
+
classNames?.root,
|
|
11424
|
+
className
|
|
11425
|
+
),
|
|
11426
|
+
style: {
|
|
11427
|
+
...theme.styles.layoutPane,
|
|
11428
|
+
...style
|
|
11429
|
+
},
|
|
11430
|
+
children
|
|
11431
|
+
}
|
|
11432
|
+
);
|
|
11433
|
+
}
|
|
11434
|
+
function BaseLayoutResizeHandle({
|
|
11435
|
+
orientation = "horizontal",
|
|
11436
|
+
resizable = false,
|
|
11437
|
+
disabled = false,
|
|
11438
|
+
size,
|
|
11439
|
+
minSize,
|
|
11440
|
+
maxSize,
|
|
11441
|
+
label = "Resize panels",
|
|
11442
|
+
appearance,
|
|
11443
|
+
className,
|
|
11444
|
+
classNames,
|
|
11445
|
+
style,
|
|
11446
|
+
tabIndex,
|
|
11447
|
+
...handleProps
|
|
11448
|
+
}) {
|
|
11449
|
+
const theme = resolveBaseAppearance(appearance);
|
|
11450
|
+
const interactive = resizable && !disabled;
|
|
11451
|
+
const separatorOrientation = getSeparatorOrientation(orientation);
|
|
11452
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
11453
|
+
"div",
|
|
11454
|
+
{
|
|
11455
|
+
...handleProps,
|
|
11456
|
+
role: interactive ? "separator" : void 0,
|
|
11457
|
+
"aria-label": interactive ? label : void 0,
|
|
11458
|
+
"aria-orientation": interactive ? separatorOrientation : void 0,
|
|
11459
|
+
"aria-valuemin": interactive ? minSize : void 0,
|
|
11460
|
+
"aria-valuemax": interactive ? maxSize : void 0,
|
|
11461
|
+
"aria-valuenow": interactive ? size : void 0,
|
|
11462
|
+
"aria-disabled": interactive ? void 0 : true,
|
|
11463
|
+
tabIndex: interactive ? tabIndex ?? 0 : void 0,
|
|
11464
|
+
className: cn(
|
|
11465
|
+
theme.slots.layoutResizeHandle,
|
|
11466
|
+
orientation === "horizontal" ? theme.slots.layoutResizeHandleHorizontal : theme.slots.layoutResizeHandleVertical,
|
|
11467
|
+
!interactive && theme.slots.layoutResizeHandleDisabled,
|
|
11468
|
+
classNames?.root,
|
|
11469
|
+
className
|
|
11470
|
+
),
|
|
11471
|
+
style: {
|
|
11472
|
+
...theme.styles.layoutResizeHandle,
|
|
11473
|
+
...style
|
|
11474
|
+
},
|
|
11475
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
11476
|
+
"span",
|
|
11477
|
+
{
|
|
11478
|
+
"aria-hidden": "true",
|
|
11479
|
+
className: cn(
|
|
11480
|
+
theme.slots.layoutResizeHandleIndicator,
|
|
11481
|
+
orientation === "horizontal" ? "h-8 w-px" : "h-px w-8",
|
|
11482
|
+
classNames?.indicator
|
|
11483
|
+
)
|
|
11484
|
+
}
|
|
11485
|
+
)
|
|
11486
|
+
}
|
|
11487
|
+
);
|
|
11488
|
+
}
|
|
11489
|
+
function BaseLayoutSplit({
|
|
11490
|
+
orientation = "horizontal",
|
|
11491
|
+
primary,
|
|
11492
|
+
secondary,
|
|
11493
|
+
children,
|
|
11494
|
+
resizable = false,
|
|
11495
|
+
size,
|
|
11496
|
+
defaultSize,
|
|
11497
|
+
minSize,
|
|
11498
|
+
maxSize,
|
|
11499
|
+
gap,
|
|
11500
|
+
keyboardStep,
|
|
11501
|
+
resizeLabel,
|
|
11502
|
+
appearance,
|
|
11503
|
+
className,
|
|
11504
|
+
classNames,
|
|
11505
|
+
style,
|
|
11506
|
+
onSizeChange,
|
|
11507
|
+
...splitProps
|
|
11508
|
+
}) {
|
|
11509
|
+
const theme = resolveBaseAppearance(appearance);
|
|
11510
|
+
const bounds = resolveSplitBounds({ minSize, maxSize, keyboardStep });
|
|
11511
|
+
const initialSize = resolveSplitSize(
|
|
11512
|
+
"defaultSize",
|
|
11513
|
+
defaultSize,
|
|
11514
|
+
DEFAULT_SPLIT_SIZE,
|
|
11515
|
+
bounds.min,
|
|
11516
|
+
bounds.max
|
|
11517
|
+
);
|
|
11518
|
+
const [uncontrolledSize, setUncontrolledSize] = React.useState(initialSize);
|
|
11519
|
+
const rootRef = React.useRef(null);
|
|
11520
|
+
const cleanupRef = React.useRef(null);
|
|
11521
|
+
const controlled = size !== void 0;
|
|
11522
|
+
const renderedSize = resolveSplitSize(
|
|
11523
|
+
"size",
|
|
11524
|
+
controlled ? size : uncontrolledSize,
|
|
11525
|
+
initialSize,
|
|
11526
|
+
bounds.min,
|
|
11527
|
+
bounds.max
|
|
11528
|
+
);
|
|
11529
|
+
const commitSize = React.useCallback(
|
|
11530
|
+
(nextSize) => {
|
|
11531
|
+
const clampedSize = clamp(nextSize, bounds.min, bounds.max);
|
|
11532
|
+
if (!controlled) {
|
|
11533
|
+
setUncontrolledSize(clampedSize);
|
|
11534
|
+
}
|
|
11535
|
+
onSizeChange?.(clampedSize);
|
|
11536
|
+
},
|
|
11537
|
+
[bounds.max, bounds.min, controlled, onSizeChange]
|
|
11538
|
+
);
|
|
11539
|
+
const updateFromPointer = React.useCallback(
|
|
11540
|
+
(event) => {
|
|
11541
|
+
const root = rootRef.current;
|
|
11542
|
+
if (!root) return;
|
|
11543
|
+
const rect = root.getBoundingClientRect();
|
|
11544
|
+
const total = orientation === "horizontal" ? rect.width : rect.height;
|
|
11545
|
+
if (total <= 0) return;
|
|
11546
|
+
const offset = orientation === "horizontal" ? event.clientX - rect.left : event.clientY - rect.top;
|
|
11547
|
+
commitSize(offset / total * 100);
|
|
11548
|
+
},
|
|
11549
|
+
[commitSize, orientation]
|
|
11550
|
+
);
|
|
11551
|
+
const stopResize = React.useCallback(() => {
|
|
11552
|
+
cleanupRef.current?.();
|
|
11553
|
+
cleanupRef.current = null;
|
|
11554
|
+
}, []);
|
|
11555
|
+
React.useEffect(() => stopResize, [stopResize]);
|
|
11556
|
+
const handlePointerDown = (event) => {
|
|
11557
|
+
if (!resizable) return;
|
|
11558
|
+
event.preventDefault();
|
|
11559
|
+
stopResize();
|
|
11560
|
+
updateFromPointer(event);
|
|
11561
|
+
const handleMove = (nextEvent) => {
|
|
11562
|
+
updateFromPointer(nextEvent);
|
|
11563
|
+
};
|
|
11564
|
+
const handleStop = () => {
|
|
11565
|
+
stopResize();
|
|
11566
|
+
};
|
|
11567
|
+
window.addEventListener("pointermove", handleMove);
|
|
11568
|
+
window.addEventListener("pointerup", handleStop, { once: true });
|
|
11569
|
+
window.addEventListener("pointercancel", handleStop, { once: true });
|
|
11570
|
+
cleanupRef.current = () => {
|
|
11571
|
+
window.removeEventListener("pointermove", handleMove);
|
|
11572
|
+
window.removeEventListener("pointerup", handleStop);
|
|
11573
|
+
window.removeEventListener("pointercancel", handleStop);
|
|
11574
|
+
};
|
|
11575
|
+
};
|
|
11576
|
+
const handleKeyDown = (event) => {
|
|
11577
|
+
if (!resizable) return;
|
|
11578
|
+
const step = event.shiftKey ? bounds.keyboardStep * 4 : bounds.keyboardStep;
|
|
11579
|
+
let nextSize;
|
|
11580
|
+
if (event.key === "Home") nextSize = bounds.min;
|
|
11581
|
+
if (event.key === "End") nextSize = bounds.max;
|
|
11582
|
+
if (orientation === "horizontal" && event.key === "ArrowLeft") {
|
|
11583
|
+
nextSize = renderedSize - step;
|
|
11584
|
+
}
|
|
11585
|
+
if (orientation === "horizontal" && event.key === "ArrowRight") {
|
|
11586
|
+
nextSize = renderedSize + step;
|
|
11587
|
+
}
|
|
11588
|
+
if (orientation === "vertical" && event.key === "ArrowUp") {
|
|
11589
|
+
nextSize = renderedSize - step;
|
|
11590
|
+
}
|
|
11591
|
+
if (orientation === "vertical" && event.key === "ArrowDown") {
|
|
11592
|
+
nextSize = renderedSize + step;
|
|
11593
|
+
}
|
|
11594
|
+
if (nextSize === void 0) return;
|
|
11595
|
+
event.preventDefault();
|
|
11596
|
+
commitSize(nextSize);
|
|
11597
|
+
};
|
|
11598
|
+
const resolvedGap = gap !== void 0 ? toCssSize(gap, "0px") : void 0;
|
|
11599
|
+
const resizeTrack = resolvedGap !== void 0 ? "var(--base-layout-split-gap)" : "auto";
|
|
11600
|
+
const resizeHandleStyle = resolvedGap !== void 0 ? orientation === "horizontal" ? { width: "var(--base-layout-split-gap)" } : { height: "var(--base-layout-split-gap)" } : void 0;
|
|
11601
|
+
const splitStyle = {
|
|
11602
|
+
...theme.styles.layoutSplit,
|
|
11603
|
+
[orientation === "horizontal" ? "gridTemplateColumns" : "gridTemplateRows"]: resizable ? `${renderedSize}% ${resizeTrack} minmax(0, 1fr)` : `${renderedSize}% minmax(0, 1fr)`,
|
|
11604
|
+
...resizable ? { gap: 0 } : {},
|
|
11605
|
+
...resolvedGap !== void 0 ? {
|
|
11606
|
+
"--base-layout-split-gap": resolvedGap,
|
|
11607
|
+
...resizable ? {} : { gap: resolvedGap }
|
|
11608
|
+
} : {},
|
|
11609
|
+
...style
|
|
11610
|
+
};
|
|
11611
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
11612
|
+
"div",
|
|
11613
|
+
{
|
|
11614
|
+
...splitProps,
|
|
11615
|
+
ref: rootRef,
|
|
11616
|
+
className: cn(
|
|
11617
|
+
theme.slots.layoutSplitRoot,
|
|
11618
|
+
orientation === "horizontal" ? theme.slots.layoutSplitHorizontal : theme.slots.layoutSplitVertical,
|
|
11619
|
+
classNames?.root,
|
|
11620
|
+
className
|
|
11621
|
+
),
|
|
11622
|
+
style: splitStyle,
|
|
11623
|
+
children: [
|
|
11624
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
11625
|
+
"div",
|
|
11626
|
+
{
|
|
11627
|
+
className: cn(
|
|
11628
|
+
theme.slots.layoutSplitPane,
|
|
11629
|
+
theme.slots.layoutSplitPrimary,
|
|
11630
|
+
classNames?.primary
|
|
11631
|
+
),
|
|
11632
|
+
style: theme.styles.layoutSplitPane,
|
|
11633
|
+
children: hasRenderableNode(primary) ? primary : children
|
|
11634
|
+
}
|
|
11635
|
+
),
|
|
11636
|
+
resizable ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
11637
|
+
BaseLayoutResizeHandle,
|
|
11638
|
+
{
|
|
11639
|
+
orientation,
|
|
11640
|
+
resizable: true,
|
|
11641
|
+
size: renderedSize,
|
|
11642
|
+
minSize: bounds.min,
|
|
11643
|
+
maxSize: bounds.max,
|
|
11644
|
+
label: resizeLabel,
|
|
11645
|
+
appearance,
|
|
11646
|
+
className: classNames?.handle,
|
|
11647
|
+
style: resizeHandleStyle,
|
|
11648
|
+
onPointerDown: handlePointerDown,
|
|
11649
|
+
onKeyDown: handleKeyDown
|
|
11650
|
+
}
|
|
11651
|
+
) : null,
|
|
11652
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
11653
|
+
"div",
|
|
11654
|
+
{
|
|
11655
|
+
className: cn(
|
|
11656
|
+
theme.slots.layoutSplitPane,
|
|
11657
|
+
theme.slots.layoutSplitSecondary,
|
|
11658
|
+
classNames?.secondary
|
|
11659
|
+
),
|
|
11660
|
+
style: theme.styles.layoutSplitPane,
|
|
11661
|
+
children: secondary
|
|
11662
|
+
}
|
|
11663
|
+
)
|
|
11664
|
+
]
|
|
11665
|
+
}
|
|
11666
|
+
);
|
|
11667
|
+
}
|
|
11160
11668
|
function DefaultLoadingIcon({ className }) {
|
|
11161
11669
|
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
11162
11670
|
"svg",
|
|
@@ -11446,7 +11954,7 @@ function BasePagination({
|
|
|
11446
11954
|
function toFiniteNumber(value, fallback) {
|
|
11447
11955
|
return Number.isFinite(value) ? Number(value) : fallback;
|
|
11448
11956
|
}
|
|
11449
|
-
function
|
|
11957
|
+
function clamp2(value, min5, max5) {
|
|
11450
11958
|
return Math.min(Math.max(value, min5), max5);
|
|
11451
11959
|
}
|
|
11452
11960
|
function BaseProgress({
|
|
@@ -11464,7 +11972,7 @@ function BaseProgress({
|
|
|
11464
11972
|
}) {
|
|
11465
11973
|
const theme = resolveBaseAppearance(appearance);
|
|
11466
11974
|
const safeMax = Math.max(toFiniteNumber(max5, 100), 1);
|
|
11467
|
-
const safeValue =
|
|
11975
|
+
const safeValue = clamp2(toFiniteNumber(value, 0), 0, safeMax);
|
|
11468
11976
|
const percent = safeValue / safeMax * 100;
|
|
11469
11977
|
const renderedValue = valueFormatter?.(safeValue, safeMax) ?? `${Math.round(percent)}%`;
|
|
11470
11978
|
const hasLabelRow = hasRenderableNode(label) || showValue;
|
|
@@ -12230,7 +12738,7 @@ function useBaseTableContext(appearance) {
|
|
|
12230
12738
|
}
|
|
12231
12739
|
};
|
|
12232
12740
|
}
|
|
12233
|
-
function
|
|
12741
|
+
function toCssSize2(value) {
|
|
12234
12742
|
if (value === void 0) return void 0;
|
|
12235
12743
|
return typeof value === "number" ? `${value}px` : value;
|
|
12236
12744
|
}
|
|
@@ -12443,7 +12951,7 @@ function BaseTableRow({
|
|
|
12443
12951
|
}
|
|
12444
12952
|
);
|
|
12445
12953
|
}
|
|
12446
|
-
|
|
12954
|
+
var BaseTableHead = React.forwardRef(function BaseTableHead2({
|
|
12447
12955
|
columnId,
|
|
12448
12956
|
align = "left",
|
|
12449
12957
|
icon,
|
|
@@ -12471,10 +12979,18 @@ function BaseTableHead({
|
|
|
12471
12979
|
onDragOver,
|
|
12472
12980
|
onDrop,
|
|
12473
12981
|
...headProps
|
|
12474
|
-
}) {
|
|
12982
|
+
}, forwardedRef) {
|
|
12475
12983
|
const tableContext = useBaseTableContext(appearance);
|
|
12476
12984
|
const { theme } = tableContext;
|
|
12477
12985
|
const headRef = React.useRef(null);
|
|
12986
|
+
const setHeadRef = (node) => {
|
|
12987
|
+
headRef.current = node;
|
|
12988
|
+
if (typeof forwardedRef === "function") {
|
|
12989
|
+
forwardedRef(node);
|
|
12990
|
+
} else if (forwardedRef) {
|
|
12991
|
+
forwardedRef.current = node;
|
|
12992
|
+
}
|
|
12993
|
+
};
|
|
12478
12994
|
const controlledWidth = columnId && tableContext.columnSizes?.[columnId] !== void 0 ? tableContext.columnSizes[columnId] : width;
|
|
12479
12995
|
const canDrag = Boolean(
|
|
12480
12996
|
columnId && draggable !== false && (draggable || tableContext.columnDragEnabled) && tableContext.columnOrder && tableContext.onColumnOrderChange
|
|
@@ -12629,7 +13145,7 @@ function BaseTableHead({
|
|
|
12629
13145
|
"th",
|
|
12630
13146
|
{
|
|
12631
13147
|
...headProps,
|
|
12632
|
-
ref:
|
|
13148
|
+
ref: setHeadRef,
|
|
12633
13149
|
scope: headProps.scope ?? "col",
|
|
12634
13150
|
"aria-sort": ariaSort,
|
|
12635
13151
|
className: cn(
|
|
@@ -12641,9 +13157,9 @@ function BaseTableHead({
|
|
|
12641
13157
|
),
|
|
12642
13158
|
style: {
|
|
12643
13159
|
...theme.styles.tableHead,
|
|
12644
|
-
width:
|
|
12645
|
-
minWidth:
|
|
12646
|
-
maxWidth:
|
|
13160
|
+
width: toCssSize2(controlledWidth),
|
|
13161
|
+
minWidth: toCssSize2(minWidth),
|
|
13162
|
+
maxWidth: toCssSize2(maxWidth),
|
|
12647
13163
|
...style
|
|
12648
13164
|
},
|
|
12649
13165
|
onDragOver: handleDragOver,
|
|
@@ -12664,7 +13180,7 @@ function BaseTableHead({
|
|
|
12664
13180
|
]
|
|
12665
13181
|
}
|
|
12666
13182
|
);
|
|
12667
|
-
}
|
|
13183
|
+
});
|
|
12668
13184
|
function BaseTableCell({
|
|
12669
13185
|
align = "left",
|
|
12670
13186
|
appearance,
|
|
@@ -12792,7 +13308,7 @@ function BaseTableLoading({
|
|
|
12792
13308
|
classNames?.skeleton
|
|
12793
13309
|
),
|
|
12794
13310
|
style: {
|
|
12795
|
-
width:
|
|
13311
|
+
width: toCssSize2(columnWidths[columnIndex])
|
|
12796
13312
|
}
|
|
12797
13313
|
}
|
|
12798
13314
|
)
|
|
@@ -15807,7 +16323,7 @@ var DEFAULT_ZOOM_STEP = 1.18;
|
|
|
15807
16323
|
var DEFAULT_STAGE_PADDING = 16;
|
|
15808
16324
|
var MAX_SAFE_SCALE = 1e6;
|
|
15809
16325
|
var MIN_SAFE_SCALE = 1e-6;
|
|
15810
|
-
var
|
|
16326
|
+
var clamp3 = (value, min5, max5) => Math.min(max5, Math.max(min5, value));
|
|
15811
16327
|
var isNoDragTarget = (target) => target instanceof Element && Boolean(target.closest('[data-no-drag="true"]'));
|
|
15812
16328
|
function ResetIcon() {
|
|
15813
16329
|
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
@@ -15931,7 +16447,7 @@ function DataExplorerImagePreview({
|
|
|
15931
16447
|
availableWidth / size.width,
|
|
15932
16448
|
availableHeight / size.height
|
|
15933
16449
|
);
|
|
15934
|
-
const nextScale =
|
|
16450
|
+
const nextScale = clamp3(
|
|
15935
16451
|
fitScale,
|
|
15936
16452
|
normalizedMinScale,
|
|
15937
16453
|
normalizedMaxScale
|
|
@@ -15985,7 +16501,7 @@ function DataExplorerImagePreview({
|
|
|
15985
16501
|
if (!Number.isFinite(factor) || factor === 1) return;
|
|
15986
16502
|
if (!Number.isFinite(stageX) || !Number.isFinite(stageY)) return;
|
|
15987
16503
|
setView((current) => {
|
|
15988
|
-
const nextScale =
|
|
16504
|
+
const nextScale = clamp3(
|
|
15989
16505
|
current.scale * factor,
|
|
15990
16506
|
normalizedMinScale,
|
|
15991
16507
|
normalizedMaxScale
|
|
@@ -19996,6 +20512,3637 @@ function AppLayout({ header, sidebar, children, flush = false, className }) {
|
|
|
19996
20512
|
] })
|
|
19997
20513
|
] });
|
|
19998
20514
|
}
|
|
20515
|
+
function ClampIcon({ expanded }) {
|
|
20516
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("svg", { "aria-hidden": "true", viewBox: "0 0 20 20", className: "h-4 w-4", fill: "none", children: [
|
|
20517
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
20518
|
+
"path",
|
|
20519
|
+
{
|
|
20520
|
+
d: "M4 4.5h12M4 15.5h12M7.5 7.5 5 10l2.5 2.5M12.5 7.5 15 10l-2.5 2.5",
|
|
20521
|
+
stroke: "currentColor",
|
|
20522
|
+
strokeWidth: "1.6",
|
|
20523
|
+
strokeLinecap: "round",
|
|
20524
|
+
strokeLinejoin: "round",
|
|
20525
|
+
className: expanded ? "" : "hidden"
|
|
20526
|
+
}
|
|
20527
|
+
),
|
|
20528
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
20529
|
+
"path",
|
|
20530
|
+
{
|
|
20531
|
+
d: "M4 4.5h12M4 15.5h12M5 7.5 7.5 10 5 12.5M15 7.5 12.5 10l2.5 2.5",
|
|
20532
|
+
stroke: "currentColor",
|
|
20533
|
+
strokeWidth: "1.6",
|
|
20534
|
+
strokeLinecap: "round",
|
|
20535
|
+
strokeLinejoin: "round",
|
|
20536
|
+
className: expanded ? "hidden" : ""
|
|
20537
|
+
}
|
|
20538
|
+
)
|
|
20539
|
+
] });
|
|
20540
|
+
}
|
|
20541
|
+
function ResizeGripIcon() {
|
|
20542
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
20543
|
+
"span",
|
|
20544
|
+
{
|
|
20545
|
+
"aria-hidden": "true",
|
|
20546
|
+
className: "pointer-events-none absolute right-1/2 top-3 bottom-3 w-px translate-x-1/2 rounded-full bg-border/65 opacity-0 transition-opacity group-hover/resize:opacity-100"
|
|
20547
|
+
}
|
|
20548
|
+
);
|
|
20549
|
+
}
|
|
20550
|
+
function getItemTitle(item) {
|
|
20551
|
+
if (item.title) return item.title;
|
|
20552
|
+
return typeof item.label === "string" ? item.label : void 0;
|
|
20553
|
+
}
|
|
20554
|
+
function clampWidth2(width, minWidth, maxWidth) {
|
|
20555
|
+
return Math.min(Math.max(width, minWidth), maxWidth);
|
|
20556
|
+
}
|
|
20557
|
+
function assignRef(ref, node) {
|
|
20558
|
+
if (typeof ref === "function") {
|
|
20559
|
+
ref(node);
|
|
20560
|
+
} else if (ref) {
|
|
20561
|
+
ref.current = node;
|
|
20562
|
+
}
|
|
20563
|
+
}
|
|
20564
|
+
function readStoredLayout(storageKey, options) {
|
|
20565
|
+
const fallback = {
|
|
20566
|
+
collapsed: options.defaultCollapsed,
|
|
20567
|
+
width: clampWidth2(options.defaultWidth, options.minWidth, options.maxWidth)
|
|
20568
|
+
};
|
|
20569
|
+
if (typeof window === "undefined" || !storageKey) return fallback;
|
|
20570
|
+
try {
|
|
20571
|
+
const rawValue = window.localStorage.getItem(storageKey);
|
|
20572
|
+
if (!rawValue) return fallback;
|
|
20573
|
+
const parsedValue = JSON.parse(rawValue);
|
|
20574
|
+
return {
|
|
20575
|
+
collapsed: typeof parsedValue.collapsed === "boolean" ? parsedValue.collapsed : fallback.collapsed,
|
|
20576
|
+
width: typeof parsedValue.width === "number" && Number.isFinite(parsedValue.width) ? clampWidth2(parsedValue.width, options.minWidth, options.maxWidth) : fallback.width
|
|
20577
|
+
};
|
|
20578
|
+
} catch {
|
|
20579
|
+
return fallback;
|
|
20580
|
+
}
|
|
20581
|
+
}
|
|
20582
|
+
var WorkbenchResizableSidebar = React.forwardRef(
|
|
20583
|
+
function WorkbenchResizableSidebar2({
|
|
20584
|
+
title,
|
|
20585
|
+
items,
|
|
20586
|
+
activeItemId,
|
|
20587
|
+
itemAs,
|
|
20588
|
+
collapsed,
|
|
20589
|
+
defaultCollapsed = false,
|
|
20590
|
+
onCollapsedChange,
|
|
20591
|
+
width,
|
|
20592
|
+
onWidthChange,
|
|
20593
|
+
defaultWidth = 220,
|
|
20594
|
+
minWidth = 180,
|
|
20595
|
+
maxWidth = 420,
|
|
20596
|
+
collapsedWidth = 60,
|
|
20597
|
+
collapseThreshold = 140,
|
|
20598
|
+
storageKey,
|
|
20599
|
+
resizable = true,
|
|
20600
|
+
collapsible = true,
|
|
20601
|
+
collapseLabel = "Collapse sidebar",
|
|
20602
|
+
expandLabel = "Expand sidebar",
|
|
20603
|
+
resizeLabel = "Resize sidebar",
|
|
20604
|
+
desktopClassName = "hidden md:flex",
|
|
20605
|
+
mobileClassName = "flex md:hidden",
|
|
20606
|
+
className,
|
|
20607
|
+
classNames,
|
|
20608
|
+
style
|
|
20609
|
+
}, ref) {
|
|
20610
|
+
const initialLayoutRef = React.useRef(null);
|
|
20611
|
+
if (!initialLayoutRef.current) {
|
|
20612
|
+
initialLayoutRef.current = readStoredLayout(storageKey, {
|
|
20613
|
+
defaultCollapsed,
|
|
20614
|
+
defaultWidth,
|
|
20615
|
+
minWidth,
|
|
20616
|
+
maxWidth
|
|
20617
|
+
});
|
|
20618
|
+
}
|
|
20619
|
+
const sidebarRef = React.useRef(null);
|
|
20620
|
+
const [internalCollapsed, setInternalCollapsed] = React.useState(initialLayoutRef.current.collapsed);
|
|
20621
|
+
const [internalWidth, setInternalWidth] = React.useState(initialLayoutRef.current.width);
|
|
20622
|
+
const [isResizing, setIsResizing] = React.useState(false);
|
|
20623
|
+
const resolvedCollapsed = collapsed ?? internalCollapsed;
|
|
20624
|
+
const resolvedWidth = width ?? internalWidth;
|
|
20625
|
+
const isCollapsedControlled = collapsed !== void 0;
|
|
20626
|
+
const isWidthControlled = width !== void 0;
|
|
20627
|
+
const setSidebarRef = (node) => {
|
|
20628
|
+
sidebarRef.current = node;
|
|
20629
|
+
assignRef(ref, node);
|
|
20630
|
+
};
|
|
20631
|
+
const updateCollapsed = (nextCollapsed) => {
|
|
20632
|
+
if (!collapsible && nextCollapsed) return;
|
|
20633
|
+
if (!isCollapsedControlled) {
|
|
20634
|
+
setInternalCollapsed(nextCollapsed);
|
|
20635
|
+
}
|
|
20636
|
+
onCollapsedChange?.(nextCollapsed);
|
|
20637
|
+
};
|
|
20638
|
+
const updateWidth = (nextWidth) => {
|
|
20639
|
+
const clampedWidth = clampWidth2(nextWidth, minWidth, maxWidth);
|
|
20640
|
+
if (!isWidthControlled) {
|
|
20641
|
+
setInternalWidth(clampedWidth);
|
|
20642
|
+
}
|
|
20643
|
+
onWidthChange?.(clampedWidth);
|
|
20644
|
+
};
|
|
20645
|
+
const startResize = (event) => {
|
|
20646
|
+
if (!resizable) return;
|
|
20647
|
+
event.preventDefault();
|
|
20648
|
+
setIsResizing(true);
|
|
20649
|
+
};
|
|
20650
|
+
const handleResizeKeyDown = (event) => {
|
|
20651
|
+
if (!resizable) return;
|
|
20652
|
+
if (event.key !== "ArrowLeft" && event.key !== "ArrowRight") return;
|
|
20653
|
+
event.preventDefault();
|
|
20654
|
+
if (event.key === "ArrowLeft") {
|
|
20655
|
+
const nextWidth = resolvedWidth - 24;
|
|
20656
|
+
if (nextWidth < collapseThreshold && collapsible) {
|
|
20657
|
+
updateCollapsed(true);
|
|
20658
|
+
return;
|
|
20659
|
+
}
|
|
20660
|
+
updateWidth(nextWidth);
|
|
20661
|
+
} else {
|
|
20662
|
+
if (resolvedCollapsed) {
|
|
20663
|
+
updateCollapsed(false);
|
|
20664
|
+
updateWidth(Math.max(resolvedWidth, minWidth));
|
|
20665
|
+
return;
|
|
20666
|
+
}
|
|
20667
|
+
updateWidth(resolvedWidth + 24);
|
|
20668
|
+
}
|
|
20669
|
+
};
|
|
20670
|
+
React.useEffect(() => {
|
|
20671
|
+
if (typeof window === "undefined" || !storageKey) return;
|
|
20672
|
+
window.localStorage.setItem(storageKey, JSON.stringify({
|
|
20673
|
+
collapsed: resolvedCollapsed,
|
|
20674
|
+
width: clampWidth2(resolvedWidth, minWidth, maxWidth)
|
|
20675
|
+
}));
|
|
20676
|
+
}, [maxWidth, minWidth, resolvedCollapsed, resolvedWidth, storageKey]);
|
|
20677
|
+
React.useEffect(() => {
|
|
20678
|
+
if (!isResizing) return void 0;
|
|
20679
|
+
const handlePointerMove = (event) => {
|
|
20680
|
+
const sidebarNode = sidebarRef.current;
|
|
20681
|
+
if (!sidebarNode) return;
|
|
20682
|
+
const nextWidth = event.clientX - sidebarNode.getBoundingClientRect().left;
|
|
20683
|
+
if (nextWidth < collapseThreshold && collapsible) {
|
|
20684
|
+
updateCollapsed(true);
|
|
20685
|
+
return;
|
|
20686
|
+
}
|
|
20687
|
+
updateCollapsed(false);
|
|
20688
|
+
updateWidth(nextWidth);
|
|
20689
|
+
};
|
|
20690
|
+
const handlePointerUp = () => setIsResizing(false);
|
|
20691
|
+
window.addEventListener("pointermove", handlePointerMove);
|
|
20692
|
+
window.addEventListener("pointerup", handlePointerUp);
|
|
20693
|
+
document.body.style.cursor = "col-resize";
|
|
20694
|
+
document.body.style.userSelect = "none";
|
|
20695
|
+
return () => {
|
|
20696
|
+
window.removeEventListener("pointermove", handlePointerMove);
|
|
20697
|
+
window.removeEventListener("pointerup", handlePointerUp);
|
|
20698
|
+
document.body.style.cursor = "";
|
|
20699
|
+
document.body.style.userSelect = "";
|
|
20700
|
+
};
|
|
20701
|
+
}, [collapseThreshold, collapsible, isResizing, maxWidth, minWidth, resolvedWidth, resolvedCollapsed]);
|
|
20702
|
+
const renderItem = (item, mobile = false) => {
|
|
20703
|
+
const active = item.active ?? item.id === activeItemId;
|
|
20704
|
+
const ItemComponent = itemAs ?? (item.href ? "a" : "button");
|
|
20705
|
+
const itemTitle = getItemTitle(item);
|
|
20706
|
+
const itemProps = {
|
|
20707
|
+
...item.to ? { to: item.to } : {},
|
|
20708
|
+
...item.href ? { href: item.href } : {},
|
|
20709
|
+
...ItemComponent === "button" ? { type: "button" } : {},
|
|
20710
|
+
title: itemTitle,
|
|
20711
|
+
"aria-current": active ? "page" : void 0,
|
|
20712
|
+
"aria-disabled": item.disabled || void 0,
|
|
20713
|
+
tabIndex: item.disabled ? -1 : void 0,
|
|
20714
|
+
onClick: (event) => {
|
|
20715
|
+
if (item.disabled) {
|
|
20716
|
+
event.preventDefault();
|
|
20717
|
+
return;
|
|
20718
|
+
}
|
|
20719
|
+
item.onClick?.(event);
|
|
20720
|
+
}
|
|
20721
|
+
};
|
|
20722
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
20723
|
+
ItemComponent,
|
|
20724
|
+
{
|
|
20725
|
+
...itemProps,
|
|
20726
|
+
"data-active": active ? "true" : "false",
|
|
20727
|
+
className: cn(
|
|
20728
|
+
mobile ? "inline-flex h-9 shrink-0 items-center gap-2 rounded-lg border px-3 text-xs font-medium transition-colors" : "relative flex h-9 w-full items-center justify-between gap-2 overflow-hidden rounded-md border px-2 text-left text-[12px] shadow-none transition-colors",
|
|
20729
|
+
mobile ? active ? "border-primary/40 bg-primary/12 text-foreground" : "border-border/60 bg-card/60 text-muted-foreground hover:bg-card/80 hover:text-foreground" : active ? "border-primary/40 bg-primary/12 text-foreground shadow-sm" : "border-border/60 bg-card/60 text-foreground hover:border-primary/20 hover:bg-card/80",
|
|
20730
|
+
!mobile && resolvedCollapsed && "justify-center px-0",
|
|
20731
|
+
item.disabled && "pointer-events-none opacity-50",
|
|
20732
|
+
mobile ? classNames?.mobileItem : classNames?.item,
|
|
20733
|
+
item.className
|
|
20734
|
+
),
|
|
20735
|
+
children: [
|
|
20736
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: cn("inline-flex h-4 w-4 shrink-0 items-center justify-center [&_svg]:h-3.5 [&_svg]:w-3.5", classNames?.itemIcon), children: item.icon }),
|
|
20737
|
+
mobile || !resolvedCollapsed ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: cn("min-w-0 flex-1 truncate", classNames?.itemLabel), children: item.label }) : null,
|
|
20738
|
+
!mobile && !resolvedCollapsed && item.endContent ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "shrink-0", children: item.endContent }) : null
|
|
20739
|
+
]
|
|
20740
|
+
},
|
|
20741
|
+
item.id
|
|
20742
|
+
);
|
|
20743
|
+
};
|
|
20744
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
20745
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
20746
|
+
"aside",
|
|
20747
|
+
{
|
|
20748
|
+
ref: setSidebarRef,
|
|
20749
|
+
"data-workbench-resizable-sidebar": true,
|
|
20750
|
+
"data-collapsed": resolvedCollapsed ? "true" : "false",
|
|
20751
|
+
className: cn(
|
|
20752
|
+
"relative z-20 h-full min-h-0 flex-shrink-0 flex-col rounded-xl border border-border/70 bg-card p-3 text-card-foreground shadow-sm",
|
|
20753
|
+
"transition-[width,opacity] duration-300",
|
|
20754
|
+
resolvedCollapsed && "items-center",
|
|
20755
|
+
desktopClassName,
|
|
20756
|
+
classNames?.root,
|
|
20757
|
+
className
|
|
20758
|
+
),
|
|
20759
|
+
style: {
|
|
20760
|
+
width: resolvedCollapsed ? collapsedWidth : resolvedWidth,
|
|
20761
|
+
transition: isResizing ? "none" : void 0,
|
|
20762
|
+
...style
|
|
20763
|
+
},
|
|
20764
|
+
children: [
|
|
20765
|
+
resizable ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
20766
|
+
"button",
|
|
20767
|
+
{
|
|
20768
|
+
type: "button",
|
|
20769
|
+
"aria-label": resizeLabel,
|
|
20770
|
+
title: resizeLabel,
|
|
20771
|
+
className: cn("group/resize absolute -right-1.5 bottom-0 top-0 z-50 w-3 cursor-col-resize bg-transparent outline-none focus-visible:ring-2 focus-visible:ring-primary/30", classNames?.resizeHandle),
|
|
20772
|
+
onPointerDown: startResize,
|
|
20773
|
+
onKeyDown: handleResizeKeyDown,
|
|
20774
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(ResizeGripIcon, {})
|
|
20775
|
+
}
|
|
20776
|
+
) : null,
|
|
20777
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex h-full w-full min-w-0 flex-col overflow-visible", children: [
|
|
20778
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: cn("mb-3 flex min-w-0 items-center gap-2", resolvedCollapsed ? "justify-center px-0" : "justify-between px-2", classNames?.header), children: [
|
|
20779
|
+
!resolvedCollapsed && title ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: cn("min-w-0 truncate text-[11px] font-medium uppercase text-muted-foreground", classNames?.title), children: title }) : null,
|
|
20780
|
+
collapsible ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
20781
|
+
"button",
|
|
20782
|
+
{
|
|
20783
|
+
type: "button",
|
|
20784
|
+
className: cn("inline-flex h-9 w-9 shrink-0 items-center justify-center rounded-md text-muted-foreground transition-colors hover:bg-muted/50 hover:text-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary/30", classNames?.collapseButton),
|
|
20785
|
+
"aria-label": resolvedCollapsed ? expandLabel : collapseLabel,
|
|
20786
|
+
title: resolvedCollapsed ? expandLabel : collapseLabel,
|
|
20787
|
+
onClick: () => updateCollapsed(!resolvedCollapsed),
|
|
20788
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(ClampIcon, { expanded: !resolvedCollapsed })
|
|
20789
|
+
}
|
|
20790
|
+
) : null
|
|
20791
|
+
] }),
|
|
20792
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: cn("min-h-0 flex-1 space-y-2 overflow-y-auto", resolvedCollapsed && "flex w-full flex-col items-center", classNames?.list), children: items.map((item) => renderItem(item)) })
|
|
20793
|
+
] })
|
|
20794
|
+
]
|
|
20795
|
+
}
|
|
20796
|
+
),
|
|
20797
|
+
/* @__PURE__ */ jsxRuntime.jsx("nav", { className: cn("gap-2 overflow-x-auto pb-1", mobileClassName, classNames?.mobileNav), "aria-label": typeof title === "string" ? title : void 0, children: items.map((item) => renderItem(item, true)) })
|
|
20798
|
+
] });
|
|
20799
|
+
}
|
|
20800
|
+
);
|
|
20801
|
+
function shouldRenderBodyWrapper(props) {
|
|
20802
|
+
return Boolean(
|
|
20803
|
+
props.header || props.footer || props.bodyAs || props.bodyClassName || props.bodyProps || props.classNames?.body
|
|
20804
|
+
);
|
|
20805
|
+
}
|
|
20806
|
+
var WorkbenchContentPane = React.forwardRef(
|
|
20807
|
+
function WorkbenchContentPane2({
|
|
20808
|
+
as: Component = "section",
|
|
20809
|
+
bodyAs: BodyComponent = "div",
|
|
20810
|
+
header,
|
|
20811
|
+
footer,
|
|
20812
|
+
children,
|
|
20813
|
+
className,
|
|
20814
|
+
headerClassName,
|
|
20815
|
+
bodyClassName,
|
|
20816
|
+
footerClassName,
|
|
20817
|
+
bodyProps,
|
|
20818
|
+
classNames,
|
|
20819
|
+
style,
|
|
20820
|
+
...props
|
|
20821
|
+
}, ref) {
|
|
20822
|
+
const renderBodyWrapper = shouldRenderBodyWrapper({
|
|
20823
|
+
header,
|
|
20824
|
+
footer,
|
|
20825
|
+
bodyAs: BodyComponent === "div" ? void 0 : BodyComponent,
|
|
20826
|
+
bodyClassName,
|
|
20827
|
+
bodyProps,
|
|
20828
|
+
classNames
|
|
20829
|
+
});
|
|
20830
|
+
const { className: bodyPropsClassName, ...restBodyProps } = bodyProps ?? {};
|
|
20831
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
20832
|
+
Component,
|
|
20833
|
+
{
|
|
20834
|
+
ref,
|
|
20835
|
+
"data-workbench-content-pane": true,
|
|
20836
|
+
className: cn(
|
|
20837
|
+
"workbench-surface-subtle flex h-full min-w-0 flex-1 flex-col overflow-hidden rounded-xl border border-border/50 transition-all duration-300 dark:border-border/40",
|
|
20838
|
+
classNames?.root,
|
|
20839
|
+
className
|
|
20840
|
+
),
|
|
20841
|
+
style,
|
|
20842
|
+
...props,
|
|
20843
|
+
children: [
|
|
20844
|
+
header ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: cn("shrink-0 border-b border-border/40 px-4 py-3 dark:border-border/30", classNames?.header, headerClassName), children: header }) : null,
|
|
20845
|
+
renderBodyWrapper ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
20846
|
+
BodyComponent,
|
|
20847
|
+
{
|
|
20848
|
+
className: cn("min-h-0 flex-1 overflow-hidden", classNames?.body, bodyClassName, bodyPropsClassName),
|
|
20849
|
+
...restBodyProps,
|
|
20850
|
+
children
|
|
20851
|
+
}
|
|
20852
|
+
) : children,
|
|
20853
|
+
footer ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: cn("shrink-0 border-t border-border/40 px-4 py-3 dark:border-border/30", classNames?.footer, footerClassName), children: footer }) : null
|
|
20854
|
+
]
|
|
20855
|
+
}
|
|
20856
|
+
);
|
|
20857
|
+
}
|
|
20858
|
+
);
|
|
20859
|
+
var defaultLabels = {
|
|
20860
|
+
settingsButton: "Gallery settings",
|
|
20861
|
+
title: "Gallery settings",
|
|
20862
|
+
visibleColumns: "Visible fields",
|
|
20863
|
+
coverField: "Cover field",
|
|
20864
|
+
autoDetect: "Auto",
|
|
20865
|
+
cardDensity: "Card density",
|
|
20866
|
+
cardColumns: "Cards per row",
|
|
20867
|
+
detailColumns: "Detail columns",
|
|
20868
|
+
fieldVisibility: "Field visibility",
|
|
20869
|
+
fieldLimit: "Field limit",
|
|
20870
|
+
fieldLimitHint: "Uses current field order",
|
|
20871
|
+
layout: "Gallery layout",
|
|
20872
|
+
compact: "Compact",
|
|
20873
|
+
comfortable: "Standard",
|
|
20874
|
+
detailed: "Detailed",
|
|
20875
|
+
autoColumns: "Auto",
|
|
20876
|
+
columns: (count) => `${count}`,
|
|
20877
|
+
bentoColumns: (count) => `${count}`,
|
|
20878
|
+
topLimit: "First fields",
|
|
20879
|
+
allFields: "All fields",
|
|
20880
|
+
adaptiveGrid: "Grid",
|
|
20881
|
+
masonry: "Masonry"
|
|
20882
|
+
};
|
|
20883
|
+
function normalizeColumnKey(column) {
|
|
20884
|
+
return String(column?.key || "");
|
|
20885
|
+
}
|
|
20886
|
+
function getDefaultColumnLabel(column) {
|
|
20887
|
+
return column.label ?? column.key;
|
|
20888
|
+
}
|
|
20889
|
+
function getDefaultVisibleColumnKeys(columns) {
|
|
20890
|
+
return columns.filter((column) => normalizeColumnKey(column) && column.hidden !== true).map((column) => normalizeColumnKey(column));
|
|
20891
|
+
}
|
|
20892
|
+
function getResolvedVisibleColumnKeys({
|
|
20893
|
+
columns,
|
|
20894
|
+
visibleColumnKeys,
|
|
20895
|
+
allowEmptyVisibleColumns
|
|
20896
|
+
}) {
|
|
20897
|
+
const validKeys = new Set(columns.map(normalizeColumnKey).filter(Boolean));
|
|
20898
|
+
const controlledKeys = Array.isArray(visibleColumnKeys) ? visibleColumnKeys.filter((key) => validKeys.has(String(key))) : null;
|
|
20899
|
+
if (controlledKeys && (controlledKeys.length || allowEmptyVisibleColumns)) {
|
|
20900
|
+
return controlledKeys;
|
|
20901
|
+
}
|
|
20902
|
+
return getDefaultVisibleColumnKeys(columns);
|
|
20903
|
+
}
|
|
20904
|
+
function getDefaultDensityOptions(labels) {
|
|
20905
|
+
return [
|
|
20906
|
+
{ value: "compact", label: labels.compact },
|
|
20907
|
+
{ value: "comfortable", label: labels.comfortable },
|
|
20908
|
+
{ value: "detailed", label: labels.detailed }
|
|
20909
|
+
];
|
|
20910
|
+
}
|
|
20911
|
+
function getDefaultGridColumnOptions(labels) {
|
|
20912
|
+
return [
|
|
20913
|
+
{ value: "auto", label: labels.autoColumns },
|
|
20914
|
+
{ value: 1, label: labels.columns(1) },
|
|
20915
|
+
{ value: 2, label: labels.columns(2) },
|
|
20916
|
+
{ value: 3, label: labels.columns(3) },
|
|
20917
|
+
{ value: 4, label: labels.columns(4) }
|
|
20918
|
+
];
|
|
20919
|
+
}
|
|
20920
|
+
function getDefaultBentoColumnOptions(labels) {
|
|
20921
|
+
return [
|
|
20922
|
+
{ value: 1, label: labels.bentoColumns(1) },
|
|
20923
|
+
{ value: 2, label: labels.bentoColumns(2) },
|
|
20924
|
+
{ value: 3, label: labels.bentoColumns(3) }
|
|
20925
|
+
];
|
|
20926
|
+
}
|
|
20927
|
+
function getDefaultDetailVisibilityOptions(labels) {
|
|
20928
|
+
return [
|
|
20929
|
+
{ value: "limit", label: labels.topLimit },
|
|
20930
|
+
{ value: "all", label: labels.allFields }
|
|
20931
|
+
];
|
|
20932
|
+
}
|
|
20933
|
+
function getDefaultLayoutOptions(labels) {
|
|
20934
|
+
return [
|
|
20935
|
+
{ value: "fixed", label: labels.adaptiveGrid },
|
|
20936
|
+
{ value: "masonry", label: labels.masonry }
|
|
20937
|
+
];
|
|
20938
|
+
}
|
|
20939
|
+
function normalizeOptionValue(value) {
|
|
20940
|
+
return String(value);
|
|
20941
|
+
}
|
|
20942
|
+
function getOptionValue(options, rawValue, fallbackValue) {
|
|
20943
|
+
const valueText = String(rawValue ?? fallbackValue);
|
|
20944
|
+
return options.some((option) => String(option.value) === valueText) ? valueText : String(fallbackValue);
|
|
20945
|
+
}
|
|
20946
|
+
function parseNumberOption(value) {
|
|
20947
|
+
const parsed = Number.parseInt(value, 10);
|
|
20948
|
+
return Number.isFinite(parsed) ? parsed : 1;
|
|
20949
|
+
}
|
|
20950
|
+
var compactSegmentedClassNames = {
|
|
20951
|
+
root: "flex w-full flex-wrap",
|
|
20952
|
+
item: "min-w-[58px] flex-1 px-2 text-[11px]",
|
|
20953
|
+
label: "text-[11px]"
|
|
20954
|
+
};
|
|
20955
|
+
function WorkbenchGallerySettingsPanel({
|
|
20956
|
+
columns = [],
|
|
20957
|
+
galleryFieldOptions,
|
|
20958
|
+
value,
|
|
20959
|
+
onValueChange,
|
|
20960
|
+
labels,
|
|
20961
|
+
densityOptions,
|
|
20962
|
+
gridColumnOptions,
|
|
20963
|
+
bentoColumnOptions,
|
|
20964
|
+
detailVisibilityOptions,
|
|
20965
|
+
layoutOptions,
|
|
20966
|
+
getColumnLabel = getDefaultColumnLabel,
|
|
20967
|
+
getColumnDescription,
|
|
20968
|
+
showColumnVisibility = true,
|
|
20969
|
+
showGalleryControls = true,
|
|
20970
|
+
showLayoutControl = true,
|
|
20971
|
+
showGridColumns = true,
|
|
20972
|
+
showDetailColumns = true,
|
|
20973
|
+
allowEmptyVisibleColumns = false,
|
|
20974
|
+
className,
|
|
20975
|
+
classNames
|
|
20976
|
+
}) {
|
|
20977
|
+
const resolvedLabels = { ...defaultLabels, ...labels };
|
|
20978
|
+
const resolvedValue = value || {};
|
|
20979
|
+
const resolvedColumns = columns.filter((column) => normalizeColumnKey(column));
|
|
20980
|
+
const resolvedVisibleColumnKeys = getResolvedVisibleColumnKeys({
|
|
20981
|
+
columns: resolvedColumns,
|
|
20982
|
+
visibleColumnKeys: resolvedValue.visibleColumnKeys,
|
|
20983
|
+
allowEmptyVisibleColumns
|
|
20984
|
+
});
|
|
20985
|
+
const visibleColumnKeySet = new Set(resolvedVisibleColumnKeys);
|
|
20986
|
+
const resolvedGalleryFieldOptions = (galleryFieldOptions || resolvedColumns).filter((column) => normalizeColumnKey(column));
|
|
20987
|
+
const resolvedDensityOptions = densityOptions || getDefaultDensityOptions(resolvedLabels);
|
|
20988
|
+
const resolvedGridColumnOptions = gridColumnOptions || getDefaultGridColumnOptions(resolvedLabels);
|
|
20989
|
+
const resolvedBentoColumnOptions = bentoColumnOptions || getDefaultBentoColumnOptions(resolvedLabels);
|
|
20990
|
+
const resolvedDetailVisibilityOptions = detailVisibilityOptions || getDefaultDetailVisibilityOptions(resolvedLabels);
|
|
20991
|
+
const resolvedLayoutOptions = layoutOptions || getDefaultLayoutOptions(resolvedLabels);
|
|
20992
|
+
const canUpdate = typeof onValueChange === "function";
|
|
20993
|
+
const updateValue = (patch) => {
|
|
20994
|
+
onValueChange?.({ ...resolvedValue, ...patch }, patch);
|
|
20995
|
+
};
|
|
20996
|
+
const toggleColumn = (columnKey) => {
|
|
20997
|
+
if (!canUpdate) return;
|
|
20998
|
+
const nextVisibleSet = new Set(resolvedVisibleColumnKeys);
|
|
20999
|
+
if (nextVisibleSet.has(columnKey)) {
|
|
21000
|
+
nextVisibleSet.delete(columnKey);
|
|
21001
|
+
} else {
|
|
21002
|
+
nextVisibleSet.add(columnKey);
|
|
21003
|
+
}
|
|
21004
|
+
let nextVisibleColumnKeys = resolvedColumns.map(normalizeColumnKey).filter((key) => nextVisibleSet.has(key));
|
|
21005
|
+
if (!nextVisibleColumnKeys.length && !allowEmptyVisibleColumns) {
|
|
21006
|
+
nextVisibleColumnKeys = [columnKey];
|
|
21007
|
+
}
|
|
21008
|
+
updateValue({ visibleColumnKeys: nextVisibleColumnKeys });
|
|
21009
|
+
};
|
|
21010
|
+
const shouldRenderColumnVisibility = showColumnVisibility && resolvedColumns.length > 0;
|
|
21011
|
+
const shouldRenderGalleryControls = showGalleryControls;
|
|
21012
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cn("space-y-3 text-foreground", classNames?.root, className), children: [
|
|
21013
|
+
shouldRenderColumnVisibility ? /* @__PURE__ */ jsxRuntime.jsxs("section", { className: cn("space-y-2", classNames?.section), children: [
|
|
21014
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: cn("text-[10px] font-medium uppercase tracking-wide text-muted-foreground", classNames?.sectionHeader), children: resolvedLabels.visibleColumns }),
|
|
21015
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: cn("max-h-[220px] space-y-1 overflow-y-auto pr-1", classNames?.columnList), children: resolvedColumns.map((column) => {
|
|
21016
|
+
const columnKey = normalizeColumnKey(column);
|
|
21017
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
21018
|
+
BaseCheckbox,
|
|
21019
|
+
{
|
|
21020
|
+
checked: visibleColumnKeySet.has(columnKey),
|
|
21021
|
+
disabled: !canUpdate,
|
|
21022
|
+
label: getColumnLabel(column),
|
|
21023
|
+
description: getColumnDescription?.(column),
|
|
21024
|
+
onChange: () => toggleColumn(columnKey),
|
|
21025
|
+
className: cn("flex w-full rounded-lg px-2 py-1.5 hover:bg-muted/50", classNames?.columnItem)
|
|
21026
|
+
},
|
|
21027
|
+
`workbench-gallery-column-${columnKey}`
|
|
21028
|
+
);
|
|
21029
|
+
}) })
|
|
21030
|
+
] }) : null,
|
|
21031
|
+
shouldRenderGalleryControls ? /* @__PURE__ */ jsxRuntime.jsxs("section", { className: cn("space-y-3 border-t border-border/60 pt-3", classNames?.section), children: [
|
|
21032
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
21033
|
+
BaseField,
|
|
21034
|
+
{
|
|
21035
|
+
label: resolvedLabels.coverField,
|
|
21036
|
+
classNames: {
|
|
21037
|
+
label: "text-[10px] uppercase tracking-wide text-muted-foreground"
|
|
21038
|
+
},
|
|
21039
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
21040
|
+
BaseSelect,
|
|
21041
|
+
{
|
|
21042
|
+
value: String(resolvedValue.galleryFieldKey || "auto"),
|
|
21043
|
+
options: [
|
|
21044
|
+
{ value: "auto", label: resolvedLabels.autoDetect },
|
|
21045
|
+
...resolvedGalleryFieldOptions.map((column) => ({
|
|
21046
|
+
value: normalizeColumnKey(column),
|
|
21047
|
+
label: getColumnLabel(column)
|
|
21048
|
+
}))
|
|
21049
|
+
],
|
|
21050
|
+
disabled: !canUpdate,
|
|
21051
|
+
onChange: (event) => updateValue({ galleryFieldKey: event.currentTarget.value || "auto" }),
|
|
21052
|
+
className: classNames?.control
|
|
21053
|
+
}
|
|
21054
|
+
)
|
|
21055
|
+
}
|
|
21056
|
+
),
|
|
21057
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
21058
|
+
BaseField,
|
|
21059
|
+
{
|
|
21060
|
+
label: resolvedLabels.cardDensity,
|
|
21061
|
+
classNames: {
|
|
21062
|
+
label: "text-[10px] uppercase tracking-wide text-muted-foreground"
|
|
21063
|
+
},
|
|
21064
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
21065
|
+
BaseSegmentedControl,
|
|
21066
|
+
{
|
|
21067
|
+
value: getOptionValue(resolvedDensityOptions, resolvedValue.galleryDensity, "comfortable"),
|
|
21068
|
+
options: resolvedDensityOptions.map((option) => ({
|
|
21069
|
+
value: normalizeOptionValue(option.value),
|
|
21070
|
+
label: option.label,
|
|
21071
|
+
disabled: option.disabled
|
|
21072
|
+
})),
|
|
21073
|
+
onValueChange: (nextValue) => updateValue({ galleryDensity: nextValue }),
|
|
21074
|
+
className: cn("w-full", classNames?.control),
|
|
21075
|
+
classNames: compactSegmentedClassNames
|
|
21076
|
+
}
|
|
21077
|
+
)
|
|
21078
|
+
}
|
|
21079
|
+
),
|
|
21080
|
+
showGridColumns ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
21081
|
+
BaseField,
|
|
21082
|
+
{
|
|
21083
|
+
label: resolvedLabels.cardColumns,
|
|
21084
|
+
classNames: {
|
|
21085
|
+
label: "text-[10px] uppercase tracking-wide text-muted-foreground"
|
|
21086
|
+
},
|
|
21087
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
21088
|
+
BaseSegmentedControl,
|
|
21089
|
+
{
|
|
21090
|
+
value: getOptionValue(resolvedGridColumnOptions, resolvedValue.galleryGridColumns, "auto"),
|
|
21091
|
+
options: resolvedGridColumnOptions.map((option) => ({
|
|
21092
|
+
value: normalizeOptionValue(option.value),
|
|
21093
|
+
label: option.label,
|
|
21094
|
+
disabled: option.disabled
|
|
21095
|
+
})),
|
|
21096
|
+
onValueChange: (nextValue) => updateValue({
|
|
21097
|
+
galleryGridColumns: nextValue === "auto" ? "auto" : parseNumberOption(nextValue)
|
|
21098
|
+
}),
|
|
21099
|
+
className: cn("w-full", classNames?.control),
|
|
21100
|
+
classNames: compactSegmentedClassNames
|
|
21101
|
+
}
|
|
21102
|
+
)
|
|
21103
|
+
}
|
|
21104
|
+
) : null,
|
|
21105
|
+
showDetailColumns ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
21106
|
+
BaseField,
|
|
21107
|
+
{
|
|
21108
|
+
label: resolvedLabels.detailColumns,
|
|
21109
|
+
classNames: {
|
|
21110
|
+
label: "text-[10px] uppercase tracking-wide text-muted-foreground"
|
|
21111
|
+
},
|
|
21112
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
21113
|
+
BaseSegmentedControl,
|
|
21114
|
+
{
|
|
21115
|
+
value: getOptionValue(resolvedBentoColumnOptions, resolvedValue.galleryBentoColumns, 2),
|
|
21116
|
+
options: resolvedBentoColumnOptions.map((option) => ({
|
|
21117
|
+
value: normalizeOptionValue(option.value),
|
|
21118
|
+
label: option.label,
|
|
21119
|
+
disabled: option.disabled
|
|
21120
|
+
})),
|
|
21121
|
+
onValueChange: (nextValue) => updateValue({ galleryBentoColumns: parseNumberOption(nextValue) }),
|
|
21122
|
+
className: cn("w-full", classNames?.control),
|
|
21123
|
+
classNames: compactSegmentedClassNames
|
|
21124
|
+
}
|
|
21125
|
+
)
|
|
21126
|
+
}
|
|
21127
|
+
) : null,
|
|
21128
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
21129
|
+
BaseField,
|
|
21130
|
+
{
|
|
21131
|
+
label: resolvedLabels.fieldVisibility,
|
|
21132
|
+
classNames: {
|
|
21133
|
+
label: "text-[10px] uppercase tracking-wide text-muted-foreground"
|
|
21134
|
+
},
|
|
21135
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
21136
|
+
BaseSegmentedControl,
|
|
21137
|
+
{
|
|
21138
|
+
value: getOptionValue(resolvedDetailVisibilityOptions, resolvedValue.galleryDetailVisibility, "limit"),
|
|
21139
|
+
options: resolvedDetailVisibilityOptions.map((option) => ({
|
|
21140
|
+
value: normalizeOptionValue(option.value),
|
|
21141
|
+
label: option.label,
|
|
21142
|
+
disabled: option.disabled
|
|
21143
|
+
})),
|
|
21144
|
+
onValueChange: (nextValue) => updateValue({ galleryDetailVisibility: nextValue }),
|
|
21145
|
+
className: cn("w-full", classNames?.control),
|
|
21146
|
+
classNames: compactSegmentedClassNames
|
|
21147
|
+
}
|
|
21148
|
+
)
|
|
21149
|
+
}
|
|
21150
|
+
),
|
|
21151
|
+
resolvedValue.galleryDetailVisibility !== "all" ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
21152
|
+
BaseField,
|
|
21153
|
+
{
|
|
21154
|
+
label: resolvedLabels.fieldLimit,
|
|
21155
|
+
description: resolvedLabels.fieldLimitHint,
|
|
21156
|
+
classNames: {
|
|
21157
|
+
label: "text-[10px] uppercase tracking-wide text-muted-foreground",
|
|
21158
|
+
description: "text-[10px]"
|
|
21159
|
+
},
|
|
21160
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
21161
|
+
BaseInput,
|
|
21162
|
+
{
|
|
21163
|
+
type: "number",
|
|
21164
|
+
min: 1,
|
|
21165
|
+
step: 1,
|
|
21166
|
+
value: String(resolvedValue.galleryDetailLimit || 4),
|
|
21167
|
+
disabled: !canUpdate,
|
|
21168
|
+
onChange: (event) => updateValue({ galleryDetailLimit: event.currentTarget.value }),
|
|
21169
|
+
className: classNames?.control
|
|
21170
|
+
}
|
|
21171
|
+
)
|
|
21172
|
+
}
|
|
21173
|
+
) : null,
|
|
21174
|
+
showLayoutControl ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
21175
|
+
BaseField,
|
|
21176
|
+
{
|
|
21177
|
+
label: resolvedLabels.layout,
|
|
21178
|
+
classNames: {
|
|
21179
|
+
label: "text-[10px] uppercase tracking-wide text-muted-foreground"
|
|
21180
|
+
},
|
|
21181
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
21182
|
+
BaseSegmentedControl,
|
|
21183
|
+
{
|
|
21184
|
+
value: getOptionValue(resolvedLayoutOptions, resolvedValue.galleryLayout, "fixed"),
|
|
21185
|
+
options: resolvedLayoutOptions.map((option) => ({
|
|
21186
|
+
value: normalizeOptionValue(option.value),
|
|
21187
|
+
label: option.label,
|
|
21188
|
+
disabled: option.disabled
|
|
21189
|
+
})),
|
|
21190
|
+
onValueChange: (nextValue) => updateValue({ galleryLayout: nextValue }),
|
|
21191
|
+
className: cn("w-full", classNames?.control),
|
|
21192
|
+
classNames: compactSegmentedClassNames
|
|
21193
|
+
}
|
|
21194
|
+
)
|
|
21195
|
+
}
|
|
21196
|
+
) : null
|
|
21197
|
+
] }) : null
|
|
21198
|
+
] });
|
|
21199
|
+
}
|
|
21200
|
+
function WorkbenchGallerySettingsButton({
|
|
21201
|
+
open,
|
|
21202
|
+
defaultOpen = false,
|
|
21203
|
+
onOpenChange,
|
|
21204
|
+
triggerIcon,
|
|
21205
|
+
triggerLabel,
|
|
21206
|
+
triggerTitle,
|
|
21207
|
+
align = "end",
|
|
21208
|
+
popoverWidth = 320,
|
|
21209
|
+
panelHeader,
|
|
21210
|
+
panelBefore,
|
|
21211
|
+
panelAfter,
|
|
21212
|
+
panelClassName,
|
|
21213
|
+
buttonClassName,
|
|
21214
|
+
popoverClassName,
|
|
21215
|
+
buttonClassNames,
|
|
21216
|
+
labels,
|
|
21217
|
+
className,
|
|
21218
|
+
classNames,
|
|
21219
|
+
...panelProps
|
|
21220
|
+
}) {
|
|
21221
|
+
const resolvedLabels = { ...defaultLabels, ...labels };
|
|
21222
|
+
const rootRef = React.useRef(null);
|
|
21223
|
+
const [uncontrolledOpen, setUncontrolledOpen] = React.useState(defaultOpen);
|
|
21224
|
+
const [popoverStyle, setPopoverStyle] = React.useState({});
|
|
21225
|
+
const isControlled = open !== void 0;
|
|
21226
|
+
const isOpen = isControlled ? Boolean(open) : uncontrolledOpen;
|
|
21227
|
+
const setOpen = (nextOpen) => {
|
|
21228
|
+
if (!isControlled) {
|
|
21229
|
+
setUncontrolledOpen(nextOpen);
|
|
21230
|
+
}
|
|
21231
|
+
onOpenChange?.(nextOpen);
|
|
21232
|
+
};
|
|
21233
|
+
React.useLayoutEffect(() => {
|
|
21234
|
+
if (!isOpen) return void 0;
|
|
21235
|
+
const updatePopoverPosition = () => {
|
|
21236
|
+
const triggerRect = rootRef.current?.getBoundingClientRect();
|
|
21237
|
+
if (!triggerRect || typeof window === "undefined") return;
|
|
21238
|
+
const viewportPadding = 12;
|
|
21239
|
+
const availableWidth = Math.max(window.innerWidth - viewportPadding * 2, 0);
|
|
21240
|
+
const resolvedWidth = Math.min(popoverWidth, availableWidth || popoverWidth);
|
|
21241
|
+
const preferredLeft = align === "start" ? triggerRect.left : triggerRect.right - resolvedWidth;
|
|
21242
|
+
const left = Math.min(
|
|
21243
|
+
Math.max(preferredLeft, viewportPadding),
|
|
21244
|
+
Math.max(window.innerWidth - resolvedWidth - viewportPadding, viewportPadding)
|
|
21245
|
+
);
|
|
21246
|
+
const top = Math.min(
|
|
21247
|
+
triggerRect.bottom + 8,
|
|
21248
|
+
Math.max(window.innerHeight - 80, viewportPadding)
|
|
21249
|
+
);
|
|
21250
|
+
setPopoverStyle({
|
|
21251
|
+
left,
|
|
21252
|
+
top,
|
|
21253
|
+
width: resolvedWidth,
|
|
21254
|
+
maxHeight: `calc(100vh - ${Math.round(top + viewportPadding)}px)`
|
|
21255
|
+
});
|
|
21256
|
+
};
|
|
21257
|
+
const handlePointerDown = (event) => {
|
|
21258
|
+
if (!rootRef.current?.contains(event.target)) {
|
|
21259
|
+
setOpen(false);
|
|
21260
|
+
}
|
|
21261
|
+
};
|
|
21262
|
+
const handleKeyDown = (event) => {
|
|
21263
|
+
if (event.key === "Escape") setOpen(false);
|
|
21264
|
+
};
|
|
21265
|
+
updatePopoverPosition();
|
|
21266
|
+
window.addEventListener("resize", updatePopoverPosition);
|
|
21267
|
+
window.addEventListener("scroll", updatePopoverPosition, true);
|
|
21268
|
+
window.addEventListener("pointerdown", handlePointerDown);
|
|
21269
|
+
window.addEventListener("keydown", handleKeyDown);
|
|
21270
|
+
return () => {
|
|
21271
|
+
window.removeEventListener("resize", updatePopoverPosition);
|
|
21272
|
+
window.removeEventListener("scroll", updatePopoverPosition, true);
|
|
21273
|
+
window.removeEventListener("pointerdown", handlePointerDown);
|
|
21274
|
+
window.removeEventListener("keydown", handleKeyDown);
|
|
21275
|
+
};
|
|
21276
|
+
}, [align, isOpen, popoverWidth]);
|
|
21277
|
+
const resolvedTriggerLabel = triggerLabel ?? resolvedLabels.settingsButton;
|
|
21278
|
+
const resolvedPanelHeader = panelHeader ?? resolvedLabels.title;
|
|
21279
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { ref: rootRef, className: cn("relative inline-flex", buttonClassNames?.root, className), children: [
|
|
21280
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
21281
|
+
BaseButton,
|
|
21282
|
+
{
|
|
21283
|
+
icon: triggerIcon,
|
|
21284
|
+
label: resolvedTriggerLabel,
|
|
21285
|
+
title: triggerTitle || (typeof resolvedTriggerLabel === "string" ? resolvedTriggerLabel : void 0),
|
|
21286
|
+
iconOnly: Boolean(triggerIcon),
|
|
21287
|
+
active: isOpen,
|
|
21288
|
+
tone: "muted",
|
|
21289
|
+
"aria-haspopup": "dialog",
|
|
21290
|
+
"aria-expanded": isOpen,
|
|
21291
|
+
className: cn(buttonClassNames?.trigger, buttonClassName),
|
|
21292
|
+
onClick: () => setOpen(!isOpen)
|
|
21293
|
+
}
|
|
21294
|
+
),
|
|
21295
|
+
isOpen ? /* @__PURE__ */ jsxRuntime.jsxs(
|
|
21296
|
+
"div",
|
|
21297
|
+
{
|
|
21298
|
+
role: "dialog",
|
|
21299
|
+
"aria-label": typeof resolvedPanelHeader === "string" ? resolvedPanelHeader : void 0,
|
|
21300
|
+
className: cn(
|
|
21301
|
+
"fixed z-50 overflow-y-auto rounded-xl border border-border bg-card p-3 text-foreground shadow-lg",
|
|
21302
|
+
align === "start" ? "origin-top-left" : "origin-top-right",
|
|
21303
|
+
buttonClassNames?.popover,
|
|
21304
|
+
popoverClassName
|
|
21305
|
+
),
|
|
21306
|
+
style: popoverStyle,
|
|
21307
|
+
children: [
|
|
21308
|
+
resolvedPanelHeader ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: cn("mb-3 text-[11px] font-medium text-foreground", buttonClassNames?.header), children: resolvedPanelHeader }) : null,
|
|
21309
|
+
panelBefore,
|
|
21310
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
21311
|
+
WorkbenchGallerySettingsPanel,
|
|
21312
|
+
{
|
|
21313
|
+
...panelProps,
|
|
21314
|
+
labels: resolvedLabels,
|
|
21315
|
+
className: cn(buttonClassNames?.panel, panelClassName),
|
|
21316
|
+
classNames
|
|
21317
|
+
}
|
|
21318
|
+
),
|
|
21319
|
+
panelAfter
|
|
21320
|
+
]
|
|
21321
|
+
}
|
|
21322
|
+
) : null
|
|
21323
|
+
] });
|
|
21324
|
+
}
|
|
21325
|
+
function TableViewIcon() {
|
|
21326
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("svg", { "aria-hidden": "true", viewBox: "0 0 24 24", className: "h-3.5 w-3.5", fill: "none", stroke: "currentColor", strokeWidth: "2", children: [
|
|
21327
|
+
/* @__PURE__ */ jsxRuntime.jsx("rect", { x: "3", y: "4", width: "18", height: "16", rx: "2" }),
|
|
21328
|
+
/* @__PURE__ */ jsxRuntime.jsx("path", { d: "M3 10h18M9 4v16" })
|
|
21329
|
+
] });
|
|
21330
|
+
}
|
|
21331
|
+
function GalleryViewIcon() {
|
|
21332
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("svg", { "aria-hidden": "true", viewBox: "0 0 24 24", className: "h-3.5 w-3.5", fill: "none", stroke: "currentColor", strokeWidth: "2", children: [
|
|
21333
|
+
/* @__PURE__ */ jsxRuntime.jsx("rect", { x: "3", y: "3", width: "7", height: "7", rx: "1.5" }),
|
|
21334
|
+
/* @__PURE__ */ jsxRuntime.jsx("rect", { x: "14", y: "3", width: "7", height: "7", rx: "1.5" }),
|
|
21335
|
+
/* @__PURE__ */ jsxRuntime.jsx("rect", { x: "3", y: "14", width: "7", height: "7", rx: "1.5" }),
|
|
21336
|
+
/* @__PURE__ */ jsxRuntime.jsx("rect", { x: "14", y: "14", width: "7", height: "7", rx: "1.5" })
|
|
21337
|
+
] });
|
|
21338
|
+
}
|
|
21339
|
+
function SettingsIcon() {
|
|
21340
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("svg", { "aria-hidden": "true", viewBox: "0 0 24 24", className: "h-3.5 w-3.5", fill: "none", stroke: "currentColor", strokeWidth: "2", children: [
|
|
21341
|
+
/* @__PURE__ */ jsxRuntime.jsx("path", { d: "M20 7h-9M7 7H4M14 17H4M20 17h-3" }),
|
|
21342
|
+
/* @__PURE__ */ jsxRuntime.jsx("circle", { cx: "9", cy: "7", r: "2" }),
|
|
21343
|
+
/* @__PURE__ */ jsxRuntime.jsx("circle", { cx: "16", cy: "17", r: "2" })
|
|
21344
|
+
] });
|
|
21345
|
+
}
|
|
21346
|
+
function ChevronDownIcon3({ open }) {
|
|
21347
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
21348
|
+
"svg",
|
|
21349
|
+
{
|
|
21350
|
+
"aria-hidden": "true",
|
|
21351
|
+
viewBox: "0 0 24 24",
|
|
21352
|
+
className: cn("h-3 w-3 opacity-55 transition-transform", open && "rotate-180"),
|
|
21353
|
+
fill: "none",
|
|
21354
|
+
stroke: "currentColor",
|
|
21355
|
+
strokeWidth: "2",
|
|
21356
|
+
children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "m6 9 6 6 6-6" })
|
|
21357
|
+
}
|
|
21358
|
+
);
|
|
21359
|
+
}
|
|
21360
|
+
var defaultViewModeOptions = [
|
|
21361
|
+
{ value: "list", label: "Table view", icon: /* @__PURE__ */ jsxRuntime.jsx(TableViewIcon, {}) },
|
|
21362
|
+
{ value: "gallery", label: "Gallery view", icon: /* @__PURE__ */ jsxRuntime.jsx(GalleryViewIcon, {}) }
|
|
21363
|
+
];
|
|
21364
|
+
function getViewModeOptionIcon(option) {
|
|
21365
|
+
if (option.icon !== void 0) return option.icon;
|
|
21366
|
+
if (option.value === "list" || option.value === "table") return /* @__PURE__ */ jsxRuntime.jsx(TableViewIcon, {});
|
|
21367
|
+
if (option.value === "gallery") return /* @__PURE__ */ jsxRuntime.jsx(GalleryViewIcon, {});
|
|
21368
|
+
return null;
|
|
21369
|
+
}
|
|
21370
|
+
function getSettingsTriggerLabel(settings) {
|
|
21371
|
+
return settings.triggerLabel ?? settings.labels?.settingsButton ?? "Settings";
|
|
21372
|
+
}
|
|
21373
|
+
function WorkbenchContentToolbarViewModeControl({
|
|
21374
|
+
value,
|
|
21375
|
+
options,
|
|
21376
|
+
onValueChange,
|
|
21377
|
+
classNames
|
|
21378
|
+
}) {
|
|
21379
|
+
const rootRef = React.useRef(null);
|
|
21380
|
+
const [open, setOpen] = React.useState(false);
|
|
21381
|
+
const activeOption = options.find((option) => option.value === value) || options.find((option) => !option.disabled) || options[0];
|
|
21382
|
+
const activeIcon = activeOption ? getViewModeOptionIcon(activeOption) : null;
|
|
21383
|
+
React.useEffect(() => {
|
|
21384
|
+
if (!open) return void 0;
|
|
21385
|
+
const handlePointerDown = (event) => {
|
|
21386
|
+
if (!rootRef.current?.contains(event.target)) {
|
|
21387
|
+
setOpen(false);
|
|
21388
|
+
}
|
|
21389
|
+
};
|
|
21390
|
+
const handleKeyDown = (event) => {
|
|
21391
|
+
if (event.key === "Escape") setOpen(false);
|
|
21392
|
+
};
|
|
21393
|
+
window.addEventListener("pointerdown", handlePointerDown);
|
|
21394
|
+
window.addEventListener("keydown", handleKeyDown);
|
|
21395
|
+
return () => {
|
|
21396
|
+
window.removeEventListener("pointerdown", handlePointerDown);
|
|
21397
|
+
window.removeEventListener("keydown", handleKeyDown);
|
|
21398
|
+
};
|
|
21399
|
+
}, [open]);
|
|
21400
|
+
if (!activeOption) return null;
|
|
21401
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { ref: rootRef, className: cn("relative inline-flex", classNames?.viewModeRoot), children: [
|
|
21402
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
21403
|
+
"button",
|
|
21404
|
+
{
|
|
21405
|
+
type: "button",
|
|
21406
|
+
"aria-haspopup": "listbox",
|
|
21407
|
+
"aria-expanded": open,
|
|
21408
|
+
className: cn(
|
|
21409
|
+
"inline-flex h-7 min-w-0 items-center justify-center gap-1.5 rounded-md border border-border/70 bg-card px-2 text-xs font-medium text-foreground shadow-none transition-colors hover:bg-muted/50 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary/25",
|
|
21410
|
+
classNames?.viewModeTrigger
|
|
21411
|
+
),
|
|
21412
|
+
onClick: () => setOpen((current) => !current),
|
|
21413
|
+
children: [
|
|
21414
|
+
activeIcon ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "inline-flex h-3.5 w-3.5 shrink-0 items-center justify-center text-muted-foreground", children: activeIcon }) : null,
|
|
21415
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "min-w-0 truncate", children: activeOption.label }),
|
|
21416
|
+
/* @__PURE__ */ jsxRuntime.jsx(ChevronDownIcon3, { open })
|
|
21417
|
+
]
|
|
21418
|
+
}
|
|
21419
|
+
),
|
|
21420
|
+
open ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
21421
|
+
"div",
|
|
21422
|
+
{
|
|
21423
|
+
role: "listbox",
|
|
21424
|
+
className: cn(
|
|
21425
|
+
"absolute left-0 top-full z-50 mt-2 min-w-[160px] overflow-hidden rounded-xl border border-border/60 bg-card/95 p-1.5 text-xs text-foreground shadow-lg backdrop-blur-xl",
|
|
21426
|
+
classNames?.viewModeMenu
|
|
21427
|
+
),
|
|
21428
|
+
children: options.map((option) => {
|
|
21429
|
+
const selected = option.value === activeOption.value;
|
|
21430
|
+
const optionIcon = getViewModeOptionIcon(option);
|
|
21431
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
21432
|
+
"button",
|
|
21433
|
+
{
|
|
21434
|
+
type: "button",
|
|
21435
|
+
role: "option",
|
|
21436
|
+
"aria-selected": selected,
|
|
21437
|
+
disabled: option.disabled,
|
|
21438
|
+
className: cn(
|
|
21439
|
+
"flex min-h-8 w-full items-center gap-2 rounded-lg px-2.5 py-1.5 text-left text-xs font-medium text-muted-foreground transition-colors hover:bg-muted/55 hover:text-foreground disabled:cursor-not-allowed disabled:opacity-50",
|
|
21440
|
+
selected && "bg-muted/60 text-foreground",
|
|
21441
|
+
classNames?.viewModeItem
|
|
21442
|
+
),
|
|
21443
|
+
onClick: () => {
|
|
21444
|
+
if (option.disabled) return;
|
|
21445
|
+
onValueChange?.(option.value, option);
|
|
21446
|
+
setOpen(false);
|
|
21447
|
+
},
|
|
21448
|
+
children: [
|
|
21449
|
+
optionIcon ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "inline-flex h-3.5 w-3.5 shrink-0 items-center justify-center", children: optionIcon }) : null,
|
|
21450
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "min-w-0 truncate", children: option.label })
|
|
21451
|
+
]
|
|
21452
|
+
},
|
|
21453
|
+
option.value
|
|
21454
|
+
);
|
|
21455
|
+
})
|
|
21456
|
+
}
|
|
21457
|
+
) : null
|
|
21458
|
+
] });
|
|
21459
|
+
}
|
|
21460
|
+
var WorkbenchContentToolbar = React.forwardRef(
|
|
21461
|
+
function WorkbenchContentToolbar2({
|
|
21462
|
+
as: Component = "div",
|
|
21463
|
+
children,
|
|
21464
|
+
end,
|
|
21465
|
+
viewMode,
|
|
21466
|
+
viewModeOptions,
|
|
21467
|
+
onViewModeChange,
|
|
21468
|
+
gallerySettings,
|
|
21469
|
+
gallerySettingsPlacement = "start",
|
|
21470
|
+
className,
|
|
21471
|
+
startClassName,
|
|
21472
|
+
endClassName,
|
|
21473
|
+
classNames,
|
|
21474
|
+
...props
|
|
21475
|
+
}, ref) {
|
|
21476
|
+
const resolvedViewModeOptions = viewModeOptions || (viewMode ? defaultViewModeOptions : []);
|
|
21477
|
+
const resolvedGallerySettings = gallerySettings && typeof gallerySettings === "object" ? gallerySettings : null;
|
|
21478
|
+
const shouldRenderViewMode = Boolean(resolvedViewModeOptions.length);
|
|
21479
|
+
const shouldRenderSettings = Boolean(resolvedGallerySettings);
|
|
21480
|
+
const shouldRenderSettingsInStart = shouldRenderSettings && gallerySettingsPlacement !== "end";
|
|
21481
|
+
const shouldRenderSettingsInEnd = shouldRenderSettings && gallerySettingsPlacement === "end";
|
|
21482
|
+
const shouldRenderStart = shouldRenderViewMode || shouldRenderSettingsInStart || Boolean(children);
|
|
21483
|
+
const shouldRenderEnd = Boolean(end) || shouldRenderSettingsInEnd;
|
|
21484
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
21485
|
+
Component,
|
|
21486
|
+
{
|
|
21487
|
+
ref,
|
|
21488
|
+
"data-workbench-content-toolbar": true,
|
|
21489
|
+
className: cn(
|
|
21490
|
+
"flex min-h-[46px] shrink-0 flex-col gap-2 border-b border-border/60 px-4 py-2 md:flex-row md:items-center md:justify-between",
|
|
21491
|
+
classNames?.root,
|
|
21492
|
+
className
|
|
21493
|
+
),
|
|
21494
|
+
...props,
|
|
21495
|
+
children: [
|
|
21496
|
+
shouldRenderStart ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cn("flex flex-wrap items-center gap-2", classNames?.start, startClassName), children: [
|
|
21497
|
+
shouldRenderViewMode ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
21498
|
+
WorkbenchContentToolbarViewModeControl,
|
|
21499
|
+
{
|
|
21500
|
+
value: viewMode,
|
|
21501
|
+
options: resolvedViewModeOptions,
|
|
21502
|
+
onValueChange: onViewModeChange,
|
|
21503
|
+
classNames
|
|
21504
|
+
}
|
|
21505
|
+
) : null,
|
|
21506
|
+
shouldRenderSettingsInStart && resolvedGallerySettings ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
21507
|
+
WorkbenchGallerySettingsButton,
|
|
21508
|
+
{
|
|
21509
|
+
align: "end",
|
|
21510
|
+
triggerIcon: /* @__PURE__ */ jsxRuntime.jsx(SettingsIcon, {}),
|
|
21511
|
+
triggerLabel: getSettingsTriggerLabel(resolvedGallerySettings),
|
|
21512
|
+
...resolvedGallerySettings,
|
|
21513
|
+
buttonClassName: cn(
|
|
21514
|
+
"!h-7 !w-7 !min-h-0 !rounded-md !p-0 text-xs",
|
|
21515
|
+
classNames?.settings,
|
|
21516
|
+
resolvedGallerySettings.buttonClassName
|
|
21517
|
+
)
|
|
21518
|
+
}
|
|
21519
|
+
) : null,
|
|
21520
|
+
children
|
|
21521
|
+
] }) : null,
|
|
21522
|
+
shouldRenderEnd ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cn("flex shrink-0 items-center gap-2", classNames?.end, endClassName), children: [
|
|
21523
|
+
end,
|
|
21524
|
+
shouldRenderSettingsInEnd && resolvedGallerySettings ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
21525
|
+
WorkbenchGallerySettingsButton,
|
|
21526
|
+
{
|
|
21527
|
+
align: "end",
|
|
21528
|
+
triggerIcon: /* @__PURE__ */ jsxRuntime.jsx(SettingsIcon, {}),
|
|
21529
|
+
triggerLabel: getSettingsTriggerLabel(resolvedGallerySettings),
|
|
21530
|
+
...resolvedGallerySettings,
|
|
21531
|
+
buttonClassName: cn(
|
|
21532
|
+
"!h-7 !w-7 !min-h-0 !rounded-md !p-0 text-xs",
|
|
21533
|
+
classNames?.settings,
|
|
21534
|
+
resolvedGallerySettings.buttonClassName
|
|
21535
|
+
)
|
|
21536
|
+
}
|
|
21537
|
+
) : null
|
|
21538
|
+
] }) : null
|
|
21539
|
+
]
|
|
21540
|
+
}
|
|
21541
|
+
);
|
|
21542
|
+
}
|
|
21543
|
+
);
|
|
21544
|
+
function shouldRenderBodyWrapper2(props) {
|
|
21545
|
+
return Boolean(
|
|
21546
|
+
props.header || props.footer || props.bodyAs || props.bodyClassName || props.bodyProps || props.classNames?.body
|
|
21547
|
+
);
|
|
21548
|
+
}
|
|
21549
|
+
function hasRenderableChildren(children) {
|
|
21550
|
+
if (children === null || children === void 0 || typeof children === "boolean") return false;
|
|
21551
|
+
if (typeof children === "string") return children.trim().length > 0;
|
|
21552
|
+
if (Array.isArray(children)) return children.some(hasRenderableChildren);
|
|
21553
|
+
const childList = React.Children.toArray(children);
|
|
21554
|
+
if (!childList.length) return false;
|
|
21555
|
+
return childList.some((child) => typeof child === "string" ? child.trim().length > 0 : true);
|
|
21556
|
+
}
|
|
21557
|
+
function resolveWidthStyle(open, width) {
|
|
21558
|
+
if (width === void 0) return {};
|
|
21559
|
+
if (open === void 0) return { width };
|
|
21560
|
+
return {
|
|
21561
|
+
width: open ? width : 0,
|
|
21562
|
+
opacity: open ? 1 : 0
|
|
21563
|
+
};
|
|
21564
|
+
}
|
|
21565
|
+
function getFallbackFieldLabel(field) {
|
|
21566
|
+
return field.label ?? field.key;
|
|
21567
|
+
}
|
|
21568
|
+
function getObjectDisplayValue(value) {
|
|
21569
|
+
const displayKeys = ["text", "label", "title", "display", "value", "recordId"];
|
|
21570
|
+
for (const key of displayKeys) {
|
|
21571
|
+
if (!Object.prototype.hasOwnProperty.call(value, key)) continue;
|
|
21572
|
+
const displayValue = value[key];
|
|
21573
|
+
if (displayValue !== null && displayValue !== void 0 && displayValue !== "") {
|
|
21574
|
+
return displayValue;
|
|
21575
|
+
}
|
|
21576
|
+
}
|
|
21577
|
+
return void 0;
|
|
21578
|
+
}
|
|
21579
|
+
function isEmptyDetailValue(value) {
|
|
21580
|
+
return value === null || value === void 0 || value === "";
|
|
21581
|
+
}
|
|
21582
|
+
function isPlainDisplayValue(value) {
|
|
21583
|
+
return ["string", "number", "boolean"].includes(typeof value);
|
|
21584
|
+
}
|
|
21585
|
+
function getMediaDisplayData(value) {
|
|
21586
|
+
if (!value) return null;
|
|
21587
|
+
if (typeof value === "string") {
|
|
21588
|
+
const isDataImage = value.startsWith("data:image/");
|
|
21589
|
+
const isImageUrl = /\.(avif|gif|jpe?g|png|svg|webp)(\?.*)?$/i.test(value);
|
|
21590
|
+
return isDataImage || isImageUrl ? { src: value } : null;
|
|
21591
|
+
}
|
|
21592
|
+
if (typeof value !== "object" || React.isValidElement(value)) return null;
|
|
21593
|
+
const media = value;
|
|
21594
|
+
const src = media.src || media.url || media.thumbnail || media.preview || media.image;
|
|
21595
|
+
return src ? {
|
|
21596
|
+
src: String(src),
|
|
21597
|
+
alt: media.alt || media.label || media.title || "",
|
|
21598
|
+
caption: media.caption || media.description || media.label || media.title
|
|
21599
|
+
} : null;
|
|
21600
|
+
}
|
|
21601
|
+
function shouldRenderAsMedia(field, value) {
|
|
21602
|
+
const renderType = String(field?.renderType || "").toLowerCase();
|
|
21603
|
+
return ["image", "media", "preview", "thumbnail"].includes(renderType) || Boolean(getMediaDisplayData(value));
|
|
21604
|
+
}
|
|
21605
|
+
function renderMaybeFieldIcon(icon, className) {
|
|
21606
|
+
if (!icon) {
|
|
21607
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("span", { className: cn("relative inline-flex h-3.5 w-3.5 shrink-0 items-center justify-center", className), children: [
|
|
21608
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "absolute inset-0 rounded-full border border-primary/25 bg-primary/10" }),
|
|
21609
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "h-1.5 w-1.5 rounded-full bg-primary" })
|
|
21610
|
+
] });
|
|
21611
|
+
}
|
|
21612
|
+
if (typeof icon === "string" || typeof icon === "number") {
|
|
21613
|
+
return /* @__PURE__ */ jsxRuntime.jsx("span", { className: cn("inline-flex h-3.5 min-w-3.5 shrink-0 items-center justify-center rounded-sm text-[10px] font-semibold text-primary", className), children: icon });
|
|
21614
|
+
}
|
|
21615
|
+
if (typeof icon === "boolean") return null;
|
|
21616
|
+
if (React.isValidElement(icon)) return icon;
|
|
21617
|
+
const IconComponent = icon;
|
|
21618
|
+
return /* @__PURE__ */ jsxRuntime.jsx(IconComponent, { className: cn("h-3.5 w-3.5 shrink-0 text-primary", className) });
|
|
21619
|
+
}
|
|
21620
|
+
function renderDetailFieldLabel(label, field, classNames) {
|
|
21621
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("span", { className: cn("inline-flex min-w-0 items-center gap-1.5 text-[11px] font-semibold text-foreground", classNames?.fieldLabel), children: [
|
|
21622
|
+
renderMaybeFieldIcon(field.labelIcon || field.icon, classNames?.fieldLabelIcon),
|
|
21623
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "min-w-0 truncate", children: label })
|
|
21624
|
+
] });
|
|
21625
|
+
}
|
|
21626
|
+
function WorkbenchDetailSidebarMediaValue({
|
|
21627
|
+
media,
|
|
21628
|
+
classNames
|
|
21629
|
+
}) {
|
|
21630
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cn("grid gap-2", classNames?.mediaValue), children: [
|
|
21631
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "overflow-hidden rounded-md border border-border/55 bg-muted/20 dark:border-border/45 dark:bg-muted/10", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
21632
|
+
"img",
|
|
21633
|
+
{
|
|
21634
|
+
src: media.src,
|
|
21635
|
+
alt: String(media.alt || ""),
|
|
21636
|
+
className: cn("block aspect-[16/9] w-full object-cover", classNames?.mediaImage)
|
|
21637
|
+
}
|
|
21638
|
+
) }),
|
|
21639
|
+
media.caption ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: cn("truncate text-[11px] leading-4 text-muted-foreground", classNames?.mediaCaption), children: media.caption }) : null
|
|
21640
|
+
] });
|
|
21641
|
+
}
|
|
21642
|
+
function getDefaultDetailDisplayValue(value, emptyValue, field, classNames) {
|
|
21643
|
+
if (isEmptyDetailValue(value)) return emptyValue;
|
|
21644
|
+
if (React.isValidElement(value)) return value;
|
|
21645
|
+
if (shouldRenderAsMedia(field, value)) {
|
|
21646
|
+
const media = getMediaDisplayData(value);
|
|
21647
|
+
if (media) return /* @__PURE__ */ jsxRuntime.jsx(WorkbenchDetailSidebarMediaValue, { media, classNames });
|
|
21648
|
+
}
|
|
21649
|
+
if (Array.isArray(value)) {
|
|
21650
|
+
const parts = value.map((item) => getDefaultDetailDisplayValue(item, "", void 0, classNames)).filter((item) => !isEmptyDetailValue(item));
|
|
21651
|
+
if (!parts.length) return emptyValue;
|
|
21652
|
+
if (parts.every(isPlainDisplayValue)) return parts.map(String).join(" \xB7 ");
|
|
21653
|
+
return /* @__PURE__ */ jsxRuntime.jsx("span", { className: "inline-flex flex-wrap items-center gap-1", children: parts.map((part, index) => /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "inline-flex items-center gap-1", children: [
|
|
21654
|
+
index > 0 ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-muted-foreground", children: "\xB7" }) : null,
|
|
21655
|
+
isPlainDisplayValue(part) ? String(part) : part
|
|
21656
|
+
] }, index)) });
|
|
21657
|
+
}
|
|
21658
|
+
if (typeof value === "object") {
|
|
21659
|
+
const displayValue = getObjectDisplayValue(value);
|
|
21660
|
+
return displayValue === void 0 ? emptyValue : getDefaultDetailDisplayValue(displayValue, emptyValue, field, classNames);
|
|
21661
|
+
}
|
|
21662
|
+
return String(value);
|
|
21663
|
+
}
|
|
21664
|
+
function getDefaultFieldValue(field, record) {
|
|
21665
|
+
if (Object.prototype.hasOwnProperty.call(field, "value")) {
|
|
21666
|
+
return typeof field.value === "function" ? field.value(record, field) : field.value;
|
|
21667
|
+
}
|
|
21668
|
+
return record ? record?.[field.key] : void 0;
|
|
21669
|
+
}
|
|
21670
|
+
function shouldHideField(field, record) {
|
|
21671
|
+
return typeof field.hidden === "function" ? field.hidden(field, record) : Boolean(field.hidden);
|
|
21672
|
+
}
|
|
21673
|
+
function shouldHideSection(section, record) {
|
|
21674
|
+
return typeof section.hidden === "function" ? section.hidden(section, record) : Boolean(section.hidden);
|
|
21675
|
+
}
|
|
21676
|
+
function WorkbenchDetailSidebarAutoContent({
|
|
21677
|
+
record,
|
|
21678
|
+
fields,
|
|
21679
|
+
sections,
|
|
21680
|
+
fieldColumns = 1,
|
|
21681
|
+
emptyValue = "\u2014",
|
|
21682
|
+
emptyState,
|
|
21683
|
+
getFieldValue,
|
|
21684
|
+
renderFieldValue,
|
|
21685
|
+
formatFieldValue,
|
|
21686
|
+
formatFieldLabel,
|
|
21687
|
+
classNames
|
|
21688
|
+
}) {
|
|
21689
|
+
const resolvedSections = sections?.length ? sections : fields?.length ? [{ fields, columns: fieldColumns }] : [];
|
|
21690
|
+
const visibleSections = resolvedSections.filter((section) => !shouldHideSection(section, record));
|
|
21691
|
+
if (!visibleSections.length) {
|
|
21692
|
+
return emptyState ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: cn("rounded-lg border border-dashed border-border/60 px-3 py-6 text-center text-xs text-muted-foreground", classNames?.emptyState), children: emptyState }) : null;
|
|
21693
|
+
}
|
|
21694
|
+
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: cn("space-y-3", classNames?.autoBody), children: visibleSections.map((section, sectionIndex) => {
|
|
21695
|
+
const visibleFields = (section.fields || []).filter((field) => !shouldHideField(field, record));
|
|
21696
|
+
const sectionKey = section.id || `section-${sectionIndex}`;
|
|
21697
|
+
if (!visibleFields.length && !section.emptyState) return null;
|
|
21698
|
+
const items = visibleFields.map((field, fieldIndex) => {
|
|
21699
|
+
const context = {
|
|
21700
|
+
field,
|
|
21701
|
+
fieldIndex,
|
|
21702
|
+
section,
|
|
21703
|
+
sectionIndex,
|
|
21704
|
+
record
|
|
21705
|
+
};
|
|
21706
|
+
const rawValue = getFieldValue ? getFieldValue(field, record, context) : getDefaultFieldValue(field, record);
|
|
21707
|
+
const value = renderFieldValue ? renderFieldValue(field, record, context) : formatFieldValue ? formatFieldValue(rawValue, context) : getDefaultDetailDisplayValue(rawValue, field.emptyValue ?? emptyValue, field, classNames);
|
|
21708
|
+
const fieldLabel = formatFieldLabel ? formatFieldLabel(getFallbackFieldLabel(field), context) : getFallbackFieldLabel(field);
|
|
21709
|
+
return {
|
|
21710
|
+
term: renderDetailFieldLabel(fieldLabel, field, classNames),
|
|
21711
|
+
value
|
|
21712
|
+
};
|
|
21713
|
+
});
|
|
21714
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("section", { className: cn("min-w-0 space-y-3", classNames?.section), children: [
|
|
21715
|
+
section.title || section.description ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cn("min-w-0 space-y-1.5", classNames?.sectionHeader), children: [
|
|
21716
|
+
section.title ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: cn("inline-flex max-w-full items-center gap-2 rounded-md border border-primary/20 bg-primary/5 px-2.5 py-1.5 text-xs font-medium text-primary dark:border-primary/25 dark:bg-primary/10", classNames?.sectionTitle), children: section.title }) : null,
|
|
21717
|
+
section.description ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: cn("text-[11px] leading-5 text-muted-foreground", classNames?.sectionDescription), children: section.description }) : null
|
|
21718
|
+
] }) : null,
|
|
21719
|
+
items.length ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
21720
|
+
BaseDescriptionList,
|
|
21721
|
+
{
|
|
21722
|
+
items,
|
|
21723
|
+
columns: section.columns || fieldColumns,
|
|
21724
|
+
className: cn("gap-3", classNames?.descriptionList),
|
|
21725
|
+
classNames: {
|
|
21726
|
+
item: cn("!border-0 !bg-transparent !p-0 !shadow-none !gap-1.5", classNames?.descriptionListItem),
|
|
21727
|
+
term: cn("!normal-case !tracking-normal !text-foreground", classNames?.descriptionListTerm),
|
|
21728
|
+
value: cn(
|
|
21729
|
+
"min-h-10 rounded-md border border-border/55 bg-muted/25 px-3 py-2 text-xs leading-5 text-foreground shadow-[inset_0_1px_0_hsl(var(--background)/0.8)] dark:border-border/45 dark:bg-white/[0.035]",
|
|
21730
|
+
classNames?.fieldValue,
|
|
21731
|
+
classNames?.descriptionListValue
|
|
21732
|
+
)
|
|
21733
|
+
}
|
|
21734
|
+
}
|
|
21735
|
+
) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: cn("py-3 text-center text-xs text-muted-foreground", classNames?.emptyState), children: section.emptyState })
|
|
21736
|
+
] }, sectionKey);
|
|
21737
|
+
}) });
|
|
21738
|
+
}
|
|
21739
|
+
var WorkbenchDetailSidebar = React.forwardRef(
|
|
21740
|
+
function WorkbenchDetailSidebar2({
|
|
21741
|
+
as: Component = "aside",
|
|
21742
|
+
bodyAs: BodyComponent = "div",
|
|
21743
|
+
open,
|
|
21744
|
+
width,
|
|
21745
|
+
header,
|
|
21746
|
+
footer,
|
|
21747
|
+
resizeHandle,
|
|
21748
|
+
children,
|
|
21749
|
+
record,
|
|
21750
|
+
fields,
|
|
21751
|
+
sections,
|
|
21752
|
+
fieldColumns,
|
|
21753
|
+
emptyValue,
|
|
21754
|
+
emptyState,
|
|
21755
|
+
getFieldValue,
|
|
21756
|
+
renderFieldValue,
|
|
21757
|
+
formatFieldValue,
|
|
21758
|
+
formatFieldLabel,
|
|
21759
|
+
className,
|
|
21760
|
+
headerClassName,
|
|
21761
|
+
bodyClassName,
|
|
21762
|
+
footerClassName,
|
|
21763
|
+
resizeHandleClassName,
|
|
21764
|
+
bodyProps,
|
|
21765
|
+
classNames,
|
|
21766
|
+
style,
|
|
21767
|
+
...props
|
|
21768
|
+
}, ref) {
|
|
21769
|
+
const autoContent = hasRenderableChildren(children) ? children : /* @__PURE__ */ jsxRuntime.jsx(
|
|
21770
|
+
WorkbenchDetailSidebarAutoContent,
|
|
21771
|
+
{
|
|
21772
|
+
record,
|
|
21773
|
+
fields,
|
|
21774
|
+
sections,
|
|
21775
|
+
fieldColumns,
|
|
21776
|
+
emptyValue,
|
|
21777
|
+
emptyState,
|
|
21778
|
+
getFieldValue,
|
|
21779
|
+
renderFieldValue,
|
|
21780
|
+
formatFieldValue,
|
|
21781
|
+
formatFieldLabel,
|
|
21782
|
+
classNames
|
|
21783
|
+
}
|
|
21784
|
+
);
|
|
21785
|
+
const renderBodyWrapper = shouldRenderBodyWrapper2({
|
|
21786
|
+
header,
|
|
21787
|
+
footer,
|
|
21788
|
+
bodyAs: BodyComponent === "div" ? void 0 : BodyComponent,
|
|
21789
|
+
bodyClassName,
|
|
21790
|
+
bodyProps,
|
|
21791
|
+
classNames
|
|
21792
|
+
});
|
|
21793
|
+
const { className: bodyPropsClassName, ...restBodyProps } = bodyProps ?? {};
|
|
21794
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
21795
|
+
Component,
|
|
21796
|
+
{
|
|
21797
|
+
ref,
|
|
21798
|
+
"data-workbench-detail-sidebar": true,
|
|
21799
|
+
"data-open": open === void 0 ? void 0 : open ? "true" : "false",
|
|
21800
|
+
className: cn(
|
|
21801
|
+
"workbench-surface-subtle relative flex flex-shrink-0 flex-col self-stretch overflow-hidden rounded-lg border border-border/50 transition-all duration-300 dark:border-border/40",
|
|
21802
|
+
open === false && "pointer-events-none",
|
|
21803
|
+
classNames?.root,
|
|
21804
|
+
className
|
|
21805
|
+
),
|
|
21806
|
+
style: {
|
|
21807
|
+
...resolveWidthStyle(open, width),
|
|
21808
|
+
...style
|
|
21809
|
+
},
|
|
21810
|
+
...props,
|
|
21811
|
+
children: [
|
|
21812
|
+
resizeHandle ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: cn(classNames?.resizeHandle, resizeHandleClassName), children: resizeHandle }) : null,
|
|
21813
|
+
header ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: cn("shrink-0 border-b border-border/40 px-4 py-3 dark:border-border/30", classNames?.header, headerClassName), children: header }) : null,
|
|
21814
|
+
renderBodyWrapper ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
21815
|
+
BodyComponent,
|
|
21816
|
+
{
|
|
21817
|
+
className: cn("min-h-0 flex-1 overflow-y-auto", classNames?.body, bodyClassName, bodyPropsClassName),
|
|
21818
|
+
...restBodyProps,
|
|
21819
|
+
children: autoContent
|
|
21820
|
+
}
|
|
21821
|
+
) : autoContent,
|
|
21822
|
+
footer ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: cn("shrink-0 border-t border-border/40 px-4 py-3 dark:border-border/30", classNames?.footer, footerClassName), children: footer }) : null
|
|
21823
|
+
]
|
|
21824
|
+
}
|
|
21825
|
+
);
|
|
21826
|
+
}
|
|
21827
|
+
);
|
|
21828
|
+
function isWorkbenchIconComponent(icon) {
|
|
21829
|
+
if (typeof icon === "function") return true;
|
|
21830
|
+
return typeof icon === "object" && icon !== null && !React.isValidElement(icon) && "$$typeof" in icon;
|
|
21831
|
+
}
|
|
21832
|
+
function renderWorkbenchIcon(icon, className) {
|
|
21833
|
+
if (!icon) return null;
|
|
21834
|
+
if (React.isValidElement(icon)) return icon;
|
|
21835
|
+
if (isWorkbenchIconComponent(icon)) {
|
|
21836
|
+
const Icon = icon;
|
|
21837
|
+
return /* @__PURE__ */ jsxRuntime.jsx(Icon, { className });
|
|
21838
|
+
}
|
|
21839
|
+
return icon;
|
|
21840
|
+
}
|
|
21841
|
+
function getWorkbenchIconComponent(icon) {
|
|
21842
|
+
if (!icon || !isWorkbenchIconComponent(icon)) return null;
|
|
21843
|
+
return icon;
|
|
21844
|
+
}
|
|
21845
|
+
function toCssSize3(value) {
|
|
21846
|
+
if (value === void 0) return void 0;
|
|
21847
|
+
return typeof value === "number" ? `${value}px` : value;
|
|
21848
|
+
}
|
|
21849
|
+
function defaultFormatLabel(value) {
|
|
21850
|
+
if (value === void 0 || value === null || value === false) return null;
|
|
21851
|
+
return value;
|
|
21852
|
+
}
|
|
21853
|
+
function toTitle(value) {
|
|
21854
|
+
if (typeof value === "string" || typeof value === "number") return String(value);
|
|
21855
|
+
return void 0;
|
|
21856
|
+
}
|
|
21857
|
+
function defaultGetRowKey(row, rowIndex) {
|
|
21858
|
+
return row?.id ?? row?.key ?? row?.linkKey ?? rowIndex;
|
|
21859
|
+
}
|
|
21860
|
+
function defaultGetRowSelectionKey(row) {
|
|
21861
|
+
return row?.linkKey ?? row?.id ?? row?.key;
|
|
21862
|
+
}
|
|
21863
|
+
function getOrderedColumns(columns, columnOrder) {
|
|
21864
|
+
if (!columnOrder?.length) return columns;
|
|
21865
|
+
const columnMap = new Map(columns.map((column) => [column.key, column]));
|
|
21866
|
+
const orderedColumns = columnOrder.map((columnKey) => columnMap.get(columnKey)).filter(Boolean);
|
|
21867
|
+
const orderedKeySet = new Set(orderedColumns.map((column) => column.key));
|
|
21868
|
+
const remainingColumns = columns.filter((column) => !orderedKeySet.has(column.key));
|
|
21869
|
+
return [...orderedColumns, ...remainingColumns];
|
|
21870
|
+
}
|
|
21871
|
+
function normalizeColumnOrder(columnKeys, columnOrder) {
|
|
21872
|
+
const validColumnKeys = new Set(columnKeys);
|
|
21873
|
+
const orderedKeys = (columnOrder || []).filter((columnKey) => validColumnKeys.has(columnKey));
|
|
21874
|
+
const orderedKeySet = new Set(orderedKeys);
|
|
21875
|
+
const remainingKeys = columnKeys.filter((columnKey) => !orderedKeySet.has(columnKey));
|
|
21876
|
+
return [...orderedKeys, ...remainingKeys];
|
|
21877
|
+
}
|
|
21878
|
+
function WorkbenchTableHeaderHelper({
|
|
21879
|
+
helperText,
|
|
21880
|
+
className
|
|
21881
|
+
}) {
|
|
21882
|
+
if (!hasRenderableNode(helperText)) return null;
|
|
21883
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("span", { className: cn("group relative inline-flex items-center", className), children: [
|
|
21884
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
21885
|
+
"button",
|
|
21886
|
+
{
|
|
21887
|
+
type: "button",
|
|
21888
|
+
title: toTitle(helperText),
|
|
21889
|
+
"aria-label": toTitle(helperText) || "Field help",
|
|
21890
|
+
className: "inline-flex h-4 w-4 items-center justify-center rounded-full border border-border/60 bg-background text-[10px] font-semibold normal-case tracking-normal text-muted-foreground shadow-sm transition-colors hover:border-primary/40 hover:text-primary focus-visible:border-primary/40 focus-visible:text-primary focus-visible:outline-none",
|
|
21891
|
+
onClick: (event) => event.stopPropagation(),
|
|
21892
|
+
children: "?"
|
|
21893
|
+
}
|
|
21894
|
+
),
|
|
21895
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
21896
|
+
"span",
|
|
21897
|
+
{
|
|
21898
|
+
role: "tooltip",
|
|
21899
|
+
className: "pointer-events-none absolute left-1/2 top-full z-40 mt-2 hidden w-72 -translate-x-1/2 whitespace-pre-line rounded-lg border border-border/60 bg-card px-3 py-2 text-[11px] font-normal normal-case leading-5 tracking-normal text-foreground shadow-sm backdrop-blur-sm group-hover:block group-focus-within:block",
|
|
21900
|
+
children: helperText
|
|
21901
|
+
}
|
|
21902
|
+
)
|
|
21903
|
+
] });
|
|
21904
|
+
}
|
|
21905
|
+
function WorkbenchTableView({
|
|
21906
|
+
rows = [],
|
|
21907
|
+
columns = [],
|
|
21908
|
+
onRowClick,
|
|
21909
|
+
selectedRowKey,
|
|
21910
|
+
selectedLinkKey,
|
|
21911
|
+
activePrimaryColumn,
|
|
21912
|
+
activeTablePrimaryColumn,
|
|
21913
|
+
renderedRowCount,
|
|
21914
|
+
totalRowCount,
|
|
21915
|
+
tableMinWidth,
|
|
21916
|
+
minWidth,
|
|
21917
|
+
bodyMaxHeight = "min(58vh, 38rem)",
|
|
21918
|
+
stickyFirstColumn = true,
|
|
21919
|
+
appearance,
|
|
21920
|
+
columnOrder,
|
|
21921
|
+
columnSizes,
|
|
21922
|
+
columnDragEnabled,
|
|
21923
|
+
columnResizeEnabled,
|
|
21924
|
+
className,
|
|
21925
|
+
tableClassName,
|
|
21926
|
+
rowClassName,
|
|
21927
|
+
classNames,
|
|
21928
|
+
style,
|
|
21929
|
+
renderCell,
|
|
21930
|
+
renderFieldValue,
|
|
21931
|
+
renderColumnHeader,
|
|
21932
|
+
onColumnOrderChange,
|
|
21933
|
+
onColumnSizeChange,
|
|
21934
|
+
onSort,
|
|
21935
|
+
formatLabel = defaultFormatLabel,
|
|
21936
|
+
getColumnDataType,
|
|
21937
|
+
getColumnIcon,
|
|
21938
|
+
getColumnTypeIcon,
|
|
21939
|
+
getRowKey = defaultGetRowKey,
|
|
21940
|
+
getRowSelectionKey = defaultGetRowSelectionKey,
|
|
21941
|
+
isActionColumn,
|
|
21942
|
+
isActionField,
|
|
21943
|
+
isRowDisabled,
|
|
21944
|
+
isWorkbenchPlaceholderRow,
|
|
21945
|
+
emptyState = "-",
|
|
21946
|
+
hiddenRowsMessage
|
|
21947
|
+
}) {
|
|
21948
|
+
const columnKeySignature = columns.map((column) => column.key).join("");
|
|
21949
|
+
const defaultColumnOrder = React.useMemo(() => columnKeySignature ? columnKeySignature.split("") : [], [columnKeySignature]);
|
|
21950
|
+
const [internalColumnOrder, setInternalColumnOrder] = React.useState(defaultColumnOrder);
|
|
21951
|
+
const [internalColumnSizes, setInternalColumnSizes] = React.useState({});
|
|
21952
|
+
React.useEffect(() => {
|
|
21953
|
+
setInternalColumnOrder((current) => normalizeColumnOrder(defaultColumnOrder, current));
|
|
21954
|
+
}, [defaultColumnOrder]);
|
|
21955
|
+
const resolvedColumnOrder = columnOrder ? normalizeColumnOrder(defaultColumnOrder, columnOrder) : internalColumnOrder;
|
|
21956
|
+
const resolvedColumnSizes = columnSizes ?? internalColumnSizes;
|
|
21957
|
+
const handleColumnOrderChange = React.useCallback((nextOrder, detail) => {
|
|
21958
|
+
const normalizedOrder = normalizeColumnOrder(defaultColumnOrder, nextOrder);
|
|
21959
|
+
if (!columnOrder) {
|
|
21960
|
+
setInternalColumnOrder(normalizedOrder);
|
|
21961
|
+
}
|
|
21962
|
+
onColumnOrderChange?.(normalizedOrder, detail);
|
|
21963
|
+
}, [columnOrder, defaultColumnOrder, onColumnOrderChange]);
|
|
21964
|
+
const handleColumnSizeChange = React.useCallback((columnId, width, detail) => {
|
|
21965
|
+
if (!columnSizes) {
|
|
21966
|
+
setInternalColumnSizes((current) => ({
|
|
21967
|
+
...current,
|
|
21968
|
+
[columnId]: width
|
|
21969
|
+
}));
|
|
21970
|
+
}
|
|
21971
|
+
onColumnSizeChange?.(columnId, width, detail);
|
|
21972
|
+
}, [columnSizes, onColumnSizeChange]);
|
|
21973
|
+
const resolvedSelectedKey = selectedRowKey ?? selectedLinkKey;
|
|
21974
|
+
const resolvedActivePrimaryColumn = activePrimaryColumn ?? activeTablePrimaryColumn;
|
|
21975
|
+
const orderedColumns = getOrderedColumns(columns, resolvedColumnOrder);
|
|
21976
|
+
const hiddenRowCount = Math.max(0, Number(totalRowCount || rows.length) - Number(renderedRowCount || rows.length));
|
|
21977
|
+
const resolvedMinWidth = tableMinWidth ?? minWidth ?? Math.max(760, Math.min(orderedColumns.length * 112, 1440));
|
|
21978
|
+
const renderValue = renderCell ?? renderFieldValue ?? ((column, row) => row?.[column.key]);
|
|
21979
|
+
const isAction = isActionColumn ?? isActionField ?? (() => false);
|
|
21980
|
+
const isDisabled = isRowDisabled ?? isWorkbenchPlaceholderRow ?? (() => false);
|
|
21981
|
+
const resolveColumnIcon = getColumnIcon ?? getColumnTypeIcon;
|
|
21982
|
+
const footer = hiddenRowCount > 0 && hiddenRowsMessage ? typeof hiddenRowsMessage === "function" ? hiddenRowsMessage(hiddenRowCount, renderedRowCount || rows.length, totalRowCount || rows.length) : hiddenRowsMessage : null;
|
|
21983
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
21984
|
+
BaseTableContainer,
|
|
21985
|
+
{
|
|
21986
|
+
appearance,
|
|
21987
|
+
className: cn("w-full overflow-hidden rounded-lg border border-border/40 bg-muted/15 dark:border-border/35 dark:bg-muted/10", classNames?.root, className),
|
|
21988
|
+
style,
|
|
21989
|
+
children: [
|
|
21990
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
21991
|
+
"div",
|
|
21992
|
+
{
|
|
21993
|
+
className: cn("w-full overflow-auto", classNames?.scrollArea),
|
|
21994
|
+
style: { maxHeight: toCssSize3(bodyMaxHeight) },
|
|
21995
|
+
children: /* @__PURE__ */ jsxRuntime.jsxs(
|
|
21996
|
+
BaseTable,
|
|
21997
|
+
{
|
|
21998
|
+
appearance,
|
|
21999
|
+
columnOrder: resolvedColumnOrder,
|
|
22000
|
+
columnSizes: resolvedColumnSizes,
|
|
22001
|
+
columnDragEnabled,
|
|
22002
|
+
columnResizeEnabled,
|
|
22003
|
+
onColumnOrderChange: handleColumnOrderChange,
|
|
22004
|
+
onColumnSizeChange: handleColumnSizeChange,
|
|
22005
|
+
className: cn("w-full table-auto text-left text-xs", classNames?.table, tableClassName),
|
|
22006
|
+
style: { minWidth: resolvedMinWidth },
|
|
22007
|
+
children: [
|
|
22008
|
+
/* @__PURE__ */ jsxRuntime.jsx(BaseTableHeader, { appearance, className: cn("text-[10px] font-mono uppercase tracking-wide text-muted-foreground", classNames?.header), children: /* @__PURE__ */ jsxRuntime.jsx(BaseTableRow, { className: cn("hover:bg-transparent", classNames?.headerRow), children: orderedColumns.map((column, columnIndex) => {
|
|
22009
|
+
const columnType = column.renderType || column.type || getColumnDataType?.(column.key, rows, column);
|
|
22010
|
+
const columnIcon = renderWorkbenchIcon(
|
|
22011
|
+
resolveColumnIcon?.(columnType, column),
|
|
22012
|
+
"h-3.5 w-3.5 shrink-0 text-primary"
|
|
22013
|
+
);
|
|
22014
|
+
const previousColumn = orderedColumns[columnIndex - 1];
|
|
22015
|
+
const followsRecordIcon = previousColumn?.renderType === "icon" && column.key === resolvedActivePrimaryColumn?.key;
|
|
22016
|
+
const headerContent = renderColumnHeader ? renderColumnHeader(column, { column, columnIndex, columns: orderedColumns, rows, columnType }) : formatLabel(column.label, { column });
|
|
22017
|
+
const headerTrailing = !renderColumnHeader && (hasRenderableNode(column.trailing) || hasRenderableNode(column.helperText)) ? /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "inline-flex items-center gap-1.5", children: [
|
|
22018
|
+
hasRenderableNode(column.trailing) ? formatLabel(column.trailing, { column }) : null,
|
|
22019
|
+
/* @__PURE__ */ jsxRuntime.jsx(WorkbenchTableHeaderHelper, { helperText: formatLabel(column.helperText, { column }), className: classNames?.helper })
|
|
22020
|
+
] }) : void 0;
|
|
22021
|
+
const sortable = Boolean(column.sortable);
|
|
22022
|
+
const handleSort = sortable && onSort ? () => onSort(column.key, column) : void 0;
|
|
22023
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
22024
|
+
BaseTableHead,
|
|
22025
|
+
{
|
|
22026
|
+
appearance,
|
|
22027
|
+
columnId: column.key,
|
|
22028
|
+
align: column.align,
|
|
22029
|
+
icon: renderColumnHeader ? void 0 : columnIcon,
|
|
22030
|
+
label: headerContent,
|
|
22031
|
+
description: renderColumnHeader ? void 0 : formatLabel(column.description, { column }),
|
|
22032
|
+
meta: renderColumnHeader ? void 0 : formatLabel(column.meta, { column }),
|
|
22033
|
+
actions: renderColumnHeader ? void 0 : column.actions,
|
|
22034
|
+
trailing: headerTrailing,
|
|
22035
|
+
sortable,
|
|
22036
|
+
sortDirection: column.sortDirection,
|
|
22037
|
+
sortLabel: column.sortLabel,
|
|
22038
|
+
onSort: handleSort,
|
|
22039
|
+
draggable: column.draggable,
|
|
22040
|
+
dragLabel: column.dragLabel,
|
|
22041
|
+
resizable: column.resizable,
|
|
22042
|
+
resizeLabel: column.resizeLabel,
|
|
22043
|
+
width: column.width,
|
|
22044
|
+
minWidth: typeof column.minWidth === "number" ? column.minWidth : void 0,
|
|
22045
|
+
maxWidth: typeof column.maxWidth === "number" ? column.maxWidth : void 0,
|
|
22046
|
+
className: cn(
|
|
22047
|
+
"sticky top-0 z-20 h-auto whitespace-nowrap bg-card/95 px-4 py-3 font-medium backdrop-blur-sm supports-[backdrop-filter]:bg-card/90",
|
|
22048
|
+
stickyFirstColumn && columnIndex === 0 && "left-0 z-30 shadow-[1px_0_0_0_hsl(var(--border)/0.35)]",
|
|
22049
|
+
column.compactHeaderClassName,
|
|
22050
|
+
column.headerClassName,
|
|
22051
|
+
column.renderType === "icon" && "pl-3 pr-1",
|
|
22052
|
+
followsRecordIcon && "pl-2",
|
|
22053
|
+
classNames?.headerCell
|
|
22054
|
+
),
|
|
22055
|
+
style: {
|
|
22056
|
+
minWidth: typeof column.minWidth === "string" ? column.minWidth : void 0,
|
|
22057
|
+
maxWidth: typeof column.maxWidth === "string" ? column.maxWidth : void 0
|
|
22058
|
+
}
|
|
22059
|
+
},
|
|
22060
|
+
column.key
|
|
22061
|
+
);
|
|
22062
|
+
}) }) }),
|
|
22063
|
+
/* @__PURE__ */ jsxRuntime.jsx(BaseTableBody, { appearance, className: cn("divide-y divide-border/35 dark:divide-border/30", classNames?.body), children: rows.length ? rows.map((row, rowIndex) => {
|
|
22064
|
+
const key = getRowKey(row, rowIndex);
|
|
22065
|
+
const disabled = isDisabled(row, rowIndex);
|
|
22066
|
+
const selectionKey = getRowSelectionKey(row, rowIndex);
|
|
22067
|
+
const selected = Boolean(resolvedSelectedKey && String(selectionKey) === String(resolvedSelectedKey));
|
|
22068
|
+
const resolvedRowClassName = typeof rowClassName === "function" ? rowClassName(row, rowIndex) : rowClassName;
|
|
22069
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
22070
|
+
BaseTableRow,
|
|
22071
|
+
{
|
|
22072
|
+
appearance,
|
|
22073
|
+
interactive: Boolean(onRowClick) && !disabled,
|
|
22074
|
+
selected,
|
|
22075
|
+
disabled,
|
|
22076
|
+
onClick: () => {
|
|
22077
|
+
if (!disabled) {
|
|
22078
|
+
onRowClick?.(row, rowIndex);
|
|
22079
|
+
}
|
|
22080
|
+
},
|
|
22081
|
+
className: cn(
|
|
22082
|
+
onRowClick && !disabled ? "cursor-pointer" : "cursor-default",
|
|
22083
|
+
selected ? "bg-primary/10 hover:bg-primary/15" : disabled ? "" : "hover:bg-muted/25 dark:hover:bg-muted/15",
|
|
22084
|
+
classNames?.row,
|
|
22085
|
+
resolvedRowClassName
|
|
22086
|
+
),
|
|
22087
|
+
children: orderedColumns.map((column, columnIndex) => {
|
|
22088
|
+
const shouldWrap = isAction(column) || column.wrap === true;
|
|
22089
|
+
const previousColumn = orderedColumns[columnIndex - 1];
|
|
22090
|
+
const followsRecordIcon = previousColumn?.renderType === "icon" && column.key === resolvedActivePrimaryColumn?.key;
|
|
22091
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
22092
|
+
BaseTableCell,
|
|
22093
|
+
{
|
|
22094
|
+
appearance,
|
|
22095
|
+
align: column.align,
|
|
22096
|
+
className: cn(
|
|
22097
|
+
shouldWrap ? "align-top whitespace-normal" : "whitespace-nowrap",
|
|
22098
|
+
"px-4 py-3 text-muted-foreground",
|
|
22099
|
+
stickyFirstColumn && columnIndex === 0 && "sticky left-0 z-10 bg-card/95 text-foreground shadow-[1px_0_0_0_hsl(var(--border)/0.3)]",
|
|
22100
|
+
column.compactCellClassName,
|
|
22101
|
+
column.cellClassName,
|
|
22102
|
+
column.renderType === "icon" && "pl-3 pr-1",
|
|
22103
|
+
followsRecordIcon && "pl-2",
|
|
22104
|
+
classNames?.cell
|
|
22105
|
+
),
|
|
22106
|
+
children: renderValue(column, row, {
|
|
22107
|
+
row,
|
|
22108
|
+
rowIndex,
|
|
22109
|
+
column,
|
|
22110
|
+
columnIndex,
|
|
22111
|
+
compact: true,
|
|
22112
|
+
surface: "list"
|
|
22113
|
+
})
|
|
22114
|
+
},
|
|
22115
|
+
`${key}-${column.key}`
|
|
22116
|
+
);
|
|
22117
|
+
})
|
|
22118
|
+
},
|
|
22119
|
+
key
|
|
22120
|
+
);
|
|
22121
|
+
}) : /* @__PURE__ */ jsxRuntime.jsx(
|
|
22122
|
+
BaseTableEmpty,
|
|
22123
|
+
{
|
|
22124
|
+
appearance,
|
|
22125
|
+
colSpan: Math.max(orderedColumns.length, 1),
|
|
22126
|
+
classNames: { cell: "px-4 py-10 text-center text-sm text-muted-foreground" },
|
|
22127
|
+
children: emptyState
|
|
22128
|
+
}
|
|
22129
|
+
) })
|
|
22130
|
+
]
|
|
22131
|
+
}
|
|
22132
|
+
)
|
|
22133
|
+
}
|
|
22134
|
+
),
|
|
22135
|
+
footer ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: cn("border-t border-border/40 px-4 py-2 text-[11px] text-muted-foreground dark:border-border/30", classNames?.footer), children: footer }) : null
|
|
22136
|
+
]
|
|
22137
|
+
}
|
|
22138
|
+
);
|
|
22139
|
+
}
|
|
22140
|
+
function toCssSize4(value) {
|
|
22141
|
+
if (value === void 0) return void 0;
|
|
22142
|
+
return typeof value === "number" ? `${value}px` : value;
|
|
22143
|
+
}
|
|
22144
|
+
function isBrowser() {
|
|
22145
|
+
return typeof window !== "undefined";
|
|
22146
|
+
}
|
|
22147
|
+
function defaultGetRowKey2(row, rowIndex) {
|
|
22148
|
+
return row?.id ?? row?.key ?? rowIndex;
|
|
22149
|
+
}
|
|
22150
|
+
function getColumnDefaultSize(column) {
|
|
22151
|
+
if (typeof column.width === "number") return column.width;
|
|
22152
|
+
if (typeof column.minWidth === "number") return column.minWidth;
|
|
22153
|
+
return 160;
|
|
22154
|
+
}
|
|
22155
|
+
function buildDefaultColumnSizes(columns, explicit) {
|
|
22156
|
+
return columns.reduce((acc, column) => {
|
|
22157
|
+
acc[column.key] = explicit?.[column.key] ?? getColumnDefaultSize(column);
|
|
22158
|
+
return acc;
|
|
22159
|
+
}, {});
|
|
22160
|
+
}
|
|
22161
|
+
function loadStoredColumnSizes(storageKey, defaults) {
|
|
22162
|
+
if (!storageKey || !isBrowser()) return defaults;
|
|
22163
|
+
try {
|
|
22164
|
+
const parsed = JSON.parse(window.localStorage.getItem(storageKey) || "{}");
|
|
22165
|
+
return Object.keys(defaults).reduce((acc, key) => {
|
|
22166
|
+
const value = Number(parsed?.[key]);
|
|
22167
|
+
acc[key] = Number.isFinite(value) ? value : defaults[key];
|
|
22168
|
+
return acc;
|
|
22169
|
+
}, {});
|
|
22170
|
+
} catch {
|
|
22171
|
+
return defaults;
|
|
22172
|
+
}
|
|
22173
|
+
}
|
|
22174
|
+
function persistColumnSizes(storageKey, sizes) {
|
|
22175
|
+
if (!storageKey || !isBrowser()) return;
|
|
22176
|
+
window.localStorage.setItem(storageKey, JSON.stringify(sizes));
|
|
22177
|
+
}
|
|
22178
|
+
function getFrozenColumnStorageKey(storageKey) {
|
|
22179
|
+
return storageKey ? `${storageKey}.frozenColumnCount` : void 0;
|
|
22180
|
+
}
|
|
22181
|
+
function getFrozenEndColumnStorageKey(storageKey) {
|
|
22182
|
+
return storageKey ? `${storageKey}.frozenEndColumnCount` : void 0;
|
|
22183
|
+
}
|
|
22184
|
+
function clampFrozenColumnCount(count, columnCount) {
|
|
22185
|
+
if (!Number.isFinite(count)) return 0;
|
|
22186
|
+
return Math.max(0, Math.min(Math.round(count), columnCount));
|
|
22187
|
+
}
|
|
22188
|
+
function normalizeFrozenColumnCounts(startCount, endCount, columnCount) {
|
|
22189
|
+
const normalizedStartCount = clampFrozenColumnCount(startCount, columnCount);
|
|
22190
|
+
const normalizedEndCount = clampFrozenColumnCount(endCount, Math.max(0, columnCount - normalizedStartCount));
|
|
22191
|
+
return {
|
|
22192
|
+
startCount: normalizedStartCount,
|
|
22193
|
+
endCount: normalizedEndCount
|
|
22194
|
+
};
|
|
22195
|
+
}
|
|
22196
|
+
function loadStoredFrozenColumnCount(storageKey, defaultCount, columnCount) {
|
|
22197
|
+
const fallback = clampFrozenColumnCount(defaultCount, columnCount);
|
|
22198
|
+
const frozenStorageKey = getFrozenColumnStorageKey(storageKey);
|
|
22199
|
+
if (!frozenStorageKey || !isBrowser()) return fallback;
|
|
22200
|
+
try {
|
|
22201
|
+
const storedValue = window.localStorage.getItem(frozenStorageKey);
|
|
22202
|
+
if (storedValue === null) return fallback;
|
|
22203
|
+
const value = Number(storedValue);
|
|
22204
|
+
return Number.isFinite(value) ? clampFrozenColumnCount(value, columnCount) : fallback;
|
|
22205
|
+
} catch {
|
|
22206
|
+
return fallback;
|
|
22207
|
+
}
|
|
22208
|
+
}
|
|
22209
|
+
function persistFrozenColumnCount(storageKey, count) {
|
|
22210
|
+
const frozenStorageKey = getFrozenColumnStorageKey(storageKey);
|
|
22211
|
+
if (!frozenStorageKey || !isBrowser()) return;
|
|
22212
|
+
window.localStorage.setItem(frozenStorageKey, String(count));
|
|
22213
|
+
}
|
|
22214
|
+
function loadStoredFrozenEndColumnCount(storageKey, defaultCount, columnCount) {
|
|
22215
|
+
const fallback = clampFrozenColumnCount(defaultCount, columnCount);
|
|
22216
|
+
const frozenStorageKey = getFrozenEndColumnStorageKey(storageKey);
|
|
22217
|
+
if (!frozenStorageKey || !isBrowser()) return fallback;
|
|
22218
|
+
try {
|
|
22219
|
+
const storedValue = window.localStorage.getItem(frozenStorageKey);
|
|
22220
|
+
if (storedValue === null) return fallback;
|
|
22221
|
+
const value = Number(storedValue);
|
|
22222
|
+
return Number.isFinite(value) ? clampFrozenColumnCount(value, columnCount) : fallback;
|
|
22223
|
+
} catch {
|
|
22224
|
+
return fallback;
|
|
22225
|
+
}
|
|
22226
|
+
}
|
|
22227
|
+
function persistFrozenEndColumnCount(storageKey, count) {
|
|
22228
|
+
const frozenStorageKey = getFrozenEndColumnStorageKey(storageKey);
|
|
22229
|
+
if (!frozenStorageKey || !isBrowser()) return;
|
|
22230
|
+
window.localStorage.setItem(frozenStorageKey, String(count));
|
|
22231
|
+
}
|
|
22232
|
+
function normalizeColumnOrder2(columnKeys, columnOrder) {
|
|
22233
|
+
const validColumnKeys = new Set(columnKeys);
|
|
22234
|
+
const orderedKeys = (columnOrder || []).filter((columnKey) => validColumnKeys.has(columnKey));
|
|
22235
|
+
const orderedKeySet = new Set(orderedKeys);
|
|
22236
|
+
const remainingKeys = columnKeys.filter((columnKey) => !orderedKeySet.has(columnKey));
|
|
22237
|
+
return [...orderedKeys, ...remainingKeys];
|
|
22238
|
+
}
|
|
22239
|
+
function getOrderedColumns2(columns, columnOrder) {
|
|
22240
|
+
const normalizedOrder = normalizeColumnOrder2(columns.map((column) => column.key), columnOrder);
|
|
22241
|
+
const columnMap = new Map(columns.map((column) => [column.key, column]));
|
|
22242
|
+
return normalizedOrder.map((columnKey) => columnMap.get(columnKey)).filter(Boolean);
|
|
22243
|
+
}
|
|
22244
|
+
function getColumnNumericWidth(column, columnSizes) {
|
|
22245
|
+
const controlledWidth = columnSizes[column.key];
|
|
22246
|
+
if (typeof controlledWidth === "number") return controlledWidth;
|
|
22247
|
+
return getColumnDefaultSize(column);
|
|
22248
|
+
}
|
|
22249
|
+
function buildFrozenOffsets(columns, columnSizes, frozenColumnCount) {
|
|
22250
|
+
const offsets = /* @__PURE__ */ new Map();
|
|
22251
|
+
let left = 0;
|
|
22252
|
+
columns.slice(0, Math.max(0, frozenColumnCount)).forEach((column) => {
|
|
22253
|
+
offsets.set(column.key, left);
|
|
22254
|
+
left += getColumnNumericWidth(column, columnSizes);
|
|
22255
|
+
});
|
|
22256
|
+
return offsets;
|
|
22257
|
+
}
|
|
22258
|
+
function buildFrozenEndOffsets(columns, columnSizes, frozenEndColumnCount) {
|
|
22259
|
+
const offsets = /* @__PURE__ */ new Map();
|
|
22260
|
+
let right = 0;
|
|
22261
|
+
columns.slice(Math.max(0, columns.length - frozenEndColumnCount)).reverse().forEach((column) => {
|
|
22262
|
+
offsets.set(column.key, right);
|
|
22263
|
+
right += getColumnNumericWidth(column, columnSizes);
|
|
22264
|
+
});
|
|
22265
|
+
return offsets;
|
|
22266
|
+
}
|
|
22267
|
+
function resolveRowClassName(rowClassName, row, rowIndex) {
|
|
22268
|
+
return typeof rowClassName === "function" ? rowClassName(row, rowIndex) : rowClassName;
|
|
22269
|
+
}
|
|
22270
|
+
function renderDefaultCell(column, row) {
|
|
22271
|
+
const value = row?.[column.key];
|
|
22272
|
+
if (value === void 0 || value === null || value === "") return "\u2014";
|
|
22273
|
+
return String(value);
|
|
22274
|
+
}
|
|
22275
|
+
function InteractiveTableCellContent({
|
|
22276
|
+
children,
|
|
22277
|
+
wrap
|
|
22278
|
+
}) {
|
|
22279
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
22280
|
+
"div",
|
|
22281
|
+
{
|
|
22282
|
+
className: cn(
|
|
22283
|
+
"min-w-0 max-w-full overflow-auto overscroll-contain [scrollbar-width:thin]",
|
|
22284
|
+
wrap ? "max-h-20 whitespace-pre-wrap break-words leading-5" : "whitespace-nowrap"
|
|
22285
|
+
),
|
|
22286
|
+
children
|
|
22287
|
+
}
|
|
22288
|
+
);
|
|
22289
|
+
}
|
|
22290
|
+
function PinIcon({ className }) {
|
|
22291
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
22292
|
+
"svg",
|
|
22293
|
+
{
|
|
22294
|
+
"aria-hidden": "true",
|
|
22295
|
+
viewBox: "0 0 16 16",
|
|
22296
|
+
className,
|
|
22297
|
+
fill: "none",
|
|
22298
|
+
stroke: "currentColor",
|
|
22299
|
+
strokeLinecap: "round",
|
|
22300
|
+
strokeLinejoin: "round",
|
|
22301
|
+
strokeWidth: "1.75",
|
|
22302
|
+
children: [
|
|
22303
|
+
/* @__PURE__ */ jsxRuntime.jsx("path", { d: "M5.25 2.75h5.5" }),
|
|
22304
|
+
/* @__PURE__ */ jsxRuntime.jsx("path", { d: "M6.25 2.75v4L4.5 9.25h7L9.75 6.75v-4" }),
|
|
22305
|
+
/* @__PURE__ */ jsxRuntime.jsx("path", { d: "M8 9.25v4" })
|
|
22306
|
+
]
|
|
22307
|
+
}
|
|
22308
|
+
);
|
|
22309
|
+
}
|
|
22310
|
+
function InteractiveTable({
|
|
22311
|
+
rows = [],
|
|
22312
|
+
columns = [],
|
|
22313
|
+
pinnedTopRows = [],
|
|
22314
|
+
getRowKey = defaultGetRowKey2,
|
|
22315
|
+
getPinnedTopRowKey = defaultGetRowKey2,
|
|
22316
|
+
renderCell,
|
|
22317
|
+
renderPinnedTopCell,
|
|
22318
|
+
renderColumnHeader,
|
|
22319
|
+
onRowClick,
|
|
22320
|
+
getRowState,
|
|
22321
|
+
rowClassName,
|
|
22322
|
+
pinnedTopRowClassName,
|
|
22323
|
+
emptyState = "\u2014",
|
|
22324
|
+
columnMenuLabels,
|
|
22325
|
+
columnStorageKey,
|
|
22326
|
+
columnOrder,
|
|
22327
|
+
columnSizes,
|
|
22328
|
+
defaultColumnSizes,
|
|
22329
|
+
columnDragEnabled = false,
|
|
22330
|
+
columnResizeEnabled = true,
|
|
22331
|
+
frozenColumnCount = 0,
|
|
22332
|
+
frozenEndColumnCount = 0,
|
|
22333
|
+
tableMinWidth,
|
|
22334
|
+
bodyMaxHeight = "min(60vh, 42rem)",
|
|
22335
|
+
appearance,
|
|
22336
|
+
className,
|
|
22337
|
+
tableClassName,
|
|
22338
|
+
classNames,
|
|
22339
|
+
style,
|
|
22340
|
+
onColumnOrderChange,
|
|
22341
|
+
onColumnSizeChange,
|
|
22342
|
+
onResetColumnSizes,
|
|
22343
|
+
onFrozenColumnCountChange,
|
|
22344
|
+
onFrozenEndColumnCountChange,
|
|
22345
|
+
onSort
|
|
22346
|
+
}) {
|
|
22347
|
+
const columnKeySignature = columns.map((column) => column.key).join("");
|
|
22348
|
+
const defaultOrder = React.useMemo(
|
|
22349
|
+
() => columnKeySignature ? columnKeySignature.split("") : [],
|
|
22350
|
+
[columnKeySignature]
|
|
22351
|
+
);
|
|
22352
|
+
const defaultSizes = React.useMemo(
|
|
22353
|
+
() => buildDefaultColumnSizes(columns, defaultColumnSizes),
|
|
22354
|
+
[columns, defaultColumnSizes]
|
|
22355
|
+
);
|
|
22356
|
+
const [internalColumnOrder, setInternalColumnOrder] = React.useState(defaultOrder);
|
|
22357
|
+
const [internalColumnSizes, setInternalColumnSizes] = React.useState(() => loadStoredColumnSizes(columnStorageKey, defaultSizes));
|
|
22358
|
+
const [internalFrozenColumnCount, setInternalFrozenColumnCount] = React.useState(() => loadStoredFrozenColumnCount(columnStorageKey, frozenColumnCount, columns.length));
|
|
22359
|
+
const [internalFrozenEndColumnCount, setInternalFrozenEndColumnCount] = React.useState(() => loadStoredFrozenEndColumnCount(columnStorageKey, frozenEndColumnCount, columns.length));
|
|
22360
|
+
React.useEffect(() => {
|
|
22361
|
+
setInternalColumnOrder((current) => normalizeColumnOrder2(defaultOrder, current));
|
|
22362
|
+
}, [defaultOrder]);
|
|
22363
|
+
React.useEffect(() => {
|
|
22364
|
+
if (columnSizes) return;
|
|
22365
|
+
setInternalColumnSizes(loadStoredColumnSizes(columnStorageKey, defaultSizes));
|
|
22366
|
+
}, [columnSizes, columnStorageKey, defaultSizes]);
|
|
22367
|
+
React.useEffect(() => {
|
|
22368
|
+
setInternalFrozenColumnCount(loadStoredFrozenColumnCount(columnStorageKey, frozenColumnCount, columns.length));
|
|
22369
|
+
}, [columnStorageKey, columns.length, frozenColumnCount]);
|
|
22370
|
+
React.useEffect(() => {
|
|
22371
|
+
setInternalFrozenEndColumnCount(loadStoredFrozenEndColumnCount(columnStorageKey, frozenEndColumnCount, columns.length));
|
|
22372
|
+
}, [columnStorageKey, columns.length, frozenEndColumnCount]);
|
|
22373
|
+
const resolvedColumnOrder = columnOrder ? normalizeColumnOrder2(defaultOrder, columnOrder) : internalColumnOrder;
|
|
22374
|
+
const resolvedColumnSizes = columnSizes ?? internalColumnSizes;
|
|
22375
|
+
const orderedColumns = getOrderedColumns2(columns, resolvedColumnOrder);
|
|
22376
|
+
const {
|
|
22377
|
+
startCount: resolvedFrozenColumnCount,
|
|
22378
|
+
endCount: resolvedFrozenEndColumnCount
|
|
22379
|
+
} = normalizeFrozenColumnCounts(internalFrozenColumnCount, internalFrozenEndColumnCount, orderedColumns.length);
|
|
22380
|
+
const frozenOffsets = buildFrozenOffsets(orderedColumns, resolvedColumnSizes, resolvedFrozenColumnCount);
|
|
22381
|
+
const frozenEndOffsets = buildFrozenEndOffsets(orderedColumns, resolvedColumnSizes, resolvedFrozenEndColumnCount);
|
|
22382
|
+
const resolvedMinWidth = tableMinWidth ?? Math.max(760, orderedColumns.reduce((total, column) => total + getColumnNumericWidth(column, resolvedColumnSizes), 0));
|
|
22383
|
+
const labels = {
|
|
22384
|
+
columnActions: columnMenuLabels?.columnActions ?? "Column actions",
|
|
22385
|
+
freezeColumn: columnMenuLabels?.freezeColumn ?? "Freeze to left",
|
|
22386
|
+
freezeEndColumn: columnMenuLabels?.freezeEndColumn ?? "Freeze to right",
|
|
22387
|
+
unfreezeColumn: columnMenuLabels?.unfreezeColumn ?? "Unfreeze from left",
|
|
22388
|
+
unfreezeEndColumn: columnMenuLabels?.unfreezeEndColumn ?? "Unfreeze from right",
|
|
22389
|
+
unfreezeAllColumns: columnMenuLabels?.unfreezeAllColumns ?? "Unfreeze all columns",
|
|
22390
|
+
resetColumnWidth: columnMenuLabels?.resetColumnWidth ?? "Reset column width",
|
|
22391
|
+
frozenColumnTitle: columnMenuLabels?.frozenColumnTitle ?? "Frozen column"
|
|
22392
|
+
};
|
|
22393
|
+
const handleColumnOrderChange = React.useCallback((nextOrder, detail) => {
|
|
22394
|
+
const normalizedOrder = normalizeColumnOrder2(defaultOrder, nextOrder);
|
|
22395
|
+
if (!columnOrder) {
|
|
22396
|
+
setInternalColumnOrder(normalizedOrder);
|
|
22397
|
+
}
|
|
22398
|
+
onColumnOrderChange?.(normalizedOrder, detail);
|
|
22399
|
+
}, [columnOrder, defaultOrder, onColumnOrderChange]);
|
|
22400
|
+
const handleColumnSizeChange = React.useCallback((columnId, width, detail) => {
|
|
22401
|
+
const column = columns.find((item) => item.key === columnId);
|
|
22402
|
+
const minWidth = column?.minWidth;
|
|
22403
|
+
const maxWidth = column?.maxWidth;
|
|
22404
|
+
const nextWidth = Math.max(
|
|
22405
|
+
typeof minWidth === "number" ? minWidth : 0,
|
|
22406
|
+
Math.min(width, typeof maxWidth === "number" ? maxWidth : Number.POSITIVE_INFINITY)
|
|
22407
|
+
);
|
|
22408
|
+
const nextSizes = {
|
|
22409
|
+
...resolvedColumnSizes,
|
|
22410
|
+
[columnId]: nextWidth
|
|
22411
|
+
};
|
|
22412
|
+
if (!columnSizes) {
|
|
22413
|
+
setInternalColumnSizes(nextSizes);
|
|
22414
|
+
}
|
|
22415
|
+
persistColumnSizes(columnStorageKey, nextSizes);
|
|
22416
|
+
onColumnSizeChange?.(columnId, nextWidth, detail);
|
|
22417
|
+
}, [columnSizes, columnStorageKey, columns, onColumnSizeChange, resolvedColumnSizes]);
|
|
22418
|
+
const handleResetColumnSize = React.useCallback((column) => {
|
|
22419
|
+
const nextWidth = defaultSizes[column.key] ?? getColumnDefaultSize(column);
|
|
22420
|
+
const previousWidth = getColumnNumericWidth(column, resolvedColumnSizes);
|
|
22421
|
+
const nextSizes = {
|
|
22422
|
+
...resolvedColumnSizes,
|
|
22423
|
+
[column.key]: nextWidth
|
|
22424
|
+
};
|
|
22425
|
+
if (!columnSizes) {
|
|
22426
|
+
setInternalColumnSizes(nextSizes);
|
|
22427
|
+
}
|
|
22428
|
+
persistColumnSizes(columnStorageKey, nextSizes);
|
|
22429
|
+
onColumnSizeChange?.(column.key, nextWidth, {
|
|
22430
|
+
columnId: column.key,
|
|
22431
|
+
previousWidth,
|
|
22432
|
+
minWidth: column.minWidth,
|
|
22433
|
+
maxWidth: column.maxWidth
|
|
22434
|
+
});
|
|
22435
|
+
onResetColumnSizes?.(nextSizes);
|
|
22436
|
+
}, [columnSizes, columnStorageKey, defaultSizes, onColumnSizeChange, onResetColumnSizes, resolvedColumnSizes]);
|
|
22437
|
+
const setFrozenColumnCount = React.useCallback((nextCount) => {
|
|
22438
|
+
const normalizedCount = clampFrozenColumnCount(nextCount, Math.max(0, orderedColumns.length - resolvedFrozenEndColumnCount));
|
|
22439
|
+
setInternalFrozenColumnCount(normalizedCount);
|
|
22440
|
+
persistFrozenColumnCount(columnStorageKey, normalizedCount);
|
|
22441
|
+
onFrozenColumnCountChange?.(normalizedCount);
|
|
22442
|
+
}, [columnStorageKey, onFrozenColumnCountChange, orderedColumns.length, resolvedFrozenEndColumnCount]);
|
|
22443
|
+
const setFrozenEndColumnCount = React.useCallback((nextCount) => {
|
|
22444
|
+
const normalizedCount = clampFrozenColumnCount(nextCount, Math.max(0, orderedColumns.length - resolvedFrozenColumnCount));
|
|
22445
|
+
setInternalFrozenEndColumnCount(normalizedCount);
|
|
22446
|
+
persistFrozenEndColumnCount(columnStorageKey, normalizedCount);
|
|
22447
|
+
onFrozenEndColumnCountChange?.(normalizedCount);
|
|
22448
|
+
}, [columnStorageKey, onFrozenEndColumnCountChange, orderedColumns.length, resolvedFrozenColumnCount]);
|
|
22449
|
+
const getFrozenPosition = (columnIndex) => {
|
|
22450
|
+
if (columnIndex < resolvedFrozenColumnCount) return "start";
|
|
22451
|
+
if (columnIndex >= orderedColumns.length - resolvedFrozenEndColumnCount) return "end";
|
|
22452
|
+
return void 0;
|
|
22453
|
+
};
|
|
22454
|
+
const getFrozenClassName = (column, columnIndex, isHeader = false) => {
|
|
22455
|
+
const position = getFrozenPosition(columnIndex);
|
|
22456
|
+
if (!position) return void 0;
|
|
22457
|
+
return cn(
|
|
22458
|
+
"sticky",
|
|
22459
|
+
position === "start" ? "shadow-[1px_0_0_0_hsl(var(--border)/0.45)]" : "shadow-[-1px_0_0_0_hsl(var(--border)/0.45)]",
|
|
22460
|
+
isHeader ? "bg-muted/60" : "bg-inherit",
|
|
22461
|
+
isHeader ? "z-40" : "z-20",
|
|
22462
|
+
(columnIndex === 0 || columnIndex === orderedColumns.length - 1) && (isHeader ? "z-50" : "z-30")
|
|
22463
|
+
);
|
|
22464
|
+
};
|
|
22465
|
+
const getFrozenStyle = (column, columnIndex) => {
|
|
22466
|
+
const position = getFrozenPosition(columnIndex);
|
|
22467
|
+
if (position === "start") return { left: frozenOffsets.get(column.key) ?? 0 };
|
|
22468
|
+
if (position === "end") return { right: frozenEndOffsets.get(column.key) ?? 0 };
|
|
22469
|
+
return void 0;
|
|
22470
|
+
};
|
|
22471
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
22472
|
+
BaseTableContainer,
|
|
22473
|
+
{
|
|
22474
|
+
appearance,
|
|
22475
|
+
className: cn("flex h-full min-h-0 flex-col overflow-hidden rounded-lg border border-border/60 bg-card", classNames?.root, className),
|
|
22476
|
+
style,
|
|
22477
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
22478
|
+
"div",
|
|
22479
|
+
{
|
|
22480
|
+
className: cn("min-h-0 flex-1 overflow-auto", classNames?.scrollArea),
|
|
22481
|
+
style: { maxHeight: toCssSize4(bodyMaxHeight) },
|
|
22482
|
+
children: /* @__PURE__ */ jsxRuntime.jsxs(
|
|
22483
|
+
BaseTable,
|
|
22484
|
+
{
|
|
22485
|
+
appearance,
|
|
22486
|
+
columnOrder: resolvedColumnOrder,
|
|
22487
|
+
columnSizes: resolvedColumnSizes,
|
|
22488
|
+
columnDragEnabled,
|
|
22489
|
+
columnResizeEnabled,
|
|
22490
|
+
onColumnOrderChange: handleColumnOrderChange,
|
|
22491
|
+
onColumnSizeChange: handleColumnSizeChange,
|
|
22492
|
+
className: cn("w-full table-fixed text-left text-xs", classNames?.table, tableClassName),
|
|
22493
|
+
style: { minWidth: resolvedMinWidth },
|
|
22494
|
+
children: [
|
|
22495
|
+
/* @__PURE__ */ jsxRuntime.jsx("colgroup", { children: orderedColumns.map((column) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
22496
|
+
"col",
|
|
22497
|
+
{
|
|
22498
|
+
style: {
|
|
22499
|
+
width: toCssSize4(resolvedColumnSizes[column.key] ?? column.width),
|
|
22500
|
+
minWidth: toCssSize4(column.minWidth)
|
|
22501
|
+
}
|
|
22502
|
+
},
|
|
22503
|
+
column.key
|
|
22504
|
+
)) }),
|
|
22505
|
+
/* @__PURE__ */ jsxRuntime.jsx(BaseTableHeader, { appearance, className: cn("border-b border-border/60 bg-muted/60 text-[11px] font-medium text-muted-foreground", classNames?.tableHeader), children: /* @__PURE__ */ jsxRuntime.jsx(BaseTableRow, { appearance, className: cn("hover:bg-transparent", classNames?.headerRow), children: orderedColumns.map((column, columnIndex) => {
|
|
22506
|
+
const headerContent = renderColumnHeader ? renderColumnHeader(column, { column, columnIndex, columns: orderedColumns, rows }) : column.label;
|
|
22507
|
+
const sortable = Boolean(column.sortable);
|
|
22508
|
+
const handleSort = sortable && onSort ? () => onSort(column.key, column) : void 0;
|
|
22509
|
+
const isFrozenStart = columnIndex < resolvedFrozenColumnCount;
|
|
22510
|
+
const isFrozenEnd = columnIndex >= orderedColumns.length - resolvedFrozenEndColumnCount;
|
|
22511
|
+
const isFrozen = isFrozenStart || isFrozenEnd;
|
|
22512
|
+
const isColumnAtDefaultWidth = getColumnNumericWidth(column, resolvedColumnSizes) === (defaultSizes[column.key] ?? getColumnDefaultSize(column));
|
|
22513
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(BaseContextMenu, { modal: false, children: [
|
|
22514
|
+
/* @__PURE__ */ jsxRuntime.jsx(BaseContextMenuTrigger, { asChild: true, appearance, children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
22515
|
+
BaseTableHead,
|
|
22516
|
+
{
|
|
22517
|
+
appearance,
|
|
22518
|
+
columnId: column.key,
|
|
22519
|
+
align: column.align,
|
|
22520
|
+
label: headerContent,
|
|
22521
|
+
description: column.description,
|
|
22522
|
+
trailing: isFrozen ? /* @__PURE__ */ jsxRuntime.jsx("span", { title: labels.frozenColumnTitle, className: "inline-flex h-5 w-5 items-center justify-center rounded text-primary", children: /* @__PURE__ */ jsxRuntime.jsx(PinIcon, { className: "h-3.5 w-3.5" }) }) : null,
|
|
22523
|
+
sortable,
|
|
22524
|
+
sortDirection: column.sortDirection,
|
|
22525
|
+
sortLabel: column.sortLabel,
|
|
22526
|
+
onSort: handleSort,
|
|
22527
|
+
draggable: column.draggable,
|
|
22528
|
+
resizable: column.resizable,
|
|
22529
|
+
width: column.width,
|
|
22530
|
+
minWidth: column.minWidth,
|
|
22531
|
+
maxWidth: column.maxWidth,
|
|
22532
|
+
className: cn(
|
|
22533
|
+
"sticky top-0 h-9 whitespace-nowrap border-r border-border/50 bg-muted/60 px-2.5 py-2 backdrop-blur",
|
|
22534
|
+
getFrozenClassName(column, columnIndex, true),
|
|
22535
|
+
column.headerClassName,
|
|
22536
|
+
column.className,
|
|
22537
|
+
classNames?.headerCell
|
|
22538
|
+
),
|
|
22539
|
+
style: getFrozenStyle(column, columnIndex)
|
|
22540
|
+
}
|
|
22541
|
+
) }),
|
|
22542
|
+
/* @__PURE__ */ jsxRuntime.jsxs(BaseContextMenuContent, { appearance, alignOffset: -4, className: "min-w-44", children: [
|
|
22543
|
+
/* @__PURE__ */ jsxRuntime.jsx(BaseContextMenuLabel, { appearance, children: labels.columnActions }),
|
|
22544
|
+
isFrozen ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
22545
|
+
BaseContextMenuItem,
|
|
22546
|
+
{
|
|
22547
|
+
appearance,
|
|
22548
|
+
onSelect: () => {
|
|
22549
|
+
if (isFrozenEnd) setFrozenEndColumnCount(orderedColumns.length - columnIndex - 1);
|
|
22550
|
+
else setFrozenColumnCount(columnIndex);
|
|
22551
|
+
},
|
|
22552
|
+
children: isFrozenEnd ? labels.unfreezeEndColumn : labels.unfreezeColumn
|
|
22553
|
+
}
|
|
22554
|
+
) : /* @__PURE__ */ jsxRuntime.jsx(
|
|
22555
|
+
BaseContextMenuItem,
|
|
22556
|
+
{
|
|
22557
|
+
appearance,
|
|
22558
|
+
onSelect: () => setFrozenColumnCount(columnIndex + 1),
|
|
22559
|
+
children: labels.freezeColumn
|
|
22560
|
+
}
|
|
22561
|
+
),
|
|
22562
|
+
!isFrozen ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
22563
|
+
BaseContextMenuItem,
|
|
22564
|
+
{
|
|
22565
|
+
appearance,
|
|
22566
|
+
onSelect: () => setFrozenEndColumnCount(orderedColumns.length - columnIndex),
|
|
22567
|
+
children: labels.freezeEndColumn
|
|
22568
|
+
}
|
|
22569
|
+
) : null,
|
|
22570
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
22571
|
+
BaseContextMenuItem,
|
|
22572
|
+
{
|
|
22573
|
+
appearance,
|
|
22574
|
+
disabled: resolvedFrozenColumnCount === 0 && resolvedFrozenEndColumnCount === 0,
|
|
22575
|
+
onSelect: () => {
|
|
22576
|
+
setFrozenColumnCount(0);
|
|
22577
|
+
setFrozenEndColumnCount(0);
|
|
22578
|
+
},
|
|
22579
|
+
children: labels.unfreezeAllColumns
|
|
22580
|
+
}
|
|
22581
|
+
),
|
|
22582
|
+
/* @__PURE__ */ jsxRuntime.jsx(BaseContextMenuSeparator, { appearance }),
|
|
22583
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
22584
|
+
BaseContextMenuItem,
|
|
22585
|
+
{
|
|
22586
|
+
appearance,
|
|
22587
|
+
disabled: isColumnAtDefaultWidth,
|
|
22588
|
+
onSelect: () => handleResetColumnSize(column),
|
|
22589
|
+
children: labels.resetColumnWidth
|
|
22590
|
+
}
|
|
22591
|
+
)
|
|
22592
|
+
] })
|
|
22593
|
+
] }, column.key);
|
|
22594
|
+
}) }) }),
|
|
22595
|
+
/* @__PURE__ */ jsxRuntime.jsxs(BaseTableBody, { appearance, className: cn("divide-y divide-border/50", classNames?.body), children: [
|
|
22596
|
+
pinnedTopRows.map((row, rowIndex) => {
|
|
22597
|
+
const key = getPinnedTopRowKey(row, rowIndex);
|
|
22598
|
+
const resolvedRowClassName = resolveRowClassName(pinnedTopRowClassName, row, rowIndex);
|
|
22599
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
22600
|
+
BaseTableRow,
|
|
22601
|
+
{
|
|
22602
|
+
appearance,
|
|
22603
|
+
className: cn("bg-card/95", classNames?.pinnedTopRow, resolvedRowClassName),
|
|
22604
|
+
children: orderedColumns.map((column, columnIndex) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
22605
|
+
BaseTableCell,
|
|
22606
|
+
{
|
|
22607
|
+
appearance,
|
|
22608
|
+
align: column.align,
|
|
22609
|
+
className: cn(
|
|
22610
|
+
"h-[52px] border-r border-border/50 px-2.5 py-1.5 align-middle",
|
|
22611
|
+
column.wrap ? "whitespace-normal" : "whitespace-nowrap",
|
|
22612
|
+
getFrozenClassName(column, columnIndex),
|
|
22613
|
+
column.cellClassName,
|
|
22614
|
+
classNames?.cell
|
|
22615
|
+
),
|
|
22616
|
+
style: getFrozenStyle(column, columnIndex),
|
|
22617
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(InteractiveTableCellContent, { wrap: column.wrap, children: renderPinnedTopCell ? renderPinnedTopCell(column, row, { row, rowIndex, column, columnIndex, isPinnedTopRow: true }) : renderDefaultCell(column, row) })
|
|
22618
|
+
},
|
|
22619
|
+
`pinned-${key}-${column.key}`
|
|
22620
|
+
))
|
|
22621
|
+
},
|
|
22622
|
+
`pinned-${key}`
|
|
22623
|
+
);
|
|
22624
|
+
}),
|
|
22625
|
+
rows.length ? rows.map((row, rowIndex) => {
|
|
22626
|
+
const key = getRowKey(row, rowIndex);
|
|
22627
|
+
const state = getRowState?.(row, rowIndex) || {};
|
|
22628
|
+
const resolvedRowClassName = resolveRowClassName(rowClassName, row, rowIndex);
|
|
22629
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
22630
|
+
BaseTableRow,
|
|
22631
|
+
{
|
|
22632
|
+
appearance,
|
|
22633
|
+
interactive: Boolean(onRowClick) && !state.disabled,
|
|
22634
|
+
selected: state.selected,
|
|
22635
|
+
disabled: state.disabled,
|
|
22636
|
+
onClick: () => {
|
|
22637
|
+
if (!state.disabled) onRowClick?.(row, rowIndex);
|
|
22638
|
+
},
|
|
22639
|
+
className: cn(
|
|
22640
|
+
"min-h-[52px] bg-card transition-colors",
|
|
22641
|
+
state.saving && "bg-primary/5",
|
|
22642
|
+
state.pending && "opacity-80",
|
|
22643
|
+
onRowClick && !state.disabled ? "cursor-pointer hover:bg-muted/30" : "hover:bg-muted/30",
|
|
22644
|
+
classNames?.row,
|
|
22645
|
+
resolvedRowClassName
|
|
22646
|
+
),
|
|
22647
|
+
children: orderedColumns.map((column, columnIndex) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
22648
|
+
BaseTableCell,
|
|
22649
|
+
{
|
|
22650
|
+
appearance,
|
|
22651
|
+
align: column.align,
|
|
22652
|
+
className: cn(
|
|
22653
|
+
"h-[52px] border-r border-border/50 px-2.5 py-1.5 align-middle",
|
|
22654
|
+
column.wrap ? "whitespace-normal" : "whitespace-nowrap",
|
|
22655
|
+
getFrozenClassName(column, columnIndex),
|
|
22656
|
+
column.cellClassName,
|
|
22657
|
+
classNames?.cell
|
|
22658
|
+
),
|
|
22659
|
+
style: getFrozenStyle(column, columnIndex),
|
|
22660
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(InteractiveTableCellContent, { wrap: column.wrap, children: renderCell ? renderCell(column, row, { row, rowIndex, column, columnIndex, isPinnedTopRow: false }) : renderDefaultCell(column, row) })
|
|
22661
|
+
},
|
|
22662
|
+
`${key}-${column.key}`
|
|
22663
|
+
))
|
|
22664
|
+
},
|
|
22665
|
+
key
|
|
22666
|
+
);
|
|
22667
|
+
}) : pinnedTopRows.length ? null : /* @__PURE__ */ jsxRuntime.jsx(
|
|
22668
|
+
BaseTableEmpty,
|
|
22669
|
+
{
|
|
22670
|
+
appearance,
|
|
22671
|
+
colSpan: Math.max(orderedColumns.length, 1),
|
|
22672
|
+
className: classNames?.empty,
|
|
22673
|
+
children: emptyState
|
|
22674
|
+
}
|
|
22675
|
+
)
|
|
22676
|
+
] })
|
|
22677
|
+
]
|
|
22678
|
+
}
|
|
22679
|
+
)
|
|
22680
|
+
}
|
|
22681
|
+
)
|
|
22682
|
+
}
|
|
22683
|
+
);
|
|
22684
|
+
}
|
|
22685
|
+
function InteractiveTableEditableTextCell({
|
|
22686
|
+
value,
|
|
22687
|
+
placeholder,
|
|
22688
|
+
disabled,
|
|
22689
|
+
multiline = false,
|
|
22690
|
+
commitOnBlur = true,
|
|
22691
|
+
className,
|
|
22692
|
+
inputClassName,
|
|
22693
|
+
onCommit
|
|
22694
|
+
}) {
|
|
22695
|
+
const initialValue = String(value || "");
|
|
22696
|
+
const [draft, setDraft] = React.useState(initialValue);
|
|
22697
|
+
React.useEffect(() => {
|
|
22698
|
+
setDraft(initialValue);
|
|
22699
|
+
}, [initialValue]);
|
|
22700
|
+
const commit = React.useCallback(async () => {
|
|
22701
|
+
const nextValue = String(draft || "").trim();
|
|
22702
|
+
const previousValue = String(initialValue || "").trim();
|
|
22703
|
+
if (nextValue === previousValue) return;
|
|
22704
|
+
try {
|
|
22705
|
+
await onCommit?.(nextValue);
|
|
22706
|
+
} catch {
|
|
22707
|
+
setDraft(initialValue);
|
|
22708
|
+
}
|
|
22709
|
+
}, [draft, initialValue, onCommit]);
|
|
22710
|
+
const controlClassName = cn(
|
|
22711
|
+
"w-full resize-none rounded-sm border border-transparent bg-transparent px-1.5 py-1 text-xs text-foreground outline-none transition-colors",
|
|
22712
|
+
"placeholder:text-muted-foreground/70 hover:border-border/60 hover:bg-background focus:border-primary/45 focus:bg-background",
|
|
22713
|
+
multiline ? "min-h-[42px] leading-5" : "h-8",
|
|
22714
|
+
disabled && "cursor-not-allowed text-muted-foreground hover:border-transparent hover:bg-transparent",
|
|
22715
|
+
inputClassName
|
|
22716
|
+
);
|
|
22717
|
+
if (multiline) {
|
|
22718
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
22719
|
+
"textarea",
|
|
22720
|
+
{
|
|
22721
|
+
className: cn(controlClassName, className),
|
|
22722
|
+
disabled,
|
|
22723
|
+
value: draft,
|
|
22724
|
+
placeholder,
|
|
22725
|
+
onChange: (event) => setDraft(event.target.value),
|
|
22726
|
+
onBlur: () => {
|
|
22727
|
+
if (commitOnBlur) void commit();
|
|
22728
|
+
},
|
|
22729
|
+
onKeyDown: (event) => {
|
|
22730
|
+
if ((event.metaKey || event.ctrlKey) && event.key === "Enter") {
|
|
22731
|
+
event.currentTarget.blur();
|
|
22732
|
+
}
|
|
22733
|
+
if (event.key === "Escape") {
|
|
22734
|
+
setDraft(initialValue);
|
|
22735
|
+
event.currentTarget.blur();
|
|
22736
|
+
}
|
|
22737
|
+
}
|
|
22738
|
+
}
|
|
22739
|
+
);
|
|
22740
|
+
}
|
|
22741
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
22742
|
+
"input",
|
|
22743
|
+
{
|
|
22744
|
+
className: cn(controlClassName, className),
|
|
22745
|
+
disabled,
|
|
22746
|
+
value: draft,
|
|
22747
|
+
placeholder,
|
|
22748
|
+
onChange: (event) => setDraft(event.target.value),
|
|
22749
|
+
onBlur: () => {
|
|
22750
|
+
if (commitOnBlur) void commit();
|
|
22751
|
+
},
|
|
22752
|
+
onKeyDown: (event) => {
|
|
22753
|
+
if (event.key === "Enter") event.currentTarget.blur();
|
|
22754
|
+
if (event.key === "Escape") {
|
|
22755
|
+
setDraft(initialValue);
|
|
22756
|
+
event.currentTarget.blur();
|
|
22757
|
+
}
|
|
22758
|
+
}
|
|
22759
|
+
}
|
|
22760
|
+
);
|
|
22761
|
+
}
|
|
22762
|
+
function InteractiveTableReadonlyCell({
|
|
22763
|
+
children,
|
|
22764
|
+
mono = false,
|
|
22765
|
+
className
|
|
22766
|
+
}) {
|
|
22767
|
+
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: cn("min-w-0 text-xs text-muted-foreground", mono && "font-mono", className), children: hasRenderableNode(children) ? children : "\u2014" });
|
|
22768
|
+
}
|
|
22769
|
+
function InteractiveTableSelectCell({
|
|
22770
|
+
value,
|
|
22771
|
+
options,
|
|
22772
|
+
disabled,
|
|
22773
|
+
ariaLabel,
|
|
22774
|
+
children,
|
|
22775
|
+
className,
|
|
22776
|
+
onChange
|
|
22777
|
+
}) {
|
|
22778
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cn("relative flex w-full items-center", className), children: [
|
|
22779
|
+
children,
|
|
22780
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
22781
|
+
"select",
|
|
22782
|
+
{
|
|
22783
|
+
"aria-label": ariaLabel,
|
|
22784
|
+
disabled,
|
|
22785
|
+
value,
|
|
22786
|
+
onChange: (event) => onChange?.(event.target.value),
|
|
22787
|
+
className: "absolute inset-0 h-full w-full cursor-pointer opacity-0 disabled:cursor-not-allowed",
|
|
22788
|
+
children: options.map((option) => /* @__PURE__ */ jsxRuntime.jsx("option", { value: option.value, children: option.label }, option.value))
|
|
22789
|
+
}
|
|
22790
|
+
)
|
|
22791
|
+
] });
|
|
22792
|
+
}
|
|
22793
|
+
var imageExtPattern = /\.(png|jpe?g|webp|gif|svg|bmp|avif)$/i;
|
|
22794
|
+
var audioExtPattern = /\.(wav|mp3|ogg|m4a|flac|aac)$/i;
|
|
22795
|
+
var isLikelyUrl = (value) => /^https?:\/\//i.test(String(value || ""));
|
|
22796
|
+
var getColumnRenderKind = (column) => String(column?.renderType || column?.type || "").toLowerCase();
|
|
22797
|
+
var isImageLikeValue = (value) => String(value || "").startsWith("data:image/") || imageExtPattern.test(String(value || ""));
|
|
22798
|
+
var isAudioLikeValue = (value) => String(value || "").startsWith("data:audio/") || audioExtPattern.test(String(value || ""));
|
|
22799
|
+
var escapeSvgText = (value) => String(value || "").replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">");
|
|
22800
|
+
var getDefaultGalleryFieldValue = (column, row) => {
|
|
22801
|
+
if (!column) return null;
|
|
22802
|
+
return row?.[column.key] ?? null;
|
|
22803
|
+
};
|
|
22804
|
+
var getDefaultGalleryDisplayText = (value) => {
|
|
22805
|
+
if (value === null || value === void 0 || value === "") return "\u2014";
|
|
22806
|
+
if (Array.isArray(value)) {
|
|
22807
|
+
const parts = value.map((item) => {
|
|
22808
|
+
if (typeof item === "string") return item;
|
|
22809
|
+
if (!item || typeof item !== "object") return "";
|
|
22810
|
+
const objectItem = item;
|
|
22811
|
+
return objectItem.text || objectItem.label || objectItem.title || objectItem.display || objectItem.value || objectItem.recordId || "";
|
|
22812
|
+
}).filter(Boolean);
|
|
22813
|
+
return parts.join(" \xB7 ") || "\u2014";
|
|
22814
|
+
}
|
|
22815
|
+
if (typeof value === "object") {
|
|
22816
|
+
const objectValue = value;
|
|
22817
|
+
return String(objectValue.text || objectValue.label || objectValue.title || objectValue.display || objectValue.value || "\u2014");
|
|
22818
|
+
}
|
|
22819
|
+
return String(value);
|
|
22820
|
+
};
|
|
22821
|
+
var isDefaultGalleryImageField = (column = { key: "" }, value) => getColumnRenderKind(column) === "image" || isImageLikeValue(value);
|
|
22822
|
+
var isDefaultGalleryAudioField = (column = { key: "" }, value) => getColumnRenderKind(column) === "audio" || isAudioLikeValue(value);
|
|
22823
|
+
var getDefaultGalleryImagePreviewSrc = (value, rowId, columnLabel) => {
|
|
22824
|
+
if (isLikelyUrl(value) || String(value || "").startsWith("data:image/")) return String(value);
|
|
22825
|
+
const title = escapeSvgText(value || columnLabel || rowId || "");
|
|
22826
|
+
const titleText = title ? `<text x='68' y='450' fill='white' font-family='Inter, Arial' font-size='52' font-weight='700'>${title}</text>` : "";
|
|
22827
|
+
const svg = `<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 960 540'><defs><linearGradient id='g' x1='0' y1='0' x2='1' y2='1'><stop offset='0%' stop-color='#0f172a'/><stop offset='55%' stop-color='#1d4ed8'/><stop offset='100%' stop-color='#14b8a6'/></linearGradient></defs><rect width='960' height='540' fill='url(#g)'/><g opacity='0.28'><circle cx='780' cy='130' r='150' fill='#67e8f9'/><circle cx='180' cy='430' r='170' fill='#a78bfa'/></g>${titleText}</svg>`;
|
|
22828
|
+
return `data:image/svg+xml;utf8,${encodeURIComponent(svg)}`;
|
|
22829
|
+
};
|
|
22830
|
+
var isDefaultGalleryMediaColumn = (column, row, {
|
|
22831
|
+
getFieldValue = getDefaultGalleryFieldValue,
|
|
22832
|
+
shouldEnhanceMultimodal = true,
|
|
22833
|
+
isImageField = isDefaultGalleryImageField,
|
|
22834
|
+
isAudioField = isDefaultGalleryAudioField
|
|
22835
|
+
} = {}) => {
|
|
22836
|
+
if (!column || !shouldEnhanceMultimodal) return false;
|
|
22837
|
+
const value = getFieldValue(column, row);
|
|
22838
|
+
return isImageField(column, value) || isAudioField(column, value);
|
|
22839
|
+
};
|
|
22840
|
+
var isDefaultGalleryTitleCandidate = (column, row, { isMediaColumn = () => false } = {}) => {
|
|
22841
|
+
if (!column || column.renderType === "icon") return false;
|
|
22842
|
+
return !isMediaColumn(column, row);
|
|
22843
|
+
};
|
|
22844
|
+
var isDefaultGallerySummaryCandidate = (column, row, { isMediaColumn = () => false } = {}) => {
|
|
22845
|
+
if (!column || column.renderType === "icon") return false;
|
|
22846
|
+
return !isMediaColumn(column, row);
|
|
22847
|
+
};
|
|
22848
|
+
var renderDefaultGalleryFieldValue = (column, row, {
|
|
22849
|
+
compact = false,
|
|
22850
|
+
getFieldValue = getDefaultGalleryFieldValue,
|
|
22851
|
+
getDisplayText = getDefaultGalleryDisplayText
|
|
22852
|
+
} = {}) => {
|
|
22853
|
+
const value = getFieldValue(column, row);
|
|
22854
|
+
return /* @__PURE__ */ jsxRuntime.jsx("span", { className: cn("leading-relaxed", compact && column?.wrap === true && "line-clamp-2 block"), children: getDisplayText(value) });
|
|
22855
|
+
};
|
|
22856
|
+
var getDefaultGalleryDetailLimit = (density) => {
|
|
22857
|
+
if (density === "compact") return 2;
|
|
22858
|
+
if (density === "detailed") return 6;
|
|
22859
|
+
return 4;
|
|
22860
|
+
};
|
|
22861
|
+
var getNormalizedGalleryBentoColumns = (columns, density) => {
|
|
22862
|
+
if (columns === 1 || columns === 2 || columns === 3) return Number(columns);
|
|
22863
|
+
return density === "detailed" ? 1 : 2;
|
|
22864
|
+
};
|
|
22865
|
+
var getNormalizedGalleryDetailLimit = ({
|
|
22866
|
+
density,
|
|
22867
|
+
visibility,
|
|
22868
|
+
limit
|
|
22869
|
+
}) => {
|
|
22870
|
+
if (visibility === "all") return Number.POSITIVE_INFINITY;
|
|
22871
|
+
const parsedLimit = Number.parseInt(String(limit), 10);
|
|
22872
|
+
if (Number.isFinite(parsedLimit) && parsedLimit > 0) return parsedLimit;
|
|
22873
|
+
return getDefaultGalleryDetailLimit(density);
|
|
22874
|
+
};
|
|
22875
|
+
var getGalleryCardPaddingClassName = (density) => {
|
|
22876
|
+
if (density === "compact") return "p-3";
|
|
22877
|
+
if (density === "detailed") return "p-4";
|
|
22878
|
+
return "p-3.5";
|
|
22879
|
+
};
|
|
22880
|
+
var getGalleryPreviewClassName = (density, isMasonry) => {
|
|
22881
|
+
if (isMasonry) return "h-auto w-full object-cover";
|
|
22882
|
+
if (density === "compact") return "h-32 w-full object-cover";
|
|
22883
|
+
if (density === "detailed") return "h-48 w-full object-cover";
|
|
22884
|
+
return "h-40 w-full object-cover";
|
|
22885
|
+
};
|
|
22886
|
+
var getGalleryDetailGridClassName = (columns) => {
|
|
22887
|
+
if (columns === 1) return "grid-cols-1";
|
|
22888
|
+
if (columns === 3) return "grid-cols-1 sm:grid-cols-2 2xl:grid-cols-3";
|
|
22889
|
+
return "grid-cols-1 sm:grid-cols-2";
|
|
22890
|
+
};
|
|
22891
|
+
function getIconComponent(icon) {
|
|
22892
|
+
return getWorkbenchIconComponent(icon);
|
|
22893
|
+
}
|
|
22894
|
+
function defaultFormatLabel2(value) {
|
|
22895
|
+
return value;
|
|
22896
|
+
}
|
|
22897
|
+
function getLabelText(value) {
|
|
22898
|
+
if (typeof value === "string" || typeof value === "number") return String(value);
|
|
22899
|
+
return "";
|
|
22900
|
+
}
|
|
22901
|
+
function WorkbenchGalleryCard({
|
|
22902
|
+
row,
|
|
22903
|
+
columns,
|
|
22904
|
+
onClick = () => {
|
|
22905
|
+
},
|
|
22906
|
+
isSelected = false,
|
|
22907
|
+
isMasonry = false,
|
|
22908
|
+
galleryFieldKey = "auto",
|
|
22909
|
+
galleryDensity = "comfortable",
|
|
22910
|
+
galleryBentoColumns,
|
|
22911
|
+
galleryDetailVisibility = "limit",
|
|
22912
|
+
galleryDetailLimit,
|
|
22913
|
+
shouldEnhanceMultimodal = true,
|
|
22914
|
+
getFieldValue,
|
|
22915
|
+
isMediaColumn,
|
|
22916
|
+
isTitleCandidate,
|
|
22917
|
+
isSummaryCandidate,
|
|
22918
|
+
getDisplayText,
|
|
22919
|
+
renderFieldValue,
|
|
22920
|
+
getImagePreviewSrc,
|
|
22921
|
+
isImageField,
|
|
22922
|
+
isAudioField,
|
|
22923
|
+
AudioPlayerComponent,
|
|
22924
|
+
cardVariant = "default",
|
|
22925
|
+
renderPreview,
|
|
22926
|
+
renderMeta,
|
|
22927
|
+
renderLeadingVisual,
|
|
22928
|
+
resolveRecordVisual,
|
|
22929
|
+
hiddenDetailFieldKeys = [],
|
|
22930
|
+
labels,
|
|
22931
|
+
formatLabel = defaultFormatLabel2,
|
|
22932
|
+
className
|
|
22933
|
+
}) {
|
|
22934
|
+
const resolvedGetFieldValue = getFieldValue || getDefaultGalleryFieldValue;
|
|
22935
|
+
const resolvedGetDisplayText = getDisplayText || getDefaultGalleryDisplayText;
|
|
22936
|
+
const resolvedIsImageField = isImageField || isDefaultGalleryImageField;
|
|
22937
|
+
const resolvedIsAudioField = isAudioField || isDefaultGalleryAudioField;
|
|
22938
|
+
const resolvedGetImagePreviewSrc = getImagePreviewSrc || getDefaultGalleryImagePreviewSrc;
|
|
22939
|
+
const resolvedIsMediaColumn = isMediaColumn || ((column, candidateRow) => isDefaultGalleryMediaColumn(column, candidateRow, {
|
|
22940
|
+
getFieldValue: resolvedGetFieldValue,
|
|
22941
|
+
shouldEnhanceMultimodal,
|
|
22942
|
+
isImageField: resolvedIsImageField,
|
|
22943
|
+
isAudioField: resolvedIsAudioField
|
|
22944
|
+
}));
|
|
22945
|
+
const resolvedIsTitleCandidate = isTitleCandidate || ((column, candidateRow) => isDefaultGalleryTitleCandidate(column, candidateRow, { isMediaColumn: resolvedIsMediaColumn }));
|
|
22946
|
+
const resolvedIsSummaryCandidate = isSummaryCandidate || ((column, candidateRow) => isDefaultGallerySummaryCandidate(column, candidateRow, { isMediaColumn: resolvedIsMediaColumn }));
|
|
22947
|
+
const resolvedRenderFieldValue = renderFieldValue || ((column, candidateRow, { compact } = {}) => renderDefaultGalleryFieldValue(column, candidateRow, {
|
|
22948
|
+
compact,
|
|
22949
|
+
getFieldValue: resolvedGetFieldValue,
|
|
22950
|
+
getDisplayText: resolvedGetDisplayText
|
|
22951
|
+
}));
|
|
22952
|
+
const isPreviewOnly = cardVariant === "preview-only";
|
|
22953
|
+
const isImageOnly = cardVariant === "image-only";
|
|
22954
|
+
const isChromaticBento = cardVariant === "chromatic-bento";
|
|
22955
|
+
const selectedGalleryColumn = galleryFieldKey !== "auto" ? columns.find((column) => column.key === galleryFieldKey && resolvedIsMediaColumn(column, row)) : null;
|
|
22956
|
+
const mediaColumn = selectedGalleryColumn || (shouldEnhanceMultimodal ? columns.find((column) => resolvedIsMediaColumn(column, row)) : null);
|
|
22957
|
+
const iconColumn = columns.find((column) => column.renderType === "icon");
|
|
22958
|
+
const iconVisual = iconColumn && resolveRecordVisual ? resolveRecordVisual(row[iconColumn.key], row, iconColumn) : null;
|
|
22959
|
+
const IconComponent = getIconComponent(iconVisual?.Icon || iconVisual?.icon);
|
|
22960
|
+
const mediaValue = mediaColumn ? resolvedGetFieldValue(mediaColumn, row) : null;
|
|
22961
|
+
const isImageMedia = mediaColumn ? resolvedIsImageField(mediaColumn, mediaValue) : false;
|
|
22962
|
+
const isAudioMedia = mediaColumn ? resolvedIsAudioField(mediaColumn, mediaValue) : false;
|
|
22963
|
+
const contentColumns = columns.filter((column) => column.key !== mediaColumn?.key && column.renderType !== "icon");
|
|
22964
|
+
const titleCandidates = contentColumns.filter((column) => {
|
|
22965
|
+
if (!column || resolvedIsMediaColumn(column, row) || !resolvedIsTitleCandidate(column, row)) return false;
|
|
22966
|
+
const value = resolvedGetFieldValue(column, row);
|
|
22967
|
+
return !(value === null || value === void 0 || value === "");
|
|
22968
|
+
});
|
|
22969
|
+
const titleColumn = titleCandidates[0] || null;
|
|
22970
|
+
const titleText = titleColumn ? resolvedGetDisplayText(resolvedGetFieldValue(titleColumn, row)) : resolvedGetDisplayText(row.linkKey || row.id);
|
|
22971
|
+
const summaryColumn = contentColumns.find((column) => {
|
|
22972
|
+
if (!column || column.key === titleColumn?.key || resolvedIsMediaColumn(column, row) || !resolvedIsSummaryCandidate(column, row)) return false;
|
|
22973
|
+
const summaryText2 = String(resolvedGetDisplayText(resolvedGetFieldValue(column, row)));
|
|
22974
|
+
return summaryText2 !== "\u2014" && summaryText2.length > 12;
|
|
22975
|
+
}) || contentColumns.find((column) => {
|
|
22976
|
+
if (!column || column.key === titleColumn?.key || resolvedIsMediaColumn(column, row) || !resolvedIsSummaryCandidate(column, row)) return false;
|
|
22977
|
+
const fallbackText = String(resolvedGetDisplayText(resolvedGetFieldValue(column, row)));
|
|
22978
|
+
return fallbackText !== "\u2014";
|
|
22979
|
+
}) || null;
|
|
22980
|
+
const summaryText = summaryColumn ? resolvedGetDisplayText(resolvedGetFieldValue(summaryColumn, row)) : "";
|
|
22981
|
+
const hiddenDetailKeySet = new Set(hiddenDetailFieldKeys);
|
|
22982
|
+
const detailColumns = contentColumns.filter((column) => column.key !== titleColumn?.key && column.key !== summaryColumn?.key && !hiddenDetailKeySet.has(column.key));
|
|
22983
|
+
const resolvedDetailLimit = getNormalizedGalleryDetailLimit({
|
|
22984
|
+
density: galleryDensity,
|
|
22985
|
+
visibility: galleryDetailVisibility,
|
|
22986
|
+
limit: galleryDetailLimit
|
|
22987
|
+
});
|
|
22988
|
+
const visibleDetailColumns = Number.isFinite(resolvedDetailLimit) ? detailColumns.slice(0, resolvedDetailLimit) : detailColumns;
|
|
22989
|
+
const isDetailedCard = galleryDensity === "detailed";
|
|
22990
|
+
const resolvedBentoColumns = getNormalizedGalleryBentoColumns(galleryBentoColumns, galleryDensity);
|
|
22991
|
+
const cardPaddingClassName = getGalleryCardPaddingClassName(galleryDensity);
|
|
22992
|
+
const detailGridClassName = getGalleryDetailGridClassName(resolvedBentoColumns);
|
|
22993
|
+
const previewClassName = isImageOnly ? "block h-auto w-full transition-transform duration-500 group-hover:scale-[1.02]" : getGalleryPreviewClassName(galleryDensity, isMasonry);
|
|
22994
|
+
const customPreview = typeof renderPreview === "function" ? renderPreview({
|
|
22995
|
+
row,
|
|
22996
|
+
mediaColumn,
|
|
22997
|
+
mediaValue,
|
|
22998
|
+
isImageMedia,
|
|
22999
|
+
isAudioMedia,
|
|
23000
|
+
iconVisual,
|
|
23001
|
+
IconComponent,
|
|
23002
|
+
previewClassName
|
|
23003
|
+
}) : null;
|
|
23004
|
+
const metaContent = typeof renderMeta === "function" ? renderMeta({
|
|
23005
|
+
row,
|
|
23006
|
+
contentColumns,
|
|
23007
|
+
detailColumns,
|
|
23008
|
+
titleColumn,
|
|
23009
|
+
summaryColumn,
|
|
23010
|
+
getDisplayText: resolvedGetDisplayText,
|
|
23011
|
+
getFieldValue: resolvedGetFieldValue
|
|
23012
|
+
}) : null;
|
|
23013
|
+
const customLeadingVisual = typeof renderLeadingVisual === "function" ? renderLeadingVisual({
|
|
23014
|
+
row,
|
|
23015
|
+
contentColumns,
|
|
23016
|
+
detailColumns,
|
|
23017
|
+
titleColumn,
|
|
23018
|
+
summaryColumn,
|
|
23019
|
+
iconVisual,
|
|
23020
|
+
getDisplayText: resolvedGetDisplayText,
|
|
23021
|
+
getFieldValue: resolvedGetFieldValue
|
|
23022
|
+
}) : null;
|
|
23023
|
+
const defaultLeadingVisual = !customLeadingVisual && iconVisual ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: cn("flex h-9 w-9 items-center justify-center rounded-lg border", iconVisual.chipClassName || "border-primary/20 bg-primary/10 text-primary"), children: renderWorkbenchIcon(iconVisual.Icon || iconVisual.icon, cn("h-4 w-4", iconVisual.iconClassName || "text-primary")) }) : null;
|
|
23024
|
+
const leadingVisual = customLeadingVisual || defaultLeadingVisual;
|
|
23025
|
+
const defaultMetaClassName = isChromaticBento ? "shrink-0 rounded-full border border-border/40 bg-muted/25 px-2.5 py-1 text-[10px] text-muted-foreground transition-all duration-300 group-hover:border-primary/30 group-hover:bg-primary/10 group-hover:text-primary dark:border-border/35 dark:bg-muted/15" : "shrink-0 rounded-md border border-border/40 bg-muted/25 px-2 py-1 text-[10px] text-muted-foreground dark:border-border/35 dark:bg-muted/15";
|
|
23026
|
+
const detailCellClassName = isChromaticBento ? "rounded-xl border border-border/35 bg-muted/20 px-3 py-2.5 transition-all duration-300 group-hover:border-primary/25 group-hover:bg-primary/5 dark:border-border/30 dark:bg-muted/10" : "rounded-lg border border-border/35 bg-muted/20 px-2.5 py-2 dark:border-border/30 dark:bg-muted/10";
|
|
23027
|
+
const detailLabelClassName = isChromaticBento ? "text-[10px] uppercase tracking-[0.14em] text-muted-foreground transition-colors duration-300 group-hover:text-foreground" : "text-[10px] uppercase tracking-[0.12em] text-muted-foreground";
|
|
23028
|
+
const detailValueClassName = isChromaticBento ? "mt-1.5 text-[11px] text-muted-foreground transition-colors duration-300 group-hover:text-foreground [&_*]:max-w-full [&_pre]:text-[11px] [&_pre]:leading-relaxed" : "mt-1.5 text-[11px] text-foreground [&_*]:max-w-full [&_pre]:text-[11px] [&_pre]:leading-relaxed";
|
|
23029
|
+
const fieldCountLabel = labels?.fieldCount?.(contentColumns.length);
|
|
23030
|
+
const coverOnlyHint = labels?.coverOnlyHint;
|
|
23031
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
23032
|
+
"button",
|
|
23033
|
+
{
|
|
23034
|
+
type: "button",
|
|
23035
|
+
onClick,
|
|
23036
|
+
"aria-label": getLabelText(titleText),
|
|
23037
|
+
className: cn(
|
|
23038
|
+
"group relative w-full text-left transition-all duration-300",
|
|
23039
|
+
isImageOnly ? "overflow-hidden rounded-xl bg-transparent p-0 shadow-none" : isPreviewOnly ? "overflow-hidden rounded-3xl bg-transparent p-0" : cn("overflow-hidden rounded-xl border", isChromaticBento && "rounded-3xl shadow-none"),
|
|
23040
|
+
!isPreviewOnly && !isImageOnly && cardPaddingClassName,
|
|
23041
|
+
!isPreviewOnly && !isImageOnly && (isSelected ? isChromaticBento ? "border-primary/35 bg-background/85 ring-1 ring-primary/20" : "border-primary/40 bg-primary/10 ring-1 ring-primary/30" : isChromaticBento ? "workbench-surface-card hover:-translate-y-1 hover:border-primary/20" : "workbench-surface-card hover:border-primary/30"),
|
|
23042
|
+
isPreviewOnly && isSelected && "ring-1 ring-primary/30",
|
|
23043
|
+
isImageOnly && (isSelected ? "ring-1 ring-primary/30" : "hover:-translate-y-0.5"),
|
|
23044
|
+
isMasonry ? "block h-full w-full min-w-0" : "h-full min-w-0",
|
|
23045
|
+
className
|
|
23046
|
+
),
|
|
23047
|
+
children: [
|
|
23048
|
+
isChromaticBento ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
23049
|
+
"div",
|
|
23050
|
+
{
|
|
23051
|
+
"aria-hidden": "true",
|
|
23052
|
+
className: cn(
|
|
23053
|
+
"pointer-events-none absolute inset-0 bg-[radial-gradient(circle_at_top_right,rgba(34,211,238,0.18),transparent_40%),radial-gradient(circle_at_bottom_left,rgba(16,185,129,0.12),transparent_45%)] opacity-0 transition-opacity duration-300",
|
|
23054
|
+
isSelected ? "opacity-100" : "group-hover:opacity-100"
|
|
23055
|
+
)
|
|
23056
|
+
}
|
|
23057
|
+
) : null,
|
|
23058
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative z-[1]", children: [
|
|
23059
|
+
customPreview ?? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
23060
|
+
isImageMedia && mediaColumn ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: cn(
|
|
23061
|
+
"overflow-hidden bg-card/50",
|
|
23062
|
+
isImageOnly ? "rounded-xl bg-transparent" : isPreviewOnly ? "rounded-3xl" : "mb-3 rounded-lg border border-border/70"
|
|
23063
|
+
), children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
23064
|
+
"img",
|
|
23065
|
+
{
|
|
23066
|
+
src: resolvedGetImagePreviewSrc(mediaValue, row.id, mediaColumn.label),
|
|
23067
|
+
alt: String(mediaValue || mediaColumn.label || ""),
|
|
23068
|
+
className: previewClassName,
|
|
23069
|
+
loading: "lazy",
|
|
23070
|
+
referrerPolicy: "no-referrer",
|
|
23071
|
+
onError: (event) => {
|
|
23072
|
+
event.currentTarget.onerror = null;
|
|
23073
|
+
event.currentTarget.src = resolvedGetImagePreviewSrc("", row.id, mediaColumn.label);
|
|
23074
|
+
}
|
|
23075
|
+
}
|
|
23076
|
+
) }) : null,
|
|
23077
|
+
!isImageMedia && iconVisual && isPreviewOnly ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: cn(
|
|
23078
|
+
"flex items-center justify-center",
|
|
23079
|
+
isPreviewOnly ? cn("rounded-3xl border py-10", iconVisual.chipClassName || "border-primary/20 bg-primary/5") : "mb-3 h-24 rounded-lg border border-border/60 bg-primary/5"
|
|
23080
|
+
), children: renderWorkbenchIcon(iconVisual.Icon || iconVisual.icon, cn("h-10 w-10", iconVisual.iconClassName || "text-primary")) }) : null,
|
|
23081
|
+
isAudioMedia && AudioPlayerComponent ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: cn(!isPreviewOnly && "mb-3"), children: /* @__PURE__ */ jsxRuntime.jsx(AudioPlayerComponent, { filename: String(mediaValue) }) }) : null
|
|
23082
|
+
] }),
|
|
23083
|
+
!isPreviewOnly && !isImageOnly ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
23084
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-start gap-3", children: [
|
|
23085
|
+
leadingVisual ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "shrink-0", children: leadingVisual }) : null,
|
|
23086
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex min-w-0 flex-1 items-start justify-between gap-3", children: [
|
|
23087
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "min-w-0 flex-1", children: [
|
|
23088
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: cn(
|
|
23089
|
+
"flex items-center gap-2 text-sm font-semibold",
|
|
23090
|
+
isChromaticBento ? "text-muted-foreground transition-colors duration-300 group-hover:text-foreground" : "text-foreground"
|
|
23091
|
+
), children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "truncate", children: titleText }) }),
|
|
23092
|
+
summaryText && summaryText !== titleText ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: cn(
|
|
23093
|
+
"mt-1 text-[11px] leading-5 text-muted-foreground",
|
|
23094
|
+
isDetailedCard ? "line-clamp-4" : "line-clamp-2",
|
|
23095
|
+
isChromaticBento && "transition-colors duration-300 group-hover:text-foreground"
|
|
23096
|
+
), children: summaryText }) : null
|
|
23097
|
+
] }),
|
|
23098
|
+
metaContent ?? (hasRenderableNode(fieldCountLabel) ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: defaultMetaClassName, children: fieldCountLabel }) : null)
|
|
23099
|
+
] })
|
|
23100
|
+
] }),
|
|
23101
|
+
visibleDetailColumns.length > 0 ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: cn("mt-3 grid grid-flow-row gap-2", detailGridClassName), children: visibleDetailColumns.map((column) => /* @__PURE__ */ jsxRuntime.jsxs("div", { className: detailCellClassName, children: [
|
|
23102
|
+
column.label ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: detailLabelClassName, children: formatLabel(column.label, { column }) }) : null,
|
|
23103
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: cn(detailValueClassName, !column.label && "mt-0"), children: resolvedRenderFieldValue(column, row, { compact: galleryDensity !== "detailed", surface: "gallery" }) })
|
|
23104
|
+
] }, `${row.id || row.linkKey}-${column.key}`)) }) : null,
|
|
23105
|
+
!summaryText && visibleDetailColumns.length === 0 && hasRenderableNode(coverOnlyHint) ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: cn(
|
|
23106
|
+
"mt-3 text-[11px] text-muted-foreground",
|
|
23107
|
+
isChromaticBento && "transition-colors duration-300 group-hover:text-foreground"
|
|
23108
|
+
), children: coverOnlyHint }) : null
|
|
23109
|
+
] }) : null
|
|
23110
|
+
] })
|
|
23111
|
+
]
|
|
23112
|
+
}
|
|
23113
|
+
);
|
|
23114
|
+
}
|
|
23115
|
+
var DEFAULT_MASONRY_GAP_PX = 12;
|
|
23116
|
+
var DEFAULT_MASONRY_ROW_HEIGHT_PX = 8;
|
|
23117
|
+
var DEFAULT_MASONRY_COLUMN_WIDTH_PX = 280;
|
|
23118
|
+
var DEFAULT_MASONRY_ITEM_HEIGHT_PX = 240;
|
|
23119
|
+
function clamp4(value, min5, max5) {
|
|
23120
|
+
return Math.min(Math.max(value, min5), max5);
|
|
23121
|
+
}
|
|
23122
|
+
function getRootFontSize(node) {
|
|
23123
|
+
if (typeof window === "undefined") return 16;
|
|
23124
|
+
const target = node || document.documentElement;
|
|
23125
|
+
const parsed = Number.parseFloat(window.getComputedStyle(target).fontSize);
|
|
23126
|
+
return Number.isFinite(parsed) && parsed > 0 ? parsed : 16;
|
|
23127
|
+
}
|
|
23128
|
+
function resolveLengthToPixels(value, fallback, node) {
|
|
23129
|
+
if (typeof value === "number" && Number.isFinite(value) && value > 0) return value;
|
|
23130
|
+
if (typeof value !== "string") return fallback;
|
|
23131
|
+
const normalized = value.trim().toLowerCase();
|
|
23132
|
+
if (!normalized) return fallback;
|
|
23133
|
+
if (/^\d+(\.\d+)?$/.test(normalized)) {
|
|
23134
|
+
const parsed = Number.parseFloat(normalized);
|
|
23135
|
+
return Number.isFinite(parsed) && parsed > 0 ? parsed : fallback;
|
|
23136
|
+
}
|
|
23137
|
+
if (normalized.endsWith("px")) {
|
|
23138
|
+
const parsed = Number.parseFloat(normalized);
|
|
23139
|
+
return Number.isFinite(parsed) && parsed > 0 ? parsed : fallback;
|
|
23140
|
+
}
|
|
23141
|
+
if (normalized.endsWith("rem")) {
|
|
23142
|
+
const parsed = Number.parseFloat(normalized);
|
|
23143
|
+
if (!Number.isFinite(parsed) || parsed <= 0) return fallback;
|
|
23144
|
+
return parsed * getRootFontSize(node);
|
|
23145
|
+
}
|
|
23146
|
+
return fallback;
|
|
23147
|
+
}
|
|
23148
|
+
function areMeasurementMapsEqual(prev, next) {
|
|
23149
|
+
const prevKeys = Object.keys(prev);
|
|
23150
|
+
const nextKeys = Object.keys(next);
|
|
23151
|
+
if (prevKeys.length !== nextKeys.length) return false;
|
|
23152
|
+
for (const key of nextKeys) {
|
|
23153
|
+
if (prev[key] !== next[key]) return false;
|
|
23154
|
+
}
|
|
23155
|
+
return true;
|
|
23156
|
+
}
|
|
23157
|
+
function getMasonryColumnCount({
|
|
23158
|
+
containerWidth,
|
|
23159
|
+
itemCount,
|
|
23160
|
+
targetColumnWidth,
|
|
23161
|
+
gap
|
|
23162
|
+
}) {
|
|
23163
|
+
if (!containerWidth) return 1;
|
|
23164
|
+
const safeItemCount = Math.max(itemCount, 1);
|
|
23165
|
+
const maxCandidate = Math.max(
|
|
23166
|
+
1,
|
|
23167
|
+
Math.min(
|
|
23168
|
+
safeItemCount,
|
|
23169
|
+
Math.ceil((containerWidth + gap) / (Math.max(targetColumnWidth * 0.58, 1) + gap))
|
|
23170
|
+
)
|
|
23171
|
+
);
|
|
23172
|
+
let bestCount = 1;
|
|
23173
|
+
let bestScore = Number.POSITIVE_INFINITY;
|
|
23174
|
+
for (let candidateCount = 1; candidateCount <= maxCandidate; candidateCount += 1) {
|
|
23175
|
+
const actualColumnWidth = (containerWidth - gap * Math.max(candidateCount - 1, 0)) / candidateCount;
|
|
23176
|
+
if (!Number.isFinite(actualColumnWidth) || actualColumnWidth <= 0) continue;
|
|
23177
|
+
const underflowPenalty = Math.max(0, targetColumnWidth * 0.78 - actualColumnWidth);
|
|
23178
|
+
const overflowPenalty = Math.max(0, actualColumnWidth - targetColumnWidth * 1.35);
|
|
23179
|
+
const candidateScore = Math.abs(actualColumnWidth - targetColumnWidth) + underflowPenalty * 3 + overflowPenalty * 2;
|
|
23180
|
+
if (candidateScore < bestScore) {
|
|
23181
|
+
bestScore = candidateScore;
|
|
23182
|
+
bestCount = candidateCount;
|
|
23183
|
+
}
|
|
23184
|
+
}
|
|
23185
|
+
return bestCount;
|
|
23186
|
+
}
|
|
23187
|
+
function getItemColumnSpan({
|
|
23188
|
+
size,
|
|
23189
|
+
columnWidth,
|
|
23190
|
+
columnCount,
|
|
23191
|
+
gap
|
|
23192
|
+
}) {
|
|
23193
|
+
if (Number.isFinite(size?.columnSpan) && Number(size?.columnSpan) > 0) {
|
|
23194
|
+
return clamp4(Math.round(Number(size?.columnSpan)), 1, columnCount);
|
|
23195
|
+
}
|
|
23196
|
+
const itemWidth = resolveLengthToPixels(size?.width, columnWidth, null);
|
|
23197
|
+
return clamp4(Math.ceil((itemWidth + gap) / (columnWidth + gap)), 1, columnCount);
|
|
23198
|
+
}
|
|
23199
|
+
function getItemRowSpan({
|
|
23200
|
+
size,
|
|
23201
|
+
measuredHeight,
|
|
23202
|
+
rowHeight,
|
|
23203
|
+
gap
|
|
23204
|
+
}) {
|
|
23205
|
+
if (Number.isFinite(size?.rowSpan) && Number(size?.rowSpan) > 0) {
|
|
23206
|
+
return Math.max(1, Math.round(Number(size?.rowSpan)));
|
|
23207
|
+
}
|
|
23208
|
+
const itemHeight = Number.isFinite(measuredHeight) && Number(measuredHeight) > 0 ? Number(measuredHeight) : resolveLengthToPixels(size?.height, DEFAULT_MASONRY_ITEM_HEIGHT_PX, null);
|
|
23209
|
+
return Math.max(1, Math.ceil((itemHeight + gap) / (rowHeight + gap)));
|
|
23210
|
+
}
|
|
23211
|
+
function getResolvedItemHeight({
|
|
23212
|
+
size,
|
|
23213
|
+
measuredHeight
|
|
23214
|
+
}) {
|
|
23215
|
+
return Number.isFinite(measuredHeight) && Number(measuredHeight) > 0 ? Number(measuredHeight) : resolveLengthToPixels(size?.height, DEFAULT_MASONRY_ITEM_HEIGHT_PX, null);
|
|
23216
|
+
}
|
|
23217
|
+
function WorkbenchMasonryLayout({
|
|
23218
|
+
items = [],
|
|
23219
|
+
renderItem,
|
|
23220
|
+
getItemKey = (item, index) => item?.id ?? item?.key ?? index,
|
|
23221
|
+
getItemSize,
|
|
23222
|
+
columnWidth = DEFAULT_MASONRY_COLUMN_WIDTH_PX,
|
|
23223
|
+
gap = DEFAULT_MASONRY_GAP_PX,
|
|
23224
|
+
rowHeight = DEFAULT_MASONRY_ROW_HEIGHT_PX,
|
|
23225
|
+
placementStrategy = "shelf",
|
|
23226
|
+
className
|
|
23227
|
+
}) {
|
|
23228
|
+
const containerRef = React.useRef(null);
|
|
23229
|
+
const itemNodesRef = React.useRef(/* @__PURE__ */ new Map());
|
|
23230
|
+
const itemObserverRef = React.useRef(null);
|
|
23231
|
+
const [containerWidth, setContainerWidth] = React.useState(0);
|
|
23232
|
+
const [measuredHeights, setMeasuredHeights] = React.useState({});
|
|
23233
|
+
const itemKeys = React.useMemo(
|
|
23234
|
+
() => items.map((item, index) => String(getItemKey(item, index))),
|
|
23235
|
+
[getItemKey, items]
|
|
23236
|
+
);
|
|
23237
|
+
const itemKeysSignature = itemKeys.join("|");
|
|
23238
|
+
React.useEffect(() => {
|
|
23239
|
+
const node = containerRef.current;
|
|
23240
|
+
if (!node) return void 0;
|
|
23241
|
+
const updateWidth = () => {
|
|
23242
|
+
const nextWidth = Math.round(node.getBoundingClientRect().width);
|
|
23243
|
+
setContainerWidth((prevWidth) => prevWidth === nextWidth ? prevWidth : nextWidth);
|
|
23244
|
+
};
|
|
23245
|
+
updateWidth();
|
|
23246
|
+
if (typeof ResizeObserver === "function") {
|
|
23247
|
+
const observer = new ResizeObserver(() => updateWidth());
|
|
23248
|
+
observer.observe(node);
|
|
23249
|
+
return () => observer.disconnect();
|
|
23250
|
+
}
|
|
23251
|
+
window.addEventListener("resize", updateWidth);
|
|
23252
|
+
return () => window.removeEventListener("resize", updateWidth);
|
|
23253
|
+
}, []);
|
|
23254
|
+
React.useEffect(() => {
|
|
23255
|
+
setMeasuredHeights((prev) => {
|
|
23256
|
+
const next = Object.fromEntries(
|
|
23257
|
+
Object.entries(prev).filter(([key]) => itemKeys.includes(key))
|
|
23258
|
+
);
|
|
23259
|
+
return areMeasurementMapsEqual(prev, next) ? prev : next;
|
|
23260
|
+
});
|
|
23261
|
+
}, [itemKeys, itemKeysSignature]);
|
|
23262
|
+
const resolvedTargetColumnWidth = resolveLengthToPixels(
|
|
23263
|
+
columnWidth,
|
|
23264
|
+
DEFAULT_MASONRY_COLUMN_WIDTH_PX,
|
|
23265
|
+
containerRef.current
|
|
23266
|
+
);
|
|
23267
|
+
const isDensePlacement = placementStrategy === "dense";
|
|
23268
|
+
const columnCount = getMasonryColumnCount({
|
|
23269
|
+
containerWidth,
|
|
23270
|
+
itemCount: items.length,
|
|
23271
|
+
targetColumnWidth: resolvedTargetColumnWidth,
|
|
23272
|
+
gap
|
|
23273
|
+
});
|
|
23274
|
+
const resolvedColumnWidth = containerWidth > 0 ? (containerWidth - gap * Math.max(columnCount - 1, 0)) / columnCount : resolvedTargetColumnWidth;
|
|
23275
|
+
const layoutItems = React.useMemo(() => items.map((item, index) => {
|
|
23276
|
+
const key = itemKeys[index];
|
|
23277
|
+
const size = typeof getItemSize === "function" ? getItemSize(item, {
|
|
23278
|
+
columnCount,
|
|
23279
|
+
columnWidth: resolvedColumnWidth,
|
|
23280
|
+
containerWidth,
|
|
23281
|
+
gap,
|
|
23282
|
+
placementStrategy,
|
|
23283
|
+
rowHeight
|
|
23284
|
+
}) || {} : {};
|
|
23285
|
+
return {
|
|
23286
|
+
key,
|
|
23287
|
+
item,
|
|
23288
|
+
size,
|
|
23289
|
+
columnSpan: getItemColumnSpan({
|
|
23290
|
+
size,
|
|
23291
|
+
columnWidth: resolvedColumnWidth,
|
|
23292
|
+
columnCount,
|
|
23293
|
+
gap
|
|
23294
|
+
}),
|
|
23295
|
+
rowSpan: getItemRowSpan({
|
|
23296
|
+
size,
|
|
23297
|
+
measuredHeight: measuredHeights[key],
|
|
23298
|
+
rowHeight,
|
|
23299
|
+
gap
|
|
23300
|
+
})
|
|
23301
|
+
};
|
|
23302
|
+
}), [
|
|
23303
|
+
columnCount,
|
|
23304
|
+
containerWidth,
|
|
23305
|
+
gap,
|
|
23306
|
+
getItemSize,
|
|
23307
|
+
itemKeys,
|
|
23308
|
+
items,
|
|
23309
|
+
measuredHeights,
|
|
23310
|
+
placementStrategy,
|
|
23311
|
+
resolvedColumnWidth,
|
|
23312
|
+
rowHeight
|
|
23313
|
+
]);
|
|
23314
|
+
React.useLayoutEffect(() => {
|
|
23315
|
+
const nextMeasurements = {};
|
|
23316
|
+
itemNodesRef.current.forEach((node, key) => {
|
|
23317
|
+
const nextHeight = Math.ceil(node.getBoundingClientRect().height);
|
|
23318
|
+
if (Number.isFinite(nextHeight) && nextHeight > 0) {
|
|
23319
|
+
nextMeasurements[key] = nextHeight;
|
|
23320
|
+
}
|
|
23321
|
+
});
|
|
23322
|
+
setMeasuredHeights((prev) => {
|
|
23323
|
+
if (!Object.keys(nextMeasurements).length) return prev;
|
|
23324
|
+
const merged = { ...prev, ...nextMeasurements };
|
|
23325
|
+
return areMeasurementMapsEqual(prev, merged) ? prev : merged;
|
|
23326
|
+
});
|
|
23327
|
+
}, [columnCount, isDensePlacement, itemKeysSignature, resolvedColumnWidth]);
|
|
23328
|
+
React.useEffect(() => {
|
|
23329
|
+
if (typeof ResizeObserver !== "function") return void 0;
|
|
23330
|
+
const observer = new ResizeObserver((entries) => {
|
|
23331
|
+
setMeasuredHeights((prev) => {
|
|
23332
|
+
const next = { ...prev };
|
|
23333
|
+
let didChange = false;
|
|
23334
|
+
for (const entry of entries) {
|
|
23335
|
+
const key = entry.target.dataset.masonryKey;
|
|
23336
|
+
if (!key) continue;
|
|
23337
|
+
const nextHeight = Math.ceil(entry.contentRect.height);
|
|
23338
|
+
if (!Number.isFinite(nextHeight) || nextHeight <= 0 || next[key] === nextHeight) continue;
|
|
23339
|
+
next[key] = nextHeight;
|
|
23340
|
+
didChange = true;
|
|
23341
|
+
}
|
|
23342
|
+
return didChange ? next : prev;
|
|
23343
|
+
});
|
|
23344
|
+
});
|
|
23345
|
+
itemObserverRef.current = observer;
|
|
23346
|
+
itemNodesRef.current.forEach((node) => observer.observe(node));
|
|
23347
|
+
return () => {
|
|
23348
|
+
observer.disconnect();
|
|
23349
|
+
itemObserverRef.current = null;
|
|
23350
|
+
};
|
|
23351
|
+
}, [isDensePlacement, itemKeysSignature]);
|
|
23352
|
+
const registerItemNode = (key, node) => {
|
|
23353
|
+
const currentNodes = itemNodesRef.current;
|
|
23354
|
+
const previousNode = currentNodes.get(key);
|
|
23355
|
+
if (previousNode && previousNode !== node && itemObserverRef.current) {
|
|
23356
|
+
itemObserverRef.current.unobserve(previousNode);
|
|
23357
|
+
}
|
|
23358
|
+
if (!node) {
|
|
23359
|
+
currentNodes.delete(key);
|
|
23360
|
+
return;
|
|
23361
|
+
}
|
|
23362
|
+
node.dataset.masonryKey = key;
|
|
23363
|
+
currentNodes.set(key, node);
|
|
23364
|
+
if (itemObserverRef.current) {
|
|
23365
|
+
itemObserverRef.current.observe(node);
|
|
23366
|
+
}
|
|
23367
|
+
};
|
|
23368
|
+
if (!isDensePlacement) {
|
|
23369
|
+
const orderedLayout = (() => {
|
|
23370
|
+
const columnBottoms = Array.from({ length: columnCount }, () => 0);
|
|
23371
|
+
let nextColumnIndex = 0;
|
|
23372
|
+
let maxBottom = 0;
|
|
23373
|
+
const positionedItems = layoutItems.map(({ key, item, columnSpan, rowSpan, size }) => {
|
|
23374
|
+
const resolvedSpan = clamp4(columnSpan, 1, columnCount);
|
|
23375
|
+
let startColumn = nextColumnIndex;
|
|
23376
|
+
if (startColumn + resolvedSpan > columnCount) {
|
|
23377
|
+
startColumn = 0;
|
|
23378
|
+
}
|
|
23379
|
+
startColumn = Math.min(startColumn, columnCount - resolvedSpan);
|
|
23380
|
+
const itemWidth = resolvedColumnWidth * resolvedSpan + gap * Math.max(resolvedSpan - 1, 0);
|
|
23381
|
+
const itemHeight = getResolvedItemHeight({
|
|
23382
|
+
size,
|
|
23383
|
+
measuredHeight: measuredHeights[key]
|
|
23384
|
+
});
|
|
23385
|
+
const top = Math.max(...columnBottoms.slice(startColumn, startColumn + resolvedSpan));
|
|
23386
|
+
const left = startColumn * (resolvedColumnWidth + gap);
|
|
23387
|
+
const bottom = top + itemHeight;
|
|
23388
|
+
for (let columnIndex = startColumn; columnIndex < startColumn + resolvedSpan; columnIndex += 1) {
|
|
23389
|
+
columnBottoms[columnIndex] = bottom + gap;
|
|
23390
|
+
}
|
|
23391
|
+
maxBottom = Math.max(maxBottom, bottom);
|
|
23392
|
+
nextColumnIndex = startColumn + resolvedSpan;
|
|
23393
|
+
if (nextColumnIndex >= columnCount) {
|
|
23394
|
+
nextColumnIndex = 0;
|
|
23395
|
+
}
|
|
23396
|
+
return {
|
|
23397
|
+
key,
|
|
23398
|
+
item,
|
|
23399
|
+
columnSpan: resolvedSpan,
|
|
23400
|
+
itemHeight,
|
|
23401
|
+
itemWidth,
|
|
23402
|
+
left,
|
|
23403
|
+
rowSpan,
|
|
23404
|
+
size,
|
|
23405
|
+
top
|
|
23406
|
+
};
|
|
23407
|
+
});
|
|
23408
|
+
return {
|
|
23409
|
+
containerHeight: Math.max(0, maxBottom),
|
|
23410
|
+
positionedItems
|
|
23411
|
+
};
|
|
23412
|
+
})();
|
|
23413
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
23414
|
+
"div",
|
|
23415
|
+
{
|
|
23416
|
+
ref: containerRef,
|
|
23417
|
+
className: cn("relative w-full", className),
|
|
23418
|
+
style: { height: `${orderedLayout.containerHeight}px` },
|
|
23419
|
+
children: orderedLayout.positionedItems.map(({ key, item, columnSpan, rowSpan, size, itemWidth, left, top }) => {
|
|
23420
|
+
const unresolvedSingleColumnWidth = containerWidth <= 0 && columnCount === 1;
|
|
23421
|
+
const itemWidthValue = unresolvedSingleColumnWidth ? "100%" : `${itemWidth}px`;
|
|
23422
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
23423
|
+
"div",
|
|
23424
|
+
{
|
|
23425
|
+
className: "absolute min-w-0",
|
|
23426
|
+
style: {
|
|
23427
|
+
left: unresolvedSingleColumnWidth ? 0 : `${left}px`,
|
|
23428
|
+
top: `${top}px`,
|
|
23429
|
+
width: itemWidthValue,
|
|
23430
|
+
maxWidth: itemWidthValue
|
|
23431
|
+
},
|
|
23432
|
+
children: /* @__PURE__ */ jsxRuntime.jsx("div", { ref: (node) => registerItemNode(key, node), className: "min-w-0", children: renderItem(item, {
|
|
23433
|
+
columnCount,
|
|
23434
|
+
columnSpan,
|
|
23435
|
+
columnWidth: resolvedColumnWidth,
|
|
23436
|
+
containerWidth,
|
|
23437
|
+
gap,
|
|
23438
|
+
itemWidth,
|
|
23439
|
+
placementStrategy,
|
|
23440
|
+
rowSpan,
|
|
23441
|
+
rowHeight,
|
|
23442
|
+
size
|
|
23443
|
+
}) })
|
|
23444
|
+
},
|
|
23445
|
+
key
|
|
23446
|
+
);
|
|
23447
|
+
})
|
|
23448
|
+
}
|
|
23449
|
+
);
|
|
23450
|
+
}
|
|
23451
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
23452
|
+
"div",
|
|
23453
|
+
{
|
|
23454
|
+
ref: containerRef,
|
|
23455
|
+
className: cn("grid w-full items-start", className),
|
|
23456
|
+
style: {
|
|
23457
|
+
gap: `${gap}px`,
|
|
23458
|
+
gridAutoFlow: "row dense",
|
|
23459
|
+
gridAutoRows: `${rowHeight}px`,
|
|
23460
|
+
gridTemplateColumns: `repeat(${columnCount}, minmax(0, 1fr))`
|
|
23461
|
+
},
|
|
23462
|
+
children: layoutItems.map(({ key, item, columnSpan, rowSpan, size }) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
23463
|
+
"div",
|
|
23464
|
+
{
|
|
23465
|
+
className: "min-w-0",
|
|
23466
|
+
style: {
|
|
23467
|
+
gridColumn: `span ${columnSpan}`,
|
|
23468
|
+
gridRow: `span ${rowSpan}`
|
|
23469
|
+
},
|
|
23470
|
+
children: /* @__PURE__ */ jsxRuntime.jsx("div", { ref: (node) => registerItemNode(key, node), className: "h-full", children: renderItem(item, {
|
|
23471
|
+
columnCount,
|
|
23472
|
+
columnSpan,
|
|
23473
|
+
columnWidth: resolvedColumnWidth,
|
|
23474
|
+
containerWidth,
|
|
23475
|
+
gap,
|
|
23476
|
+
placementStrategy,
|
|
23477
|
+
rowSpan,
|
|
23478
|
+
rowHeight,
|
|
23479
|
+
size
|
|
23480
|
+
}) })
|
|
23481
|
+
},
|
|
23482
|
+
key
|
|
23483
|
+
))
|
|
23484
|
+
}
|
|
23485
|
+
);
|
|
23486
|
+
}
|
|
23487
|
+
var GALLERY_GRID_GAP_PX = 12;
|
|
23488
|
+
function getNormalizedGalleryGridCardWidth(cardWidth) {
|
|
23489
|
+
if (typeof cardWidth === "number" && Number.isFinite(cardWidth) && cardWidth > 0) {
|
|
23490
|
+
return `${cardWidth}px`;
|
|
23491
|
+
}
|
|
23492
|
+
if (typeof cardWidth === "string" && cardWidth.trim()) {
|
|
23493
|
+
return cardWidth.trim();
|
|
23494
|
+
}
|
|
23495
|
+
return void 0;
|
|
23496
|
+
}
|
|
23497
|
+
function getDefaultGalleryDetailLimit2(density) {
|
|
23498
|
+
if (density === "compact") return 2;
|
|
23499
|
+
if (density === "detailed") return 6;
|
|
23500
|
+
return 4;
|
|
23501
|
+
}
|
|
23502
|
+
function getNormalizedGalleryBentoColumns2(columns, density) {
|
|
23503
|
+
if (columns === 1 || columns === 2 || columns === 3) return Number(columns);
|
|
23504
|
+
return density === "detailed" ? 1 : 2;
|
|
23505
|
+
}
|
|
23506
|
+
function getNormalizedGalleryDetailLimit2({
|
|
23507
|
+
density,
|
|
23508
|
+
visibility,
|
|
23509
|
+
limit
|
|
23510
|
+
}) {
|
|
23511
|
+
if (visibility === "all") return Number.POSITIVE_INFINITY;
|
|
23512
|
+
const parsedLimit = Number.parseInt(String(limit), 10);
|
|
23513
|
+
if (Number.isFinite(parsedLimit) && parsedLimit > 0) return parsedLimit;
|
|
23514
|
+
return getDefaultGalleryDetailLimit2(density);
|
|
23515
|
+
}
|
|
23516
|
+
function getGalleryCardWidthMetrics(density) {
|
|
23517
|
+
if (density === "compact") return { min: 220, ideal: 244, max: 268 };
|
|
23518
|
+
if (density === "detailed") return { min: 320, ideal: 372, max: 420 };
|
|
23519
|
+
return { min: 260, ideal: 304, max: 348 };
|
|
23520
|
+
}
|
|
23521
|
+
function getGalleryCardWidthForColumnCount({
|
|
23522
|
+
containerWidth,
|
|
23523
|
+
columnCount,
|
|
23524
|
+
gap
|
|
23525
|
+
}) {
|
|
23526
|
+
if (!containerWidth || !columnCount) return 0;
|
|
23527
|
+
return (containerWidth - gap * Math.max(columnCount - 1, 0)) / columnCount;
|
|
23528
|
+
}
|
|
23529
|
+
function getNormalizedGalleryGridColumns(columns) {
|
|
23530
|
+
if (columns === void 0 || columns === null || columns === "" || columns === "auto") {
|
|
23531
|
+
return void 0;
|
|
23532
|
+
}
|
|
23533
|
+
const parsedColumns = Number.parseInt(String(columns), 10);
|
|
23534
|
+
if (!Number.isFinite(parsedColumns) || parsedColumns <= 0) return void 0;
|
|
23535
|
+
return Math.max(1, Math.min(parsedColumns, 8));
|
|
23536
|
+
}
|
|
23537
|
+
function getGalleryGridColumnCount({
|
|
23538
|
+
containerWidth,
|
|
23539
|
+
rowCount,
|
|
23540
|
+
minCardWidth,
|
|
23541
|
+
idealCardWidth,
|
|
23542
|
+
maxCardWidth,
|
|
23543
|
+
gap
|
|
23544
|
+
}) {
|
|
23545
|
+
if (!containerWidth) return 1;
|
|
23546
|
+
const safeRowCount = Math.max(rowCount, 1);
|
|
23547
|
+
const lowerBound = Math.max(1, Math.ceil((containerWidth + gap) / (maxCardWidth + gap)));
|
|
23548
|
+
const upperBound = Math.max(1, Math.floor((containerWidth + gap) / (minCardWidth + gap)));
|
|
23549
|
+
const idealCount = Math.max(1, Math.round((containerWidth + gap) / (idealCardWidth + gap)));
|
|
23550
|
+
const phantomPenalty = Math.round((idealCardWidth - minCardWidth) / 2) + gap;
|
|
23551
|
+
const maxCandidate = Math.max(1, lowerBound, upperBound + 1, idealCount + 1);
|
|
23552
|
+
let bestCount = 1;
|
|
23553
|
+
let bestScore = Number.POSITIVE_INFINITY;
|
|
23554
|
+
for (let candidateCount = 1; candidateCount <= maxCandidate; candidateCount += 1) {
|
|
23555
|
+
const cardWidth = getGalleryCardWidthForColumnCount({ containerWidth, columnCount: candidateCount, gap });
|
|
23556
|
+
const overflowPenalty = Math.max(0, cardWidth - maxCardWidth);
|
|
23557
|
+
const underflowPenalty = Math.max(0, minCardWidth - cardWidth);
|
|
23558
|
+
const idealPenalty = Math.abs(cardWidth - idealCardWidth);
|
|
23559
|
+
const phantomColumns = Math.max(0, candidateCount - safeRowCount);
|
|
23560
|
+
const candidateScore = overflowPenalty * 3 + underflowPenalty * 2 + idealPenalty + phantomColumns * phantomPenalty;
|
|
23561
|
+
if (candidateScore < bestScore) {
|
|
23562
|
+
bestScore = candidateScore;
|
|
23563
|
+
bestCount = candidateCount;
|
|
23564
|
+
}
|
|
23565
|
+
}
|
|
23566
|
+
return bestCount;
|
|
23567
|
+
}
|
|
23568
|
+
function getGalleryGridLayoutStyle({
|
|
23569
|
+
isRailLayout,
|
|
23570
|
+
railCardWidth,
|
|
23571
|
+
fixedCardWidth,
|
|
23572
|
+
fixedColumnCount,
|
|
23573
|
+
containerWidth,
|
|
23574
|
+
rowCount,
|
|
23575
|
+
minCardWidth,
|
|
23576
|
+
idealCardWidth,
|
|
23577
|
+
maxCardWidth
|
|
23578
|
+
}) {
|
|
23579
|
+
if (isRailLayout) {
|
|
23580
|
+
return { gridAutoColumns: `${railCardWidth}px` };
|
|
23581
|
+
}
|
|
23582
|
+
if (fixedColumnCount) {
|
|
23583
|
+
const responsiveColumnCount = containerWidth ? Math.max(1, Math.min(
|
|
23584
|
+
fixedColumnCount,
|
|
23585
|
+
Math.floor((containerWidth + GALLERY_GRID_GAP_PX) / (minCardWidth + GALLERY_GRID_GAP_PX)) || 1
|
|
23586
|
+
)) : fixedColumnCount;
|
|
23587
|
+
return {
|
|
23588
|
+
gridTemplateColumns: `repeat(${responsiveColumnCount}, minmax(0, 1fr))`,
|
|
23589
|
+
justifyContent: "start",
|
|
23590
|
+
alignContent: "start"
|
|
23591
|
+
};
|
|
23592
|
+
}
|
|
23593
|
+
if (fixedCardWidth) {
|
|
23594
|
+
return {
|
|
23595
|
+
gridTemplateColumns: `repeat(auto-fit, minmax(min(100%, ${fixedCardWidth}), ${fixedCardWidth}))`,
|
|
23596
|
+
justifyContent: "start",
|
|
23597
|
+
alignContent: "start"
|
|
23598
|
+
};
|
|
23599
|
+
}
|
|
23600
|
+
if (!containerWidth) {
|
|
23601
|
+
return {
|
|
23602
|
+
gridTemplateColumns: `repeat(auto-fit, minmax(min(100%, ${minCardWidth}px), min(100%, ${maxCardWidth}px)))`,
|
|
23603
|
+
justifyContent: "start",
|
|
23604
|
+
alignContent: "start"
|
|
23605
|
+
};
|
|
23606
|
+
}
|
|
23607
|
+
const columnCount = getGalleryGridColumnCount({
|
|
23608
|
+
containerWidth,
|
|
23609
|
+
rowCount,
|
|
23610
|
+
minCardWidth,
|
|
23611
|
+
idealCardWidth,
|
|
23612
|
+
maxCardWidth,
|
|
23613
|
+
gap: GALLERY_GRID_GAP_PX
|
|
23614
|
+
});
|
|
23615
|
+
return {
|
|
23616
|
+
gridTemplateColumns: `repeat(${columnCount}, minmax(0, 1fr))`,
|
|
23617
|
+
justifyContent: "start",
|
|
23618
|
+
alignContent: "start"
|
|
23619
|
+
};
|
|
23620
|
+
}
|
|
23621
|
+
function getGalleryTextLength(value) {
|
|
23622
|
+
if (value === null || value === void 0) return 0;
|
|
23623
|
+
const text = String(value).trim();
|
|
23624
|
+
return text && text !== "\u2014" ? text.length : 0;
|
|
23625
|
+
}
|
|
23626
|
+
function getGalleryFieldText({
|
|
23627
|
+
column,
|
|
23628
|
+
row,
|
|
23629
|
+
getFieldValue,
|
|
23630
|
+
getDisplayText
|
|
23631
|
+
}) {
|
|
23632
|
+
if (!column) return "";
|
|
23633
|
+
const rawValue = getFieldValue(column, row);
|
|
23634
|
+
if (rawValue === null || rawValue === void 0 || rawValue === "") return "";
|
|
23635
|
+
const textValue = getDisplayText(rawValue);
|
|
23636
|
+
return textValue === "\u2014" ? "" : String(textValue);
|
|
23637
|
+
}
|
|
23638
|
+
function estimateLineCount({
|
|
23639
|
+
text,
|
|
23640
|
+
charsPerLine,
|
|
23641
|
+
maxLines
|
|
23642
|
+
}) {
|
|
23643
|
+
const textLength = getGalleryTextLength(text);
|
|
23644
|
+
if (!textLength) return 0;
|
|
23645
|
+
return Math.max(1, Math.min(maxLines, Math.ceil(textLength / charsPerLine)));
|
|
23646
|
+
}
|
|
23647
|
+
function estimateGalleryDetailCellHeight({
|
|
23648
|
+
text,
|
|
23649
|
+
density,
|
|
23650
|
+
bentoColumns
|
|
23651
|
+
}) {
|
|
23652
|
+
const baseHeight = density === "detailed" ? 54 : density === "compact" ? 44 : 48;
|
|
23653
|
+
const charsPerLine = bentoColumns === 1 ? density === "detailed" ? 32 : 26 : density === "detailed" ? 18 : 15;
|
|
23654
|
+
const maxLines = density === "detailed" ? 3 : 2;
|
|
23655
|
+
const lineCount = estimateLineCount({ text, charsPerLine, maxLines });
|
|
23656
|
+
if (!lineCount) return baseHeight;
|
|
23657
|
+
return baseHeight + Math.max(0, lineCount - 1) * 16;
|
|
23658
|
+
}
|
|
23659
|
+
function estimateGalleryDetailGridHeight({
|
|
23660
|
+
columns,
|
|
23661
|
+
density,
|
|
23662
|
+
bentoColumns
|
|
23663
|
+
}) {
|
|
23664
|
+
if (!columns.length) return 0;
|
|
23665
|
+
const cellHeights = columns.map((column) => estimateGalleryDetailCellHeight({
|
|
23666
|
+
text: column.text,
|
|
23667
|
+
density,
|
|
23668
|
+
bentoColumns
|
|
23669
|
+
}));
|
|
23670
|
+
if (bentoColumns === 1) {
|
|
23671
|
+
return 12 + cellHeights.reduce((sum, height) => sum + height, 0) + Math.max(0, columns.length - 1) * 8;
|
|
23672
|
+
}
|
|
23673
|
+
let totalHeight = 12;
|
|
23674
|
+
for (let index = 0; index < cellHeights.length; index += bentoColumns) {
|
|
23675
|
+
const rowHeights = cellHeights.slice(index, index + bentoColumns);
|
|
23676
|
+
totalHeight += Math.max(...rowHeights);
|
|
23677
|
+
if (index + bentoColumns < cellHeights.length) totalHeight += 8;
|
|
23678
|
+
}
|
|
23679
|
+
return totalHeight;
|
|
23680
|
+
}
|
|
23681
|
+
function getDefaultGalleryMasonryItemSize({
|
|
23682
|
+
row,
|
|
23683
|
+
columns,
|
|
23684
|
+
galleryFieldKey,
|
|
23685
|
+
galleryDensity,
|
|
23686
|
+
galleryBentoColumns,
|
|
23687
|
+
galleryDetailVisibility,
|
|
23688
|
+
galleryDetailLimit,
|
|
23689
|
+
getFieldValue,
|
|
23690
|
+
isMediaColumn,
|
|
23691
|
+
isTitleCandidate,
|
|
23692
|
+
isSummaryCandidate,
|
|
23693
|
+
getDisplayText,
|
|
23694
|
+
isImageField,
|
|
23695
|
+
isAudioField,
|
|
23696
|
+
cardVariant,
|
|
23697
|
+
renderPreview,
|
|
23698
|
+
renderLeadingVisual,
|
|
23699
|
+
hiddenDetailFieldKeys,
|
|
23700
|
+
layout,
|
|
23701
|
+
resolveRecordVisual
|
|
23702
|
+
}) {
|
|
23703
|
+
const iconColumn = columns.find((column) => column.renderType === "icon");
|
|
23704
|
+
const iconVisual = iconColumn && resolveRecordVisual ? resolveRecordVisual(row?.[iconColumn.key], row, iconColumn) : null;
|
|
23705
|
+
const selectedGalleryColumn = galleryFieldKey !== "auto" ? columns.find((column) => column.key === galleryFieldKey && isMediaColumn(column, row)) : null;
|
|
23706
|
+
const mediaColumn = selectedGalleryColumn || columns.find((column) => isMediaColumn(column, row)) || null;
|
|
23707
|
+
const mediaValue = mediaColumn ? getFieldValue(mediaColumn, row) : null;
|
|
23708
|
+
const isImageMedia = mediaColumn ? isImageField(mediaColumn, mediaValue) : false;
|
|
23709
|
+
const isAudioMedia = mediaColumn ? isAudioField(mediaColumn, mediaValue) : false;
|
|
23710
|
+
const hasDefaultLeadingVisual = Boolean(iconVisual);
|
|
23711
|
+
const hasLeadingVisual = Boolean(renderLeadingVisual) || hasDefaultLeadingVisual;
|
|
23712
|
+
const contentColumns = columns.filter((column) => column.key !== mediaColumn?.key && column.renderType !== "icon");
|
|
23713
|
+
const titleCandidates = contentColumns.filter((column) => {
|
|
23714
|
+
if (!column || isMediaColumn(column, row) || !isTitleCandidate(column, row)) return false;
|
|
23715
|
+
const value = getFieldValue(column, row);
|
|
23716
|
+
return !(value === null || value === void 0 || value === "");
|
|
23717
|
+
});
|
|
23718
|
+
const titleColumn = titleCandidates[0] || null;
|
|
23719
|
+
const titleText = titleColumn ? getGalleryFieldText({ column: titleColumn, row, getFieldValue, getDisplayText }) : String(getDisplayText(row?.linkKey || row?.id || ""));
|
|
23720
|
+
const summaryColumn = contentColumns.find((column) => {
|
|
23721
|
+
if (!column || column.key === titleColumn?.key || isMediaColumn(column, row) || !isSummaryCandidate(column, row)) return false;
|
|
23722
|
+
const summaryText2 = getGalleryFieldText({ column, row, getFieldValue, getDisplayText });
|
|
23723
|
+
return summaryText2.length > 12;
|
|
23724
|
+
}) || contentColumns.find((column) => {
|
|
23725
|
+
if (!column || column.key === titleColumn?.key || isMediaColumn(column, row) || !isSummaryCandidate(column, row)) return false;
|
|
23726
|
+
return getGalleryTextLength(getGalleryFieldText({ column, row, getFieldValue, getDisplayText })) > 0;
|
|
23727
|
+
}) || null;
|
|
23728
|
+
const summaryText = summaryColumn ? getGalleryFieldText({ column: summaryColumn, row, getFieldValue, getDisplayText }) : "";
|
|
23729
|
+
const hiddenDetailKeySet = new Set(hiddenDetailFieldKeys);
|
|
23730
|
+
const detailColumns = contentColumns.filter((column) => column.key !== titleColumn?.key && column.key !== summaryColumn?.key && !hiddenDetailKeySet.has(column.key)).map((column) => ({
|
|
23731
|
+
column,
|
|
23732
|
+
text: getGalleryFieldText({ column, row, getFieldValue, getDisplayText })
|
|
23733
|
+
}));
|
|
23734
|
+
const resolvedDetailLimit = getNormalizedGalleryDetailLimit2({
|
|
23735
|
+
density: galleryDensity,
|
|
23736
|
+
visibility: galleryDetailVisibility,
|
|
23737
|
+
limit: galleryDetailLimit
|
|
23738
|
+
});
|
|
23739
|
+
const visibleDetailColumns = Number.isFinite(resolvedDetailLimit) ? detailColumns.slice(0, resolvedDetailLimit) : detailColumns;
|
|
23740
|
+
const hiddenDetailCount = Math.max(detailColumns.length - visibleDetailColumns.length, 0);
|
|
23741
|
+
const resolvedBentoColumns = getNormalizedGalleryBentoColumns2(galleryBentoColumns, galleryDensity);
|
|
23742
|
+
const resolvedColumnWidth = layout?.columnWidth || getGalleryCardWidthMetrics(galleryDensity).ideal;
|
|
23743
|
+
if (cardVariant === "image-only") {
|
|
23744
|
+
return {
|
|
23745
|
+
width: resolvedColumnWidth,
|
|
23746
|
+
height: Math.round(resolvedColumnWidth * 1.25)
|
|
23747
|
+
};
|
|
23748
|
+
}
|
|
23749
|
+
if (cardVariant === "preview-only") {
|
|
23750
|
+
return {
|
|
23751
|
+
width: resolvedColumnWidth,
|
|
23752
|
+
height: Math.round(resolvedColumnWidth * 0.82)
|
|
23753
|
+
};
|
|
23754
|
+
}
|
|
23755
|
+
let estimatedHeight = galleryDensity === "detailed" ? 84 : galleryDensity === "compact" ? 64 : 72;
|
|
23756
|
+
if (typeof renderPreview === "function") {
|
|
23757
|
+
estimatedHeight += galleryDensity === "detailed" ? 188 : galleryDensity === "compact" ? 140 : 164;
|
|
23758
|
+
} else if (isImageMedia) {
|
|
23759
|
+
estimatedHeight += Math.round(resolvedColumnWidth * (galleryDensity === "detailed" ? 0.72 : 0.62)) + 12;
|
|
23760
|
+
} else if (isAudioMedia) {
|
|
23761
|
+
estimatedHeight += 92;
|
|
23762
|
+
}
|
|
23763
|
+
const titleLines = estimateLineCount({
|
|
23764
|
+
text: titleText,
|
|
23765
|
+
charsPerLine: galleryDensity === "detailed" ? 26 : 24,
|
|
23766
|
+
maxLines: 2
|
|
23767
|
+
}) || 1;
|
|
23768
|
+
const summaryLines = estimateLineCount({
|
|
23769
|
+
text: summaryText,
|
|
23770
|
+
charsPerLine: hasLeadingVisual ? 22 : galleryDensity === "detailed" ? 30 : 26,
|
|
23771
|
+
maxLines: galleryDensity === "detailed" ? 4 : 2
|
|
23772
|
+
});
|
|
23773
|
+
const textHeaderHeight = 26 + titleLines * 18 + (summaryLines > 0 ? summaryLines * 16 + 4 : 0);
|
|
23774
|
+
estimatedHeight += Math.max(hasLeadingVisual ? 56 : 0, textHeaderHeight);
|
|
23775
|
+
estimatedHeight += estimateGalleryDetailGridHeight({
|
|
23776
|
+
columns: visibleDetailColumns,
|
|
23777
|
+
density: galleryDensity,
|
|
23778
|
+
bentoColumns: resolvedBentoColumns
|
|
23779
|
+
});
|
|
23780
|
+
if (hiddenDetailCount > 0) estimatedHeight += 18;
|
|
23781
|
+
if (!summaryText && visibleDetailColumns.length === 0) estimatedHeight += 24;
|
|
23782
|
+
return {
|
|
23783
|
+
width: resolvedColumnWidth,
|
|
23784
|
+
height: estimatedHeight
|
|
23785
|
+
};
|
|
23786
|
+
}
|
|
23787
|
+
function WorkbenchGalleryView({
|
|
23788
|
+
rows = [],
|
|
23789
|
+
columns = [],
|
|
23790
|
+
onRowClick = () => {
|
|
23791
|
+
},
|
|
23792
|
+
selectedLinkKey,
|
|
23793
|
+
selectedRowKey,
|
|
23794
|
+
className,
|
|
23795
|
+
isMasonry = false,
|
|
23796
|
+
galleryLayoutMode = "auto",
|
|
23797
|
+
galleryRailCardWidth,
|
|
23798
|
+
galleryGridColumns,
|
|
23799
|
+
galleryGridCardWidth,
|
|
23800
|
+
galleryMasonryColumnWidth,
|
|
23801
|
+
masonryPlacementStrategy = "shelf",
|
|
23802
|
+
galleryFieldKey = "auto",
|
|
23803
|
+
galleryDensity = "comfortable",
|
|
23804
|
+
galleryBentoColumns = 2,
|
|
23805
|
+
galleryDetailVisibility = "limit",
|
|
23806
|
+
galleryDetailLimit,
|
|
23807
|
+
shouldEnhanceMultimodal = true,
|
|
23808
|
+
getFieldValue,
|
|
23809
|
+
isMediaColumn,
|
|
23810
|
+
isTitleCandidate,
|
|
23811
|
+
isSummaryCandidate,
|
|
23812
|
+
getDisplayText,
|
|
23813
|
+
renderFieldValue,
|
|
23814
|
+
getImagePreviewSrc,
|
|
23815
|
+
isImageField,
|
|
23816
|
+
isAudioField,
|
|
23817
|
+
AudioPlayerComponent,
|
|
23818
|
+
cardVariant = "default",
|
|
23819
|
+
renderPreview,
|
|
23820
|
+
renderMeta,
|
|
23821
|
+
renderLeadingVisual,
|
|
23822
|
+
resolveRecordVisual,
|
|
23823
|
+
hiddenDetailFieldKeys = [],
|
|
23824
|
+
labels,
|
|
23825
|
+
formatLabel,
|
|
23826
|
+
getMasonryItemSize
|
|
23827
|
+
}) {
|
|
23828
|
+
const containerRef = React.useRef(null);
|
|
23829
|
+
const [containerWidth, setContainerWidth] = React.useState(0);
|
|
23830
|
+
const { min: resolvedMinCardWidth, ideal: resolvedIdealCardWidth, max: resolvedMaxCardWidth } = getGalleryCardWidthMetrics(galleryDensity);
|
|
23831
|
+
const resolvedRailCardWidth = galleryRailCardWidth || resolvedMinCardWidth;
|
|
23832
|
+
const resolvedGridColumnCount = getNormalizedGalleryGridColumns(galleryGridColumns);
|
|
23833
|
+
const resolvedGridCardWidth = getNormalizedGalleryGridCardWidth(galleryGridCardWidth);
|
|
23834
|
+
const resolvedMasonryColumnWidth = galleryMasonryColumnWidth || resolvedMinCardWidth;
|
|
23835
|
+
const isRailLayout = galleryLayoutMode === "rail";
|
|
23836
|
+
const resolvedGetFieldValue = getFieldValue || getDefaultGalleryFieldValue;
|
|
23837
|
+
const resolvedGetDisplayText = getDisplayText || getDefaultGalleryDisplayText;
|
|
23838
|
+
const resolvedIsImageField = isImageField || isDefaultGalleryImageField;
|
|
23839
|
+
const resolvedIsAudioField = isAudioField || isDefaultGalleryAudioField;
|
|
23840
|
+
const resolvedIsMediaColumn = isMediaColumn || ((column, row) => isDefaultGalleryMediaColumn(column, row, {
|
|
23841
|
+
getFieldValue: resolvedGetFieldValue,
|
|
23842
|
+
shouldEnhanceMultimodal,
|
|
23843
|
+
isImageField: resolvedIsImageField,
|
|
23844
|
+
isAudioField: resolvedIsAudioField
|
|
23845
|
+
}));
|
|
23846
|
+
const resolvedIsTitleCandidate = isTitleCandidate || ((column, row) => isDefaultGalleryTitleCandidate(column, row, { isMediaColumn: resolvedIsMediaColumn }));
|
|
23847
|
+
const resolvedIsSummaryCandidate = isSummaryCandidate || ((column, row) => isDefaultGallerySummaryCandidate(column, row, { isMediaColumn: resolvedIsMediaColumn }));
|
|
23848
|
+
const resolvedRenderFieldValue = renderFieldValue || ((column, row, { compact } = {}) => /* @__PURE__ */ jsxRuntime.jsx("span", { children: resolvedGetDisplayText(resolvedGetFieldValue(column, row)) }));
|
|
23849
|
+
React.useEffect(() => {
|
|
23850
|
+
if (isMasonry || isRailLayout || resolvedGridCardWidth) return void 0;
|
|
23851
|
+
const node = containerRef.current;
|
|
23852
|
+
if (!node) return void 0;
|
|
23853
|
+
const updateWidth = () => {
|
|
23854
|
+
const nextWidth = Math.round(node.getBoundingClientRect().width);
|
|
23855
|
+
setContainerWidth((prevWidth) => prevWidth === nextWidth ? prevWidth : nextWidth);
|
|
23856
|
+
};
|
|
23857
|
+
updateWidth();
|
|
23858
|
+
if (typeof ResizeObserver === "function") {
|
|
23859
|
+
const observer = new ResizeObserver(() => updateWidth());
|
|
23860
|
+
observer.observe(node);
|
|
23861
|
+
return () => observer.disconnect();
|
|
23862
|
+
}
|
|
23863
|
+
window.addEventListener("resize", updateWidth);
|
|
23864
|
+
return () => window.removeEventListener("resize", updateWidth);
|
|
23865
|
+
}, [isMasonry, isRailLayout, resolvedGridCardWidth]);
|
|
23866
|
+
const layoutStyle = React.useMemo(() => getGalleryGridLayoutStyle({
|
|
23867
|
+
isRailLayout,
|
|
23868
|
+
railCardWidth: resolvedRailCardWidth,
|
|
23869
|
+
fixedCardWidth: resolvedGridCardWidth,
|
|
23870
|
+
fixedColumnCount: resolvedGridColumnCount,
|
|
23871
|
+
containerWidth,
|
|
23872
|
+
rowCount: rows.length,
|
|
23873
|
+
minCardWidth: resolvedMinCardWidth,
|
|
23874
|
+
idealCardWidth: resolvedIdealCardWidth,
|
|
23875
|
+
maxCardWidth: resolvedMaxCardWidth
|
|
23876
|
+
}), [
|
|
23877
|
+
containerWidth,
|
|
23878
|
+
isRailLayout,
|
|
23879
|
+
resolvedGridCardWidth,
|
|
23880
|
+
resolvedGridColumnCount,
|
|
23881
|
+
resolvedIdealCardWidth,
|
|
23882
|
+
resolvedMaxCardWidth,
|
|
23883
|
+
resolvedMinCardWidth,
|
|
23884
|
+
resolvedRailCardWidth,
|
|
23885
|
+
rows.length
|
|
23886
|
+
]);
|
|
23887
|
+
const renderGalleryCard = (row, rowIndex) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
23888
|
+
WorkbenchGalleryCard,
|
|
23889
|
+
{
|
|
23890
|
+
row,
|
|
23891
|
+
columns,
|
|
23892
|
+
onClick: () => onRowClick(row, rowIndex),
|
|
23893
|
+
isSelected: String(row?.linkKey || row?.id || "") === String(selectedRowKey || selectedLinkKey || ""),
|
|
23894
|
+
isMasonry,
|
|
23895
|
+
galleryFieldKey,
|
|
23896
|
+
galleryDensity,
|
|
23897
|
+
galleryBentoColumns,
|
|
23898
|
+
galleryDetailVisibility,
|
|
23899
|
+
galleryDetailLimit,
|
|
23900
|
+
shouldEnhanceMultimodal,
|
|
23901
|
+
getFieldValue: resolvedGetFieldValue,
|
|
23902
|
+
isMediaColumn: resolvedIsMediaColumn,
|
|
23903
|
+
isTitleCandidate: resolvedIsTitleCandidate,
|
|
23904
|
+
isSummaryCandidate: resolvedIsSummaryCandidate,
|
|
23905
|
+
getDisplayText: resolvedGetDisplayText,
|
|
23906
|
+
renderFieldValue: resolvedRenderFieldValue,
|
|
23907
|
+
getImagePreviewSrc,
|
|
23908
|
+
isImageField: resolvedIsImageField,
|
|
23909
|
+
isAudioField: resolvedIsAudioField,
|
|
23910
|
+
AudioPlayerComponent,
|
|
23911
|
+
cardVariant,
|
|
23912
|
+
renderPreview,
|
|
23913
|
+
renderMeta,
|
|
23914
|
+
renderLeadingVisual,
|
|
23915
|
+
resolveRecordVisual,
|
|
23916
|
+
hiddenDetailFieldKeys,
|
|
23917
|
+
labels,
|
|
23918
|
+
formatLabel
|
|
23919
|
+
},
|
|
23920
|
+
row?.id || row?.linkKey || rowIndex
|
|
23921
|
+
);
|
|
23922
|
+
if (isMasonry) {
|
|
23923
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
23924
|
+
WorkbenchMasonryLayout,
|
|
23925
|
+
{
|
|
23926
|
+
items: rows,
|
|
23927
|
+
className,
|
|
23928
|
+
gap: GALLERY_GRID_GAP_PX,
|
|
23929
|
+
columnWidth: resolvedMasonryColumnWidth,
|
|
23930
|
+
placementStrategy: masonryPlacementStrategy,
|
|
23931
|
+
getItemKey: (row, rowIndex) => row?.id || row?.linkKey || rowIndex,
|
|
23932
|
+
getItemSize: (row, layout) => {
|
|
23933
|
+
const defaultSize = getDefaultGalleryMasonryItemSize({
|
|
23934
|
+
row,
|
|
23935
|
+
columns,
|
|
23936
|
+
galleryFieldKey,
|
|
23937
|
+
galleryDensity,
|
|
23938
|
+
galleryBentoColumns,
|
|
23939
|
+
galleryDetailVisibility,
|
|
23940
|
+
galleryDetailLimit,
|
|
23941
|
+
getFieldValue: resolvedGetFieldValue,
|
|
23942
|
+
isMediaColumn: resolvedIsMediaColumn,
|
|
23943
|
+
isTitleCandidate: resolvedIsTitleCandidate,
|
|
23944
|
+
isSummaryCandidate: resolvedIsSummaryCandidate,
|
|
23945
|
+
getDisplayText: resolvedGetDisplayText,
|
|
23946
|
+
isImageField: resolvedIsImageField,
|
|
23947
|
+
isAudioField: resolvedIsAudioField,
|
|
23948
|
+
cardVariant,
|
|
23949
|
+
renderPreview,
|
|
23950
|
+
renderLeadingVisual,
|
|
23951
|
+
hiddenDetailFieldKeys,
|
|
23952
|
+
layout,
|
|
23953
|
+
resolveRecordVisual
|
|
23954
|
+
});
|
|
23955
|
+
if (typeof getMasonryItemSize !== "function") return defaultSize;
|
|
23956
|
+
const customSize = getMasonryItemSize(row, { ...layout, defaultSize }) || {};
|
|
23957
|
+
return {
|
|
23958
|
+
...defaultSize,
|
|
23959
|
+
...customSize
|
|
23960
|
+
};
|
|
23961
|
+
},
|
|
23962
|
+
renderItem: (row) => renderGalleryCard(row, rows.indexOf(row))
|
|
23963
|
+
}
|
|
23964
|
+
);
|
|
23965
|
+
}
|
|
23966
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
23967
|
+
"div",
|
|
23968
|
+
{
|
|
23969
|
+
ref: containerRef,
|
|
23970
|
+
className: cn(
|
|
23971
|
+
isRailLayout ? "grid grid-flow-col items-center gap-3" : "grid items-start gap-3",
|
|
23972
|
+
className
|
|
23973
|
+
),
|
|
23974
|
+
style: layoutStyle,
|
|
23975
|
+
children: rows.map((row, rowIndex) => renderGalleryCard(row, rowIndex))
|
|
23976
|
+
}
|
|
23977
|
+
);
|
|
23978
|
+
}
|
|
23979
|
+
function toCssSize5(value) {
|
|
23980
|
+
if (value === void 0) return void 0;
|
|
23981
|
+
return typeof value === "number" ? `${value}px` : value;
|
|
23982
|
+
}
|
|
23983
|
+
function defaultGetRowId(row, rowIndex) {
|
|
23984
|
+
return String(row?.id ?? row?.key ?? rowIndex);
|
|
23985
|
+
}
|
|
23986
|
+
function defaultGetColumnId(row) {
|
|
23987
|
+
return String(row?.columnId ?? row?.status ?? "");
|
|
23988
|
+
}
|
|
23989
|
+
function defaultRenderCard(row) {
|
|
23990
|
+
const value = row?.title ?? row?.name ?? row?.id ?? "Untitled";
|
|
23991
|
+
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "rounded-lg border border-border/70 bg-card px-3 py-2 text-sm text-foreground shadow-sm", children: String(value) });
|
|
23992
|
+
}
|
|
23993
|
+
function WorkbenchLaneDraggableCard({
|
|
23994
|
+
row,
|
|
23995
|
+
rowId,
|
|
23996
|
+
rowIndex,
|
|
23997
|
+
column,
|
|
23998
|
+
classNames,
|
|
23999
|
+
renderCard
|
|
24000
|
+
}) {
|
|
24001
|
+
const { attributes, listeners, setNodeRef, isDragging } = core.useDraggable({ id: rowId });
|
|
24002
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
24003
|
+
"div",
|
|
24004
|
+
{
|
|
24005
|
+
ref: setNodeRef,
|
|
24006
|
+
...listeners,
|
|
24007
|
+
...attributes,
|
|
24008
|
+
className: cn("touch-none", classNames?.cardWrapper),
|
|
24009
|
+
children: renderCard(row, { row, rowIndex, column, isDragging, isOverlay: false })
|
|
24010
|
+
}
|
|
24011
|
+
);
|
|
24012
|
+
}
|
|
24013
|
+
function WorkbenchLaneColumnView({
|
|
24014
|
+
column,
|
|
24015
|
+
columnRows,
|
|
24016
|
+
columnWidth,
|
|
24017
|
+
columnMinHeight,
|
|
24018
|
+
emptyColumn,
|
|
24019
|
+
classNames,
|
|
24020
|
+
renderCard
|
|
24021
|
+
}) {
|
|
24022
|
+
const { setNodeRef, isOver } = core.useDroppable({ id: column.id });
|
|
24023
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
24024
|
+
"section",
|
|
24025
|
+
{
|
|
24026
|
+
className: cn(
|
|
24027
|
+
"flex shrink-0 flex-col rounded-xl border border-border/60 bg-card p-2 shadow-sm",
|
|
24028
|
+
classNames?.column,
|
|
24029
|
+
column.className
|
|
24030
|
+
),
|
|
24031
|
+
style: { width: toCssSize5(columnWidth) ?? "280px" },
|
|
24032
|
+
children: [
|
|
24033
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: cn("flex h-10 items-center gap-2 px-1", classNames?.columnHeader, column.headerClassName), children: [
|
|
24034
|
+
column.icon ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: cn("inline-flex h-4 w-4 items-center justify-center text-muted-foreground", classNames?.columnIcon, column.iconClassName), children: column.icon }) : null,
|
|
24035
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: cn("inline-flex items-center rounded px-2 py-0.5 text-xs font-semibold bg-muted text-muted-foreground", classNames?.columnBadge, column.badgeClassName), children: column.label ?? column.id }),
|
|
24036
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: cn("text-xs text-muted-foreground", classNames?.columnCount), children: columnRows.length })
|
|
24037
|
+
] }),
|
|
24038
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
24039
|
+
"div",
|
|
24040
|
+
{
|
|
24041
|
+
ref: setNodeRef,
|
|
24042
|
+
className: cn(
|
|
24043
|
+
"mt-1 flex min-h-[200px] flex-1 flex-col gap-2 overflow-y-auto rounded-lg p-1 transition-colors [scrollbar-width:thin]",
|
|
24044
|
+
isOver && "bg-accent/60",
|
|
24045
|
+
classNames?.columnBody,
|
|
24046
|
+
column.bodyClassName
|
|
24047
|
+
),
|
|
24048
|
+
style: { minHeight: toCssSize5(columnMinHeight) },
|
|
24049
|
+
children: columnRows.length ? columnRows.map(({ row, rowIndex, rowId }) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
24050
|
+
WorkbenchLaneDraggableCard,
|
|
24051
|
+
{
|
|
24052
|
+
row,
|
|
24053
|
+
rowId,
|
|
24054
|
+
rowIndex,
|
|
24055
|
+
column,
|
|
24056
|
+
classNames,
|
|
24057
|
+
renderCard
|
|
24058
|
+
},
|
|
24059
|
+
rowId
|
|
24060
|
+
)) : emptyColumn ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: cn("flex min-h-24 items-center justify-center rounded-lg border border-dashed border-border/60 px-3 py-4 text-xs text-muted-foreground", classNames?.emptyColumn), children: emptyColumn }) : null
|
|
24061
|
+
}
|
|
24062
|
+
)
|
|
24063
|
+
]
|
|
24064
|
+
}
|
|
24065
|
+
);
|
|
24066
|
+
}
|
|
24067
|
+
function WorkbenchLaneView({
|
|
24068
|
+
rows = [],
|
|
24069
|
+
columns = [],
|
|
24070
|
+
getRowId = defaultGetRowId,
|
|
24071
|
+
getColumnId = defaultGetColumnId,
|
|
24072
|
+
renderCard = defaultRenderCard,
|
|
24073
|
+
renderOverlayCard,
|
|
24074
|
+
onMoveRow,
|
|
24075
|
+
emptyColumn,
|
|
24076
|
+
activationDistance = 5,
|
|
24077
|
+
columnWidth = 280,
|
|
24078
|
+
columnMinHeight,
|
|
24079
|
+
className,
|
|
24080
|
+
classNames,
|
|
24081
|
+
style
|
|
24082
|
+
}) {
|
|
24083
|
+
const [activeRowId, setActiveRowId] = React.useState(null);
|
|
24084
|
+
const sensors = core.useSensors(core.useSensor(core.PointerSensor, { activationConstraint: { distance: activationDistance } }));
|
|
24085
|
+
const columnMap = React.useMemo(() => new Map(columns.map((column) => [column.id, column])), [columns]);
|
|
24086
|
+
const rowEntries = React.useMemo(() => rows.map((row, rowIndex) => ({
|
|
24087
|
+
row,
|
|
24088
|
+
rowIndex,
|
|
24089
|
+
rowId: getRowId(row, rowIndex),
|
|
24090
|
+
columnId: getColumnId(row, rowIndex)
|
|
24091
|
+
})), [getColumnId, getRowId, rows]);
|
|
24092
|
+
const activeEntry = activeRowId ? rowEntries.find((entry) => entry.rowId === activeRowId) : void 0;
|
|
24093
|
+
const rowsByColumn = React.useMemo(() => {
|
|
24094
|
+
const next = /* @__PURE__ */ new Map();
|
|
24095
|
+
columns.forEach((column) => next.set(column.id, []));
|
|
24096
|
+
rowEntries.forEach(({ row, rowIndex, rowId, columnId }) => {
|
|
24097
|
+
next.get(columnId)?.push({ row, rowIndex, rowId });
|
|
24098
|
+
});
|
|
24099
|
+
return next;
|
|
24100
|
+
}, [columns, rowEntries]);
|
|
24101
|
+
const activeColumn = activeEntry ? columnMap.get(activeEntry.columnId) : void 0;
|
|
24102
|
+
const handleDragStart = React.useCallback((event) => {
|
|
24103
|
+
setActiveRowId(String(event.active.id));
|
|
24104
|
+
}, []);
|
|
24105
|
+
const handleDragEnd = React.useCallback((event) => {
|
|
24106
|
+
setActiveRowId(null);
|
|
24107
|
+
const rowId = String(event.active.id);
|
|
24108
|
+
const nextColumnId = String(event.over?.id ?? "");
|
|
24109
|
+
const activeRow = rowEntries.find((entry) => entry.rowId === rowId);
|
|
24110
|
+
if (!activeRow || !columnMap.has(nextColumnId) || activeRow.columnId === nextColumnId) return;
|
|
24111
|
+
onMoveRow?.(rowId, nextColumnId, activeRow.row);
|
|
24112
|
+
}, [columnMap, onMoveRow, rowEntries]);
|
|
24113
|
+
const handleDragCancel = React.useCallback(() => {
|
|
24114
|
+
setActiveRowId(null);
|
|
24115
|
+
}, []);
|
|
24116
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(core.DndContext, { sensors, onDragStart: handleDragStart, onDragEnd: handleDragEnd, onDragCancel: handleDragCancel, children: [
|
|
24117
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
24118
|
+
"div",
|
|
24119
|
+
{
|
|
24120
|
+
className: cn("flex min-h-0 flex-1 gap-4 overflow-x-auto p-4 [scrollbar-width:thin]", classNames?.root, className),
|
|
24121
|
+
style,
|
|
24122
|
+
children: columns.map((column) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
24123
|
+
WorkbenchLaneColumnView,
|
|
24124
|
+
{
|
|
24125
|
+
column,
|
|
24126
|
+
columnRows: rowsByColumn.get(column.id) || [],
|
|
24127
|
+
columnWidth,
|
|
24128
|
+
columnMinHeight,
|
|
24129
|
+
emptyColumn,
|
|
24130
|
+
classNames,
|
|
24131
|
+
renderCard
|
|
24132
|
+
},
|
|
24133
|
+
column.id
|
|
24134
|
+
))
|
|
24135
|
+
}
|
|
24136
|
+
),
|
|
24137
|
+
/* @__PURE__ */ jsxRuntime.jsx(core.DragOverlay, { children: activeEntry && activeColumn ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: cn(classNames?.overlayWrapper), children: (renderOverlayCard || renderCard)(activeEntry.row, {
|
|
24138
|
+
row: activeEntry.row,
|
|
24139
|
+
rowIndex: activeEntry.rowIndex,
|
|
24140
|
+
column: activeColumn,
|
|
24141
|
+
isDragging: false,
|
|
24142
|
+
isOverlay: true
|
|
24143
|
+
}) }) : null })
|
|
24144
|
+
] });
|
|
24145
|
+
}
|
|
19999
24146
|
function cn4(...inputs) {
|
|
20000
24147
|
return inputs.filter(Boolean).join(" ");
|
|
20001
24148
|
}
|
|
@@ -20323,6 +24470,10 @@ exports.BaseDropdownMenu = BaseDropdownMenu;
|
|
|
20323
24470
|
exports.BaseEmptyState = BaseEmptyState;
|
|
20324
24471
|
exports.BaseField = BaseField;
|
|
20325
24472
|
exports.BaseInput = BaseInput;
|
|
24473
|
+
exports.BaseLayout = BaseLayout;
|
|
24474
|
+
exports.BaseLayoutPane = BaseLayoutPane;
|
|
24475
|
+
exports.BaseLayoutResizeHandle = BaseLayoutResizeHandle;
|
|
24476
|
+
exports.BaseLayoutSplit = BaseLayoutSplit;
|
|
20326
24477
|
exports.BaseLoadingState = BaseLoadingState;
|
|
20327
24478
|
exports.BaseNotice = BaseNotice;
|
|
20328
24479
|
exports.BasePagination = BasePagination;
|
|
@@ -20387,11 +24538,26 @@ exports.DefaultLandingPage = DefaultLandingPage;
|
|
|
20387
24538
|
exports.DynamicComponent = DynamicComponent;
|
|
20388
24539
|
exports.EmailAuth = EmailAuth;
|
|
20389
24540
|
exports.I18nSelector = I18nSelector;
|
|
24541
|
+
exports.InteractiveTable = InteractiveTable;
|
|
24542
|
+
exports.InteractiveTableEditableTextCell = InteractiveTableEditableTextCell;
|
|
24543
|
+
exports.InteractiveTableReadonlyCell = InteractiveTableReadonlyCell;
|
|
24544
|
+
exports.InteractiveTableSelectCell = InteractiveTableSelectCell;
|
|
20390
24545
|
exports.LoginLayout = LoginLayout;
|
|
20391
24546
|
exports.NavButton = NavButton;
|
|
20392
24547
|
exports.OAuthButton = OAuthButton;
|
|
20393
24548
|
exports.OIDCButton = OIDCButton;
|
|
20394
24549
|
exports.PendingApproval = PendingApproval;
|
|
24550
|
+
exports.WorkbenchContentPane = WorkbenchContentPane;
|
|
24551
|
+
exports.WorkbenchContentToolbar = WorkbenchContentToolbar;
|
|
24552
|
+
exports.WorkbenchDetailSidebar = WorkbenchDetailSidebar;
|
|
24553
|
+
exports.WorkbenchGalleryCard = WorkbenchGalleryCard;
|
|
24554
|
+
exports.WorkbenchGallerySettingsButton = WorkbenchGallerySettingsButton;
|
|
24555
|
+
exports.WorkbenchGallerySettingsPanel = WorkbenchGallerySettingsPanel;
|
|
24556
|
+
exports.WorkbenchGalleryView = WorkbenchGalleryView;
|
|
24557
|
+
exports.WorkbenchLaneView = WorkbenchLaneView;
|
|
24558
|
+
exports.WorkbenchMasonryLayout = WorkbenchMasonryLayout;
|
|
24559
|
+
exports.WorkbenchResizableSidebar = WorkbenchResizableSidebar;
|
|
24560
|
+
exports.WorkbenchTableView = WorkbenchTableView;
|
|
20395
24561
|
exports.applyMonkeysTheme = applyMonkeysTheme;
|
|
20396
24562
|
exports.calculateHue = calculateHue;
|
|
20397
24563
|
exports.calculateLightness = calculateLightness;
|