@ceed/ads 1.28.2 → 1.29.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/components/DataTable/components.d.ts +3 -2
- package/dist/components/DataTable/hooks.d.ts +2 -0
- package/dist/components/DataTable/styled.d.ts +1 -1
- package/dist/components/DataTable/utils.d.ts +5 -0
- package/dist/index.browser.js +4 -4
- package/dist/index.browser.js.map +4 -4
- package/dist/index.cjs +186 -16
- package/dist/index.js +186 -16
- package/dist/libs/text-measurer.d.ts +8 -0
- package/framer/index.js +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -2089,6 +2089,36 @@ var CurrencyInput_default = CurrencyInput;
|
|
|
2089
2089
|
var import_react28 = __toESM(require("react"));
|
|
2090
2090
|
var import_react_virtual2 = require("@tanstack/react-virtual");
|
|
2091
2091
|
|
|
2092
|
+
// src/libs/text-measurer.ts
|
|
2093
|
+
var TextMeasurer = class {
|
|
2094
|
+
constructor(font) {
|
|
2095
|
+
const canvas = document.createElement("canvas");
|
|
2096
|
+
this.ctx = canvas.getContext("2d");
|
|
2097
|
+
if (this.ctx && font) this.ctx.font = font;
|
|
2098
|
+
}
|
|
2099
|
+
setFont(font) {
|
|
2100
|
+
if (this.ctx) this.ctx.font = font;
|
|
2101
|
+
return this;
|
|
2102
|
+
}
|
|
2103
|
+
setFontFromElement(el) {
|
|
2104
|
+
if (this.ctx) this.ctx.font = getComputedStyle(el).font;
|
|
2105
|
+
return this;
|
|
2106
|
+
}
|
|
2107
|
+
measureText(text) {
|
|
2108
|
+
if (!this.ctx) return 0;
|
|
2109
|
+
return this.ctx.measureText(text).width;
|
|
2110
|
+
}
|
|
2111
|
+
measureMaxWidth(values) {
|
|
2112
|
+
if (!this.ctx) return 0;
|
|
2113
|
+
let max = 0;
|
|
2114
|
+
for (let i = 0; i < values.length; i++) {
|
|
2115
|
+
const w = this.ctx.measureText(values[i]).width;
|
|
2116
|
+
if (w > max) max = w;
|
|
2117
|
+
}
|
|
2118
|
+
return max;
|
|
2119
|
+
}
|
|
2120
|
+
};
|
|
2121
|
+
|
|
2092
2122
|
// src/components/DataTable/utils.ts
|
|
2093
2123
|
function extractFieldsFromGroupingModel(items) {
|
|
2094
2124
|
const fields = /* @__PURE__ */ new Set();
|
|
@@ -2210,6 +2240,71 @@ function getTextAlign(props) {
|
|
|
2210
2240
|
return !props.editMode && ["number", "date", "currency"].includes(props.type || "") ? "end" : "start";
|
|
2211
2241
|
}
|
|
2212
2242
|
var numberFormatter = (value) => "Intl" in window ? new Intl.NumberFormat().format(value) : value;
|
|
2243
|
+
function computeHeaderWidth(headerEl) {
|
|
2244
|
+
const thStyle = getComputedStyle(headerEl);
|
|
2245
|
+
const paddingX = parseFloat(thStyle.paddingLeft) + parseFloat(thStyle.paddingRight);
|
|
2246
|
+
const borderX = parseFloat(thStyle.borderLeftWidth) + parseFloat(thStyle.borderRightWidth);
|
|
2247
|
+
const stack = headerEl.firstElementChild;
|
|
2248
|
+
if (!stack) return paddingX;
|
|
2249
|
+
const stackStyle = getComputedStyle(stack);
|
|
2250
|
+
const gap = parseFloat(stackStyle.gap) || parseFloat(stackStyle.columnGap) || 0;
|
|
2251
|
+
let totalChildWidth = 0;
|
|
2252
|
+
let visibleChildCount = 0;
|
|
2253
|
+
for (const child of Array.from(stack.children)) {
|
|
2254
|
+
const el = child;
|
|
2255
|
+
if (!el.offsetWidth && !el.offsetHeight) continue;
|
|
2256
|
+
visibleChildCount++;
|
|
2257
|
+
const textEl = el.querySelector?.('[data-slot="header-text"]') || (el.dataset?.slot === "header-text" ? el : null);
|
|
2258
|
+
if (textEl) {
|
|
2259
|
+
const htmlEl = textEl;
|
|
2260
|
+
const isMultiLine = getComputedStyle(htmlEl).display === "-webkit-box";
|
|
2261
|
+
if (isMultiLine) {
|
|
2262
|
+
const measurer = new TextMeasurer();
|
|
2263
|
+
measurer.setFontFromElement(htmlEl);
|
|
2264
|
+
totalChildWidth += measurer.measureText(htmlEl.textContent || "");
|
|
2265
|
+
} else {
|
|
2266
|
+
totalChildWidth += htmlEl.scrollWidth;
|
|
2267
|
+
}
|
|
2268
|
+
} else {
|
|
2269
|
+
totalChildWidth += el.offsetWidth;
|
|
2270
|
+
}
|
|
2271
|
+
}
|
|
2272
|
+
const totalGaps = visibleChildCount > 1 ? (visibleChildCount - 1) * gap : 0;
|
|
2273
|
+
return totalChildWidth + totalGaps + paddingX + borderX;
|
|
2274
|
+
}
|
|
2275
|
+
function computeBodyWidth(headerEl, table, field, dataInPage) {
|
|
2276
|
+
const headId = headerEl.id;
|
|
2277
|
+
const sampleTd = headId ? table.querySelector(`tbody td[headers="${CSS.escape(headId)}"]`) : null;
|
|
2278
|
+
const styleSource = sampleTd || headerEl;
|
|
2279
|
+
const tdStyle = getComputedStyle(styleSource);
|
|
2280
|
+
const bodyPaddingX = parseFloat(tdStyle.paddingLeft) + parseFloat(tdStyle.paddingRight);
|
|
2281
|
+
const bodyBorderX = parseFloat(tdStyle.borderLeftWidth) + parseFloat(tdStyle.borderRightWidth);
|
|
2282
|
+
const measurer = new TextMeasurer();
|
|
2283
|
+
measurer.setFont(tdStyle.font);
|
|
2284
|
+
const texts = [];
|
|
2285
|
+
for (let i = 0; i < dataInPage.length; i++) {
|
|
2286
|
+
const val = dataInPage[i][field];
|
|
2287
|
+
texts.push(val == null ? "" : String(val));
|
|
2288
|
+
}
|
|
2289
|
+
const maxTextWidth = measurer.measureMaxWidth(texts);
|
|
2290
|
+
return maxTextWidth + bodyPaddingX + bodyBorderX;
|
|
2291
|
+
}
|
|
2292
|
+
function computeAutoFitWidth(params) {
|
|
2293
|
+
const { headerEl, field, dataInPage } = params;
|
|
2294
|
+
const table = headerEl.closest("table");
|
|
2295
|
+
if (!table) return null;
|
|
2296
|
+
const headerWidth = computeHeaderWidth(headerEl);
|
|
2297
|
+
const bodyWidth = computeBodyWidth(headerEl, table, field, dataInPage);
|
|
2298
|
+
let finalWidth = Math.ceil(Math.max(headerWidth, bodyWidth));
|
|
2299
|
+
const thStyle = getComputedStyle(headerEl);
|
|
2300
|
+
const resolvedMin = thStyle.minWidth;
|
|
2301
|
+
const resolvedMax = thStyle.maxWidth;
|
|
2302
|
+
const minPx = resolvedMin !== "none" ? parseFloat(resolvedMin) : NaN;
|
|
2303
|
+
const maxPx = resolvedMax !== "none" ? parseFloat(resolvedMax) : NaN;
|
|
2304
|
+
if (!isNaN(minPx) && minPx > 0) finalWidth = Math.max(finalWidth, minPx);
|
|
2305
|
+
if (!isNaN(maxPx) && maxPx > 0) finalWidth = Math.min(finalWidth, maxPx);
|
|
2306
|
+
return finalWidth;
|
|
2307
|
+
}
|
|
2213
2308
|
|
|
2214
2309
|
// src/components/DataTable/styled.tsx
|
|
2215
2310
|
var import_react19 = __toESM(require("react"));
|
|
@@ -2320,7 +2415,7 @@ var StyledTd = (0, import_joy25.styled)("td")(({ theme }) => ({
|
|
|
2320
2415
|
var MotionSortIcon = (0, import_framer_motion17.motion)(import_ArrowUpwardRounded.default);
|
|
2321
2416
|
var DefaultLoadingOverlay = () => /* @__PURE__ */ import_react19.default.createElement(import_joy25.LinearProgress, { value: 8, variant: "plain" });
|
|
2322
2417
|
var DefaultNoRowsOverlay = () => /* @__PURE__ */ import_react19.default.createElement(import_joy25.Typography, { level: "body-sm", textColor: "text.tertiary" }, "No rows");
|
|
2323
|
-
var Resizer = (ref, targetRef = ref, onResizeStateChange) => /* @__PURE__ */ import_react19.default.createElement(
|
|
2418
|
+
var Resizer = (ref, targetRef = ref, onResizeStateChange, onAutoFit) => /* @__PURE__ */ import_react19.default.createElement(
|
|
2324
2419
|
Box_default,
|
|
2325
2420
|
{
|
|
2326
2421
|
sx: {
|
|
@@ -2328,24 +2423,67 @@ var Resizer = (ref, targetRef = ref, onResizeStateChange) => /* @__PURE__ */ imp
|
|
|
2328
2423
|
top: 0,
|
|
2329
2424
|
right: 0,
|
|
2330
2425
|
bottom: 0,
|
|
2331
|
-
width: "
|
|
2332
|
-
cursor: "col-resize"
|
|
2426
|
+
width: "7px",
|
|
2427
|
+
cursor: "col-resize",
|
|
2428
|
+
"&::after": {
|
|
2429
|
+
content: '""',
|
|
2430
|
+
position: "absolute",
|
|
2431
|
+
top: 0,
|
|
2432
|
+
bottom: 0,
|
|
2433
|
+
right: 0,
|
|
2434
|
+
width: "2px",
|
|
2435
|
+
bgcolor: "transparent",
|
|
2436
|
+
transition: "background-color 150ms ease"
|
|
2437
|
+
},
|
|
2438
|
+
"&:hover::after": {
|
|
2439
|
+
bgcolor: "primary.300"
|
|
2440
|
+
},
|
|
2441
|
+
"&[data-resizing]::after": {
|
|
2442
|
+
bgcolor: "primary.500"
|
|
2443
|
+
}
|
|
2333
2444
|
},
|
|
2334
2445
|
onClick: (e) => e.stopPropagation(),
|
|
2446
|
+
onDoubleClick: (e) => {
|
|
2447
|
+
e.stopPropagation();
|
|
2448
|
+
e.preventDefault();
|
|
2449
|
+
onAutoFit?.();
|
|
2450
|
+
},
|
|
2335
2451
|
onMouseDown: (e) => {
|
|
2452
|
+
if (e.detail >= 2) return;
|
|
2453
|
+
const resizerEl = e.currentTarget;
|
|
2454
|
+
resizerEl.dataset.resizing = "";
|
|
2336
2455
|
const initialX = e.clientX;
|
|
2337
2456
|
const initialWidth = ref.current?.getBoundingClientRect().width;
|
|
2338
|
-
|
|
2457
|
+
let activated = false;
|
|
2458
|
+
const DRAG_THRESHOLD = 3;
|
|
2459
|
+
const thStyle = ref.current ? getComputedStyle(ref.current) : null;
|
|
2460
|
+
const minW = thStyle ? parseFloat(thStyle.minWidth) : NaN;
|
|
2461
|
+
const maxW = thStyle ? parseFloat(thStyle.maxWidth) : NaN;
|
|
2339
2462
|
const onMouseMove = (e2) => {
|
|
2340
|
-
if (initialWidth
|
|
2341
|
-
|
|
2342
|
-
|
|
2463
|
+
if (!initialWidth) return;
|
|
2464
|
+
const delta = e2.clientX - initialX;
|
|
2465
|
+
if (!activated) {
|
|
2466
|
+
if (Math.abs(delta) < DRAG_THRESHOLD) return;
|
|
2467
|
+
activated = true;
|
|
2468
|
+
onResizeStateChange?.(true);
|
|
2469
|
+
}
|
|
2470
|
+
if (!ref.current || !targetRef.current) {
|
|
2471
|
+
onMouseUp();
|
|
2472
|
+
return;
|
|
2343
2473
|
}
|
|
2474
|
+
let newWidth = initialWidth + delta;
|
|
2475
|
+
if (!isNaN(minW) && minW > 0) newWidth = Math.max(newWidth, minW);
|
|
2476
|
+
if (!isNaN(maxW) && maxW > 0) newWidth = Math.min(newWidth, maxW);
|
|
2477
|
+
ref.current.style.width = `${newWidth}px`;
|
|
2478
|
+
targetRef.current.style.width = `${newWidth}px`;
|
|
2344
2479
|
};
|
|
2345
2480
|
const onMouseUp = () => {
|
|
2481
|
+
resizerEl.removeAttribute("data-resizing");
|
|
2346
2482
|
document.removeEventListener("mousemove", onMouseMove);
|
|
2347
2483
|
document.removeEventListener("mouseup", onMouseUp);
|
|
2348
|
-
|
|
2484
|
+
if (activated) {
|
|
2485
|
+
requestAnimationFrame(() => onResizeStateChange?.(false));
|
|
2486
|
+
}
|
|
2349
2487
|
};
|
|
2350
2488
|
document.addEventListener("mousemove", onMouseMove);
|
|
2351
2489
|
document.addEventListener("mouseup", onMouseUp);
|
|
@@ -2918,7 +3056,11 @@ function InfoSign(props) {
|
|
|
2918
3056
|
var InfoSign_default = InfoSign;
|
|
2919
3057
|
|
|
2920
3058
|
// src/components/DataTable/components.tsx
|
|
2921
|
-
var TextEllipsis = ({
|
|
3059
|
+
var TextEllipsis = ({
|
|
3060
|
+
children,
|
|
3061
|
+
lineClamp,
|
|
3062
|
+
...rest
|
|
3063
|
+
}) => {
|
|
2922
3064
|
const textRef = (0, import_react24.useRef)(null);
|
|
2923
3065
|
const [showTooltip, setShowTooltip] = (0, import_react24.useState)(false);
|
|
2924
3066
|
(0, import_react24.useLayoutEffect)(() => {
|
|
@@ -2933,7 +3075,7 @@ var TextEllipsis = ({ children, lineClamp }) => {
|
|
|
2933
3075
|
ro.observe(element);
|
|
2934
3076
|
return () => ro.disconnect();
|
|
2935
3077
|
}, [children, lineClamp]);
|
|
2936
|
-
return /* @__PURE__ */ import_react24.default.createElement(Tooltip_default, { title: showTooltip ? children : "", placement: "top" }, /* @__PURE__ */ import_react24.default.createElement(EllipsisDiv, { ref: textRef, lineClamp }, children));
|
|
3078
|
+
return /* @__PURE__ */ import_react24.default.createElement(Tooltip_default, { title: showTooltip ? children : "", placement: "top" }, /* @__PURE__ */ import_react24.default.createElement(EllipsisDiv, { ref: textRef, lineClamp, ...rest }, children));
|
|
2937
3079
|
};
|
|
2938
3080
|
var CellTextEllipsis = ({ children }) => {
|
|
2939
3081
|
const textRef = (0, import_react24.useRef)(null);
|
|
@@ -2985,7 +3127,8 @@ var HeadCell = (props) => {
|
|
|
2985
3127
|
headerRef,
|
|
2986
3128
|
tableColRef,
|
|
2987
3129
|
headerClassName,
|
|
2988
|
-
headerLineClamp
|
|
3130
|
+
headerLineClamp,
|
|
3131
|
+
onAutoFit
|
|
2989
3132
|
} = props;
|
|
2990
3133
|
const theme = (0, import_joy32.useTheme)();
|
|
2991
3134
|
const ref = headerRef;
|
|
@@ -3002,10 +3145,15 @@ var HeadCell = (props) => {
|
|
|
3002
3145
|
);
|
|
3003
3146
|
const isResizingRef = (0, import_react24.useRef)(false);
|
|
3004
3147
|
const resizer = (0, import_react24.useMemo)(
|
|
3005
|
-
() => resizable ?? true ? Resizer(
|
|
3006
|
-
|
|
3007
|
-
|
|
3008
|
-
|
|
3148
|
+
() => resizable ?? true ? Resizer(
|
|
3149
|
+
ref,
|
|
3150
|
+
colRef,
|
|
3151
|
+
(isResizing) => {
|
|
3152
|
+
isResizingRef.current = isResizing;
|
|
3153
|
+
},
|
|
3154
|
+
onAutoFit ? () => onAutoFit(field) : void 0
|
|
3155
|
+
) : null,
|
|
3156
|
+
[resizable, ref, colRef, onAutoFit, field]
|
|
3009
3157
|
);
|
|
3010
3158
|
const style = (0, import_react24.useMemo)(
|
|
3011
3159
|
() => ({
|
|
@@ -3093,7 +3241,7 @@ var HeadCell = (props) => {
|
|
|
3093
3241
|
initial: "initial",
|
|
3094
3242
|
className: computedHeaderClassName
|
|
3095
3243
|
},
|
|
3096
|
-
/* @__PURE__ */ import_react24.default.createElement(Stack_default, { gap: 1, direction: "row", justifyContent: textAlign, alignItems: "center", sx: { minWidth: 0 } }, textAlign === "end" && sortIcon, textAlign === "end" && infoSign, /* @__PURE__ */ import_react24.default.createElement(TextEllipsis, { lineClamp: headerLineClamp }, headerName ?? field, editMode && required && /* @__PURE__ */ import_react24.default.createElement(Asterisk, null, "*")), textAlign === "start" && infoSign, textAlign === "start" && sortIcon),
|
|
3244
|
+
/* @__PURE__ */ import_react24.default.createElement(Stack_default, { gap: 1, direction: "row", justifyContent: textAlign, alignItems: "center", sx: { minWidth: 0 } }, textAlign === "end" && sortIcon, textAlign === "end" && infoSign, /* @__PURE__ */ import_react24.default.createElement(TextEllipsis, { lineClamp: headerLineClamp, "data-slot": "header-text" }, headerName ?? field, editMode && required && /* @__PURE__ */ import_react24.default.createElement(Asterisk, null, "*")), textAlign === "start" && infoSign, textAlign === "start" && sortIcon),
|
|
3097
3245
|
resizer
|
|
3098
3246
|
);
|
|
3099
3247
|
};
|
|
@@ -3640,6 +3788,25 @@ function useDataTableRenderer({
|
|
|
3640
3788
|
prevRowsRef.current = _rows;
|
|
3641
3789
|
}
|
|
3642
3790
|
}, [_rows]);
|
|
3791
|
+
const handleAutoFit = (0, import_react25.useCallback)(
|
|
3792
|
+
(field) => {
|
|
3793
|
+
const colDef = visibleColumnsByField[field];
|
|
3794
|
+
if (!colDef?.headerRef.current) return;
|
|
3795
|
+
const column = allColumnsByField[field];
|
|
3796
|
+
const columnType = column && "type" in column ? column.type : void 0;
|
|
3797
|
+
if (columnType === "actions") return;
|
|
3798
|
+
const optimalWidth = computeAutoFitWidth({
|
|
3799
|
+
headerEl: colDef.headerRef.current,
|
|
3800
|
+
field,
|
|
3801
|
+
dataInPage
|
|
3802
|
+
});
|
|
3803
|
+
if (optimalWidth == null) return;
|
|
3804
|
+
const widthPx = `${optimalWidth}px`;
|
|
3805
|
+
colDef.headerRef.current.style.width = widthPx;
|
|
3806
|
+
if (colDef.tableColRef.current) colDef.tableColRef.current.style.width = widthPx;
|
|
3807
|
+
},
|
|
3808
|
+
[visibleColumnsByField, allColumnsByField, dataInPage]
|
|
3809
|
+
);
|
|
3643
3810
|
return {
|
|
3644
3811
|
rowCount,
|
|
3645
3812
|
selectableRowCount,
|
|
@@ -3651,6 +3818,7 @@ function useDataTableRenderer({
|
|
|
3651
3818
|
BodyRow,
|
|
3652
3819
|
dataInPage,
|
|
3653
3820
|
handleSortChange,
|
|
3821
|
+
handleAutoFit,
|
|
3654
3822
|
isAllSelected,
|
|
3655
3823
|
isTotalSelected,
|
|
3656
3824
|
isSelectedRow: (0, import_react25.useCallback)((model) => selectedModelSet.has(model), [selectedModelSet]),
|
|
@@ -4081,6 +4249,7 @@ function Component(props, apiRef) {
|
|
|
4081
4249
|
pageSize,
|
|
4082
4250
|
onPaginationModelChange,
|
|
4083
4251
|
handleSortChange,
|
|
4252
|
+
handleAutoFit,
|
|
4084
4253
|
dataInPage,
|
|
4085
4254
|
isTotalSelected,
|
|
4086
4255
|
focusedRowId,
|
|
@@ -4359,6 +4528,7 @@ function Component(props, apiRef) {
|
|
|
4359
4528
|
stickyHeader: props.stickyHeader,
|
|
4360
4529
|
editMode: !!c.isCellEditable,
|
|
4361
4530
|
onSortChange: handleSortChange,
|
|
4531
|
+
onAutoFit: handleAutoFit,
|
|
4362
4532
|
...c
|
|
4363
4533
|
}
|
|
4364
4534
|
)
|
package/dist/index.js
CHANGED
|
@@ -1955,6 +1955,36 @@ import React25, {
|
|
|
1955
1955
|
} from "react";
|
|
1956
1956
|
import { useVirtualizer as useVirtualizer2 } from "@tanstack/react-virtual";
|
|
1957
1957
|
|
|
1958
|
+
// src/libs/text-measurer.ts
|
|
1959
|
+
var TextMeasurer = class {
|
|
1960
|
+
constructor(font) {
|
|
1961
|
+
const canvas = document.createElement("canvas");
|
|
1962
|
+
this.ctx = canvas.getContext("2d");
|
|
1963
|
+
if (this.ctx && font) this.ctx.font = font;
|
|
1964
|
+
}
|
|
1965
|
+
setFont(font) {
|
|
1966
|
+
if (this.ctx) this.ctx.font = font;
|
|
1967
|
+
return this;
|
|
1968
|
+
}
|
|
1969
|
+
setFontFromElement(el) {
|
|
1970
|
+
if (this.ctx) this.ctx.font = getComputedStyle(el).font;
|
|
1971
|
+
return this;
|
|
1972
|
+
}
|
|
1973
|
+
measureText(text) {
|
|
1974
|
+
if (!this.ctx) return 0;
|
|
1975
|
+
return this.ctx.measureText(text).width;
|
|
1976
|
+
}
|
|
1977
|
+
measureMaxWidth(values) {
|
|
1978
|
+
if (!this.ctx) return 0;
|
|
1979
|
+
let max = 0;
|
|
1980
|
+
for (let i = 0; i < values.length; i++) {
|
|
1981
|
+
const w = this.ctx.measureText(values[i]).width;
|
|
1982
|
+
if (w > max) max = w;
|
|
1983
|
+
}
|
|
1984
|
+
return max;
|
|
1985
|
+
}
|
|
1986
|
+
};
|
|
1987
|
+
|
|
1958
1988
|
// src/components/DataTable/utils.ts
|
|
1959
1989
|
function extractFieldsFromGroupingModel(items) {
|
|
1960
1990
|
const fields = /* @__PURE__ */ new Set();
|
|
@@ -2076,6 +2106,71 @@ function getTextAlign(props) {
|
|
|
2076
2106
|
return !props.editMode && ["number", "date", "currency"].includes(props.type || "") ? "end" : "start";
|
|
2077
2107
|
}
|
|
2078
2108
|
var numberFormatter = (value) => "Intl" in window ? new Intl.NumberFormat().format(value) : value;
|
|
2109
|
+
function computeHeaderWidth(headerEl) {
|
|
2110
|
+
const thStyle = getComputedStyle(headerEl);
|
|
2111
|
+
const paddingX = parseFloat(thStyle.paddingLeft) + parseFloat(thStyle.paddingRight);
|
|
2112
|
+
const borderX = parseFloat(thStyle.borderLeftWidth) + parseFloat(thStyle.borderRightWidth);
|
|
2113
|
+
const stack = headerEl.firstElementChild;
|
|
2114
|
+
if (!stack) return paddingX;
|
|
2115
|
+
const stackStyle = getComputedStyle(stack);
|
|
2116
|
+
const gap = parseFloat(stackStyle.gap) || parseFloat(stackStyle.columnGap) || 0;
|
|
2117
|
+
let totalChildWidth = 0;
|
|
2118
|
+
let visibleChildCount = 0;
|
|
2119
|
+
for (const child of Array.from(stack.children)) {
|
|
2120
|
+
const el = child;
|
|
2121
|
+
if (!el.offsetWidth && !el.offsetHeight) continue;
|
|
2122
|
+
visibleChildCount++;
|
|
2123
|
+
const textEl = el.querySelector?.('[data-slot="header-text"]') || (el.dataset?.slot === "header-text" ? el : null);
|
|
2124
|
+
if (textEl) {
|
|
2125
|
+
const htmlEl = textEl;
|
|
2126
|
+
const isMultiLine = getComputedStyle(htmlEl).display === "-webkit-box";
|
|
2127
|
+
if (isMultiLine) {
|
|
2128
|
+
const measurer = new TextMeasurer();
|
|
2129
|
+
measurer.setFontFromElement(htmlEl);
|
|
2130
|
+
totalChildWidth += measurer.measureText(htmlEl.textContent || "");
|
|
2131
|
+
} else {
|
|
2132
|
+
totalChildWidth += htmlEl.scrollWidth;
|
|
2133
|
+
}
|
|
2134
|
+
} else {
|
|
2135
|
+
totalChildWidth += el.offsetWidth;
|
|
2136
|
+
}
|
|
2137
|
+
}
|
|
2138
|
+
const totalGaps = visibleChildCount > 1 ? (visibleChildCount - 1) * gap : 0;
|
|
2139
|
+
return totalChildWidth + totalGaps + paddingX + borderX;
|
|
2140
|
+
}
|
|
2141
|
+
function computeBodyWidth(headerEl, table, field, dataInPage) {
|
|
2142
|
+
const headId = headerEl.id;
|
|
2143
|
+
const sampleTd = headId ? table.querySelector(`tbody td[headers="${CSS.escape(headId)}"]`) : null;
|
|
2144
|
+
const styleSource = sampleTd || headerEl;
|
|
2145
|
+
const tdStyle = getComputedStyle(styleSource);
|
|
2146
|
+
const bodyPaddingX = parseFloat(tdStyle.paddingLeft) + parseFloat(tdStyle.paddingRight);
|
|
2147
|
+
const bodyBorderX = parseFloat(tdStyle.borderLeftWidth) + parseFloat(tdStyle.borderRightWidth);
|
|
2148
|
+
const measurer = new TextMeasurer();
|
|
2149
|
+
measurer.setFont(tdStyle.font);
|
|
2150
|
+
const texts = [];
|
|
2151
|
+
for (let i = 0; i < dataInPage.length; i++) {
|
|
2152
|
+
const val = dataInPage[i][field];
|
|
2153
|
+
texts.push(val == null ? "" : String(val));
|
|
2154
|
+
}
|
|
2155
|
+
const maxTextWidth = measurer.measureMaxWidth(texts);
|
|
2156
|
+
return maxTextWidth + bodyPaddingX + bodyBorderX;
|
|
2157
|
+
}
|
|
2158
|
+
function computeAutoFitWidth(params) {
|
|
2159
|
+
const { headerEl, field, dataInPage } = params;
|
|
2160
|
+
const table = headerEl.closest("table");
|
|
2161
|
+
if (!table) return null;
|
|
2162
|
+
const headerWidth = computeHeaderWidth(headerEl);
|
|
2163
|
+
const bodyWidth = computeBodyWidth(headerEl, table, field, dataInPage);
|
|
2164
|
+
let finalWidth = Math.ceil(Math.max(headerWidth, bodyWidth));
|
|
2165
|
+
const thStyle = getComputedStyle(headerEl);
|
|
2166
|
+
const resolvedMin = thStyle.minWidth;
|
|
2167
|
+
const resolvedMax = thStyle.maxWidth;
|
|
2168
|
+
const minPx = resolvedMin !== "none" ? parseFloat(resolvedMin) : NaN;
|
|
2169
|
+
const maxPx = resolvedMax !== "none" ? parseFloat(resolvedMax) : NaN;
|
|
2170
|
+
if (!isNaN(minPx) && minPx > 0) finalWidth = Math.max(finalWidth, minPx);
|
|
2171
|
+
if (!isNaN(maxPx) && maxPx > 0) finalWidth = Math.min(finalWidth, maxPx);
|
|
2172
|
+
return finalWidth;
|
|
2173
|
+
}
|
|
2079
2174
|
|
|
2080
2175
|
// src/components/DataTable/styled.tsx
|
|
2081
2176
|
import React17 from "react";
|
|
@@ -2186,7 +2281,7 @@ var StyledTd = styled8("td")(({ theme }) => ({
|
|
|
2186
2281
|
var MotionSortIcon = motion17(SortIcon);
|
|
2187
2282
|
var DefaultLoadingOverlay = () => /* @__PURE__ */ React17.createElement(LinearProgress, { value: 8, variant: "plain" });
|
|
2188
2283
|
var DefaultNoRowsOverlay = () => /* @__PURE__ */ React17.createElement(Typography3, { level: "body-sm", textColor: "text.tertiary" }, "No rows");
|
|
2189
|
-
var Resizer = (ref, targetRef = ref, onResizeStateChange) => /* @__PURE__ */ React17.createElement(
|
|
2284
|
+
var Resizer = (ref, targetRef = ref, onResizeStateChange, onAutoFit) => /* @__PURE__ */ React17.createElement(
|
|
2190
2285
|
Box_default,
|
|
2191
2286
|
{
|
|
2192
2287
|
sx: {
|
|
@@ -2194,24 +2289,67 @@ var Resizer = (ref, targetRef = ref, onResizeStateChange) => /* @__PURE__ */ Rea
|
|
|
2194
2289
|
top: 0,
|
|
2195
2290
|
right: 0,
|
|
2196
2291
|
bottom: 0,
|
|
2197
|
-
width: "
|
|
2198
|
-
cursor: "col-resize"
|
|
2292
|
+
width: "7px",
|
|
2293
|
+
cursor: "col-resize",
|
|
2294
|
+
"&::after": {
|
|
2295
|
+
content: '""',
|
|
2296
|
+
position: "absolute",
|
|
2297
|
+
top: 0,
|
|
2298
|
+
bottom: 0,
|
|
2299
|
+
right: 0,
|
|
2300
|
+
width: "2px",
|
|
2301
|
+
bgcolor: "transparent",
|
|
2302
|
+
transition: "background-color 150ms ease"
|
|
2303
|
+
},
|
|
2304
|
+
"&:hover::after": {
|
|
2305
|
+
bgcolor: "primary.300"
|
|
2306
|
+
},
|
|
2307
|
+
"&[data-resizing]::after": {
|
|
2308
|
+
bgcolor: "primary.500"
|
|
2309
|
+
}
|
|
2199
2310
|
},
|
|
2200
2311
|
onClick: (e) => e.stopPropagation(),
|
|
2312
|
+
onDoubleClick: (e) => {
|
|
2313
|
+
e.stopPropagation();
|
|
2314
|
+
e.preventDefault();
|
|
2315
|
+
onAutoFit?.();
|
|
2316
|
+
},
|
|
2201
2317
|
onMouseDown: (e) => {
|
|
2318
|
+
if (e.detail >= 2) return;
|
|
2319
|
+
const resizerEl = e.currentTarget;
|
|
2320
|
+
resizerEl.dataset.resizing = "";
|
|
2202
2321
|
const initialX = e.clientX;
|
|
2203
2322
|
const initialWidth = ref.current?.getBoundingClientRect().width;
|
|
2204
|
-
|
|
2323
|
+
let activated = false;
|
|
2324
|
+
const DRAG_THRESHOLD = 3;
|
|
2325
|
+
const thStyle = ref.current ? getComputedStyle(ref.current) : null;
|
|
2326
|
+
const minW = thStyle ? parseFloat(thStyle.minWidth) : NaN;
|
|
2327
|
+
const maxW = thStyle ? parseFloat(thStyle.maxWidth) : NaN;
|
|
2205
2328
|
const onMouseMove = (e2) => {
|
|
2206
|
-
if (initialWidth
|
|
2207
|
-
|
|
2208
|
-
|
|
2329
|
+
if (!initialWidth) return;
|
|
2330
|
+
const delta = e2.clientX - initialX;
|
|
2331
|
+
if (!activated) {
|
|
2332
|
+
if (Math.abs(delta) < DRAG_THRESHOLD) return;
|
|
2333
|
+
activated = true;
|
|
2334
|
+
onResizeStateChange?.(true);
|
|
2335
|
+
}
|
|
2336
|
+
if (!ref.current || !targetRef.current) {
|
|
2337
|
+
onMouseUp();
|
|
2338
|
+
return;
|
|
2209
2339
|
}
|
|
2340
|
+
let newWidth = initialWidth + delta;
|
|
2341
|
+
if (!isNaN(minW) && minW > 0) newWidth = Math.max(newWidth, minW);
|
|
2342
|
+
if (!isNaN(maxW) && maxW > 0) newWidth = Math.min(newWidth, maxW);
|
|
2343
|
+
ref.current.style.width = `${newWidth}px`;
|
|
2344
|
+
targetRef.current.style.width = `${newWidth}px`;
|
|
2210
2345
|
};
|
|
2211
2346
|
const onMouseUp = () => {
|
|
2347
|
+
resizerEl.removeAttribute("data-resizing");
|
|
2212
2348
|
document.removeEventListener("mousemove", onMouseMove);
|
|
2213
2349
|
document.removeEventListener("mouseup", onMouseUp);
|
|
2214
|
-
|
|
2350
|
+
if (activated) {
|
|
2351
|
+
requestAnimationFrame(() => onResizeStateChange?.(false));
|
|
2352
|
+
}
|
|
2215
2353
|
};
|
|
2216
2354
|
document.addEventListener("mousemove", onMouseMove);
|
|
2217
2355
|
document.addEventListener("mouseup", onMouseUp);
|
|
@@ -2793,7 +2931,11 @@ function InfoSign(props) {
|
|
|
2793
2931
|
var InfoSign_default = InfoSign;
|
|
2794
2932
|
|
|
2795
2933
|
// src/components/DataTable/components.tsx
|
|
2796
|
-
var TextEllipsis = ({
|
|
2934
|
+
var TextEllipsis = ({
|
|
2935
|
+
children,
|
|
2936
|
+
lineClamp,
|
|
2937
|
+
...rest
|
|
2938
|
+
}) => {
|
|
2797
2939
|
const textRef = useRef5(null);
|
|
2798
2940
|
const [showTooltip, setShowTooltip] = useState8(false);
|
|
2799
2941
|
useLayoutEffect(() => {
|
|
@@ -2808,7 +2950,7 @@ var TextEllipsis = ({ children, lineClamp }) => {
|
|
|
2808
2950
|
ro.observe(element);
|
|
2809
2951
|
return () => ro.disconnect();
|
|
2810
2952
|
}, [children, lineClamp]);
|
|
2811
|
-
return /* @__PURE__ */ React22.createElement(Tooltip_default, { title: showTooltip ? children : "", placement: "top" }, /* @__PURE__ */ React22.createElement(EllipsisDiv, { ref: textRef, lineClamp }, children));
|
|
2953
|
+
return /* @__PURE__ */ React22.createElement(Tooltip_default, { title: showTooltip ? children : "", placement: "top" }, /* @__PURE__ */ React22.createElement(EllipsisDiv, { ref: textRef, lineClamp, ...rest }, children));
|
|
2812
2954
|
};
|
|
2813
2955
|
var CellTextEllipsis = ({ children }) => {
|
|
2814
2956
|
const textRef = useRef5(null);
|
|
@@ -2860,7 +3002,8 @@ var HeadCell = (props) => {
|
|
|
2860
3002
|
headerRef,
|
|
2861
3003
|
tableColRef,
|
|
2862
3004
|
headerClassName,
|
|
2863
|
-
headerLineClamp
|
|
3005
|
+
headerLineClamp,
|
|
3006
|
+
onAutoFit
|
|
2864
3007
|
} = props;
|
|
2865
3008
|
const theme = useTheme();
|
|
2866
3009
|
const ref = headerRef;
|
|
@@ -2877,10 +3020,15 @@ var HeadCell = (props) => {
|
|
|
2877
3020
|
);
|
|
2878
3021
|
const isResizingRef = useRef5(false);
|
|
2879
3022
|
const resizer = useMemo8(
|
|
2880
|
-
() => resizable ?? true ? Resizer(
|
|
2881
|
-
|
|
2882
|
-
|
|
2883
|
-
|
|
3023
|
+
() => resizable ?? true ? Resizer(
|
|
3024
|
+
ref,
|
|
3025
|
+
colRef,
|
|
3026
|
+
(isResizing) => {
|
|
3027
|
+
isResizingRef.current = isResizing;
|
|
3028
|
+
},
|
|
3029
|
+
onAutoFit ? () => onAutoFit(field) : void 0
|
|
3030
|
+
) : null,
|
|
3031
|
+
[resizable, ref, colRef, onAutoFit, field]
|
|
2884
3032
|
);
|
|
2885
3033
|
const style = useMemo8(
|
|
2886
3034
|
() => ({
|
|
@@ -2968,7 +3116,7 @@ var HeadCell = (props) => {
|
|
|
2968
3116
|
initial: "initial",
|
|
2969
3117
|
className: computedHeaderClassName
|
|
2970
3118
|
},
|
|
2971
|
-
/* @__PURE__ */ React22.createElement(Stack_default, { gap: 1, direction: "row", justifyContent: textAlign, alignItems: "center", sx: { minWidth: 0 } }, textAlign === "end" && sortIcon, textAlign === "end" && infoSign, /* @__PURE__ */ React22.createElement(TextEllipsis, { lineClamp: headerLineClamp }, headerName ?? field, editMode && required && /* @__PURE__ */ React22.createElement(Asterisk, null, "*")), textAlign === "start" && infoSign, textAlign === "start" && sortIcon),
|
|
3119
|
+
/* @__PURE__ */ React22.createElement(Stack_default, { gap: 1, direction: "row", justifyContent: textAlign, alignItems: "center", sx: { minWidth: 0 } }, textAlign === "end" && sortIcon, textAlign === "end" && infoSign, /* @__PURE__ */ React22.createElement(TextEllipsis, { lineClamp: headerLineClamp, "data-slot": "header-text" }, headerName ?? field, editMode && required && /* @__PURE__ */ React22.createElement(Asterisk, null, "*")), textAlign === "start" && infoSign, textAlign === "start" && sortIcon),
|
|
2972
3120
|
resizer
|
|
2973
3121
|
);
|
|
2974
3122
|
};
|
|
@@ -3515,6 +3663,25 @@ function useDataTableRenderer({
|
|
|
3515
3663
|
prevRowsRef.current = _rows;
|
|
3516
3664
|
}
|
|
3517
3665
|
}, [_rows]);
|
|
3666
|
+
const handleAutoFit = useCallback10(
|
|
3667
|
+
(field) => {
|
|
3668
|
+
const colDef = visibleColumnsByField[field];
|
|
3669
|
+
if (!colDef?.headerRef.current) return;
|
|
3670
|
+
const column = allColumnsByField[field];
|
|
3671
|
+
const columnType = column && "type" in column ? column.type : void 0;
|
|
3672
|
+
if (columnType === "actions") return;
|
|
3673
|
+
const optimalWidth = computeAutoFitWidth({
|
|
3674
|
+
headerEl: colDef.headerRef.current,
|
|
3675
|
+
field,
|
|
3676
|
+
dataInPage
|
|
3677
|
+
});
|
|
3678
|
+
if (optimalWidth == null) return;
|
|
3679
|
+
const widthPx = `${optimalWidth}px`;
|
|
3680
|
+
colDef.headerRef.current.style.width = widthPx;
|
|
3681
|
+
if (colDef.tableColRef.current) colDef.tableColRef.current.style.width = widthPx;
|
|
3682
|
+
},
|
|
3683
|
+
[visibleColumnsByField, allColumnsByField, dataInPage]
|
|
3684
|
+
);
|
|
3518
3685
|
return {
|
|
3519
3686
|
rowCount,
|
|
3520
3687
|
selectableRowCount,
|
|
@@ -3526,6 +3693,7 @@ function useDataTableRenderer({
|
|
|
3526
3693
|
BodyRow,
|
|
3527
3694
|
dataInPage,
|
|
3528
3695
|
handleSortChange,
|
|
3696
|
+
handleAutoFit,
|
|
3529
3697
|
isAllSelected,
|
|
3530
3698
|
isTotalSelected,
|
|
3531
3699
|
isSelectedRow: useCallback10((model) => selectedModelSet.has(model), [selectedModelSet]),
|
|
@@ -3956,6 +4124,7 @@ function Component(props, apiRef) {
|
|
|
3956
4124
|
pageSize,
|
|
3957
4125
|
onPaginationModelChange,
|
|
3958
4126
|
handleSortChange,
|
|
4127
|
+
handleAutoFit,
|
|
3959
4128
|
dataInPage,
|
|
3960
4129
|
isTotalSelected,
|
|
3961
4130
|
focusedRowId,
|
|
@@ -4234,6 +4403,7 @@ function Component(props, apiRef) {
|
|
|
4234
4403
|
stickyHeader: props.stickyHeader,
|
|
4235
4404
|
editMode: !!c.isCellEditable,
|
|
4236
4405
|
onSortChange: handleSortChange,
|
|
4406
|
+
onAutoFit: handleAutoFit,
|
|
4237
4407
|
...c
|
|
4238
4408
|
}
|
|
4239
4409
|
)
|