@versini/ui-datagrid 0.3.2 → 0.3.4
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/DataGrid/DataGrid.js +10 -2
- package/dist/DataGrid/DataGridContext.js +1 -1
- package/dist/DataGrid/index.js +1 -1
- package/dist/DataGrid/utilities.js +1 -1
- package/dist/DataGridAnimated/AnimatedWrapper.js +1 -1
- package/dist/DataGridAnimated/index.js +1 -1
- package/dist/DataGridAnimated/useAnimatedHeight.js +1 -1
- package/dist/DataGridBody/DataGridBody.js +67 -19
- package/dist/DataGridBody/index.js +1 -1
- package/dist/DataGridCell/DataGridCell.js +4 -4
- package/dist/DataGridCell/index.js +1 -1
- package/dist/DataGridCellSort/DataGridCellSort.js +1 -1
- package/dist/DataGridCellSort/index.js +1 -1
- package/dist/DataGridConstants/DataGridConstants.js +1 -1
- package/dist/DataGridConstants/index.js +1 -1
- package/dist/DataGridFooter/DataGridFooter.js +1 -1
- package/dist/DataGridFooter/index.js +1 -1
- package/dist/DataGridHeader/DataGridHeader.js +1 -1
- package/dist/DataGridHeader/index.js +1 -1
- package/dist/DataGridInfinite/InfiniteScrollMarker.js +1 -1
- package/dist/DataGridInfinite/index.js +1 -1
- package/dist/DataGridInfinite/useInfiniteScroll.js +1 -1
- package/dist/DataGridRow/DataGridRow.js +20 -8
- package/dist/DataGridRow/index.js +1 -1
- package/dist/DataGridSorting/index.js +1 -1
- package/dist/DataGridSorting/sortingUtils.js +1 -1
- package/dist/common/utilities.js +1 -1
- package/package.json +2 -2
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/*!
|
|
2
|
-
@versini/ui-datagrid v0.3.
|
|
2
|
+
@versini/ui-datagrid v0.3.4
|
|
3
3
|
© 2026 gizmette.com
|
|
4
4
|
*/
|
|
5
5
|
|
|
@@ -41,6 +41,11 @@ import { getDataGridClasses } from "./utilities.js";
|
|
|
41
41
|
* hard-coded Tailwind padding classes.
|
|
42
42
|
*/ const [headerHeight, setHeaderHeight] = useState(0);
|
|
43
43
|
const [footerHeight, setFooterHeight] = useState(0);
|
|
44
|
+
/**
|
|
45
|
+
* Track measured column widths from the body. Used by sticky header/footer
|
|
46
|
+
* to sync column widths since absolutely positioned elements can't use
|
|
47
|
+
* CSS subgrid.
|
|
48
|
+
*/ const [measuredColumnWidths, setMeasuredColumnWidths] = useState([]);
|
|
44
49
|
/**
|
|
45
50
|
* Registration callbacks with stable references. Called by
|
|
46
51
|
* DataGridHeader/DataGridFooter on mount/unmount. Uses increment/decrement to
|
|
@@ -88,13 +93,15 @@ import { getDataGridClasses } from "./utilities.js";
|
|
|
88
93
|
stickyFooter: effectiveStickyFooter,
|
|
89
94
|
blurEffect,
|
|
90
95
|
columns,
|
|
96
|
+
measuredColumnWidths,
|
|
91
97
|
setCaptionId: handleSetCaptionId,
|
|
92
98
|
registerHeader,
|
|
93
99
|
unregisterHeader,
|
|
94
100
|
registerFooter,
|
|
95
101
|
unregisterFooter,
|
|
96
102
|
setHeaderHeight,
|
|
97
|
-
setFooterHeight
|
|
103
|
+
setFooterHeight,
|
|
104
|
+
setMeasuredColumnWidths
|
|
98
105
|
}), [
|
|
99
106
|
mode,
|
|
100
107
|
compact,
|
|
@@ -102,6 +109,7 @@ import { getDataGridClasses } from "./utilities.js";
|
|
|
102
109
|
effectiveStickyFooter,
|
|
103
110
|
blurEffect,
|
|
104
111
|
columns,
|
|
112
|
+
measuredColumnWidths,
|
|
105
113
|
handleSetCaptionId,
|
|
106
114
|
registerHeader,
|
|
107
115
|
unregisterHeader,
|
package/dist/DataGrid/index.js
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
/*!
|
|
2
|
-
@versini/ui-datagrid v0.3.
|
|
2
|
+
@versini/ui-datagrid v0.3.4
|
|
3
3
|
© 2026 gizmette.com
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
6
|
import { jsx } from "react/jsx-runtime";
|
|
7
7
|
import clsx from "clsx";
|
|
8
|
+
import { useContext, useLayoutEffect, useRef } from "react";
|
|
8
9
|
import { DataGridContext } from "../DataGrid/DataGridContext.js";
|
|
9
10
|
import { CellWrapper } from "../DataGridConstants/index.js";
|
|
10
11
|
|
|
@@ -12,6 +13,8 @@ import { CellWrapper } from "../DataGridConstants/index.js";
|
|
|
12
13
|
|
|
13
14
|
;// CONCATENATED MODULE: external "clsx"
|
|
14
15
|
|
|
16
|
+
;// CONCATENATED MODULE: external "react"
|
|
17
|
+
|
|
15
18
|
;// CONCATENATED MODULE: external "../DataGrid/DataGridContext.js"
|
|
16
19
|
|
|
17
20
|
;// CONCATENATED MODULE: external "../DataGridConstants/index.js"
|
|
@@ -21,28 +24,73 @@ import { CellWrapper } from "../DataGridConstants/index.js";
|
|
|
21
24
|
|
|
22
25
|
|
|
23
26
|
|
|
27
|
+
|
|
24
28
|
/* =============================================================================
|
|
25
29
|
* DataGridBody
|
|
26
30
|
* ========================================================================== */ const DataGridBody = ({ className, children, ...rest })=>{
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
31
|
+
const ctx = useContext(DataGridContext);
|
|
32
|
+
const bodyRef = useRef(null);
|
|
33
|
+
/**
|
|
34
|
+
* Measure column widths from the first body row's cells. This is needed
|
|
35
|
+
* because sticky header/footer are absolutely positioned and can't use
|
|
36
|
+
* CSS subgrid. We measure the body cells (which ARE in the grid flow)
|
|
37
|
+
* and report the widths so header/footer can use the same pixel values.
|
|
38
|
+
*/ useLayoutEffect(()=>{
|
|
39
|
+
const element = bodyRef.current;
|
|
40
|
+
const needsMeasurement = ctx.columns && (ctx.stickyHeader || ctx.stickyFooter);
|
|
41
|
+
if (!element || !needsMeasurement || !ctx.setMeasuredColumnWidths) {
|
|
42
|
+
return;
|
|
43
|
+
}
|
|
44
|
+
// Find the first row and its cells once, reuse for both measurement and observation
|
|
45
|
+
const firstRow = element.querySelector('[role="row"]');
|
|
46
|
+
if (!firstRow) {
|
|
47
|
+
return;
|
|
48
|
+
}
|
|
49
|
+
const cells = firstRow.querySelectorAll('[role="cell"], [role="columnheader"], [role="gridcell"]');
|
|
50
|
+
if (cells.length === 0) {
|
|
51
|
+
return;
|
|
52
|
+
}
|
|
53
|
+
const measureColumns = ()=>{
|
|
54
|
+
// Measure each cell's width
|
|
55
|
+
const widths = Array.from(cells).map((cell)=>cell.getBoundingClientRect().width);
|
|
56
|
+
ctx.setMeasuredColumnWidths?.(widths);
|
|
57
|
+
};
|
|
58
|
+
// Initial measurement
|
|
59
|
+
measureColumns();
|
|
60
|
+
// Set up ResizeObserver to re-measure when cells resize
|
|
61
|
+
const observer = new ResizeObserver(()=>{
|
|
62
|
+
measureColumns();
|
|
63
|
+
});
|
|
64
|
+
// Observe the body element for any size changes
|
|
65
|
+
observer.observe(element);
|
|
66
|
+
// Also observe the first row's cells directly for more accurate updates
|
|
67
|
+
for (const cell of cells){
|
|
68
|
+
observer.observe(cell);
|
|
45
69
|
}
|
|
70
|
+
return ()=>observer.disconnect();
|
|
71
|
+
}, [
|
|
72
|
+
ctx.columns,
|
|
73
|
+
ctx.stickyHeader,
|
|
74
|
+
ctx.stickyFooter,
|
|
75
|
+
ctx.setMeasuredColumnWidths,
|
|
76
|
+
children
|
|
77
|
+
]);
|
|
78
|
+
/**
|
|
79
|
+
* When columns are provided, use display:contents so the body doesn't
|
|
80
|
+
* interfere with the grid flow. Rows will use subgrid.
|
|
81
|
+
*/ const bodyClass = ctx.columns ? clsx("contents", className) : clsx("flex flex-col", className);
|
|
82
|
+
return /*#__PURE__*/ jsx(DataGridContext.Provider, {
|
|
83
|
+
value: {
|
|
84
|
+
...ctx,
|
|
85
|
+
cellWrapper: CellWrapper.BODY
|
|
86
|
+
},
|
|
87
|
+
children: /*#__PURE__*/ jsx("div", {
|
|
88
|
+
ref: bodyRef,
|
|
89
|
+
role: "rowgroup",
|
|
90
|
+
className: bodyClass,
|
|
91
|
+
...rest,
|
|
92
|
+
children: children
|
|
93
|
+
})
|
|
46
94
|
});
|
|
47
95
|
};
|
|
48
96
|
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/*!
|
|
2
|
-
@versini/ui-datagrid v0.3.
|
|
2
|
+
@versini/ui-datagrid v0.3.4
|
|
3
3
|
© 2026 gizmette.com
|
|
4
4
|
*/
|
|
5
5
|
|
|
@@ -43,10 +43,10 @@ const getCellClasses = ({ cellWrapper, className, compact, align, active, mode,
|
|
|
43
43
|
"before:bg-table-active-dark dark:before:bg-table-active-light": active && mode === "system",
|
|
44
44
|
"before:bg-table-active-light dark:before:bg-table-active-dark": active && mode === "alt-system"
|
|
45
45
|
}, /**
|
|
46
|
-
* Vertical borders. self-stretch ensures border spans
|
|
47
|
-
* layout.
|
|
46
|
+
* Vertical borders and active indicator. self-stretch ensures border spans
|
|
47
|
+
* full row height in grid layout.
|
|
48
48
|
*/ {
|
|
49
|
-
"self-stretch": borderLeft || borderRight,
|
|
49
|
+
"self-stretch": borderLeft || borderRight || active,
|
|
50
50
|
"border-l border-l-table-dark": borderLeft && mode === "dark",
|
|
51
51
|
"border-l border-l-table-light": borderLeft && mode === "light",
|
|
52
52
|
"border-l border-l-table-dark dark:border-l-table-light": borderLeft && mode === "system",
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/*!
|
|
2
|
-
@versini/ui-datagrid v0.3.
|
|
2
|
+
@versini/ui-datagrid v0.3.4
|
|
3
3
|
© 2026 gizmette.com
|
|
4
4
|
*/
|
|
5
5
|
|
|
@@ -55,7 +55,7 @@ const getRowClasses = ({ mode, className, cellWrapper })=>{
|
|
|
55
55
|
// Count the number of direct children to determine column count.
|
|
56
56
|
const columnCount = react.Children.count(children);
|
|
57
57
|
return /*#__PURE__*/ jsx(DataGridContext.Consumer, {
|
|
58
|
-
children: ({ mode, cellWrapper, stickyHeader, stickyFooter, columns })=>{
|
|
58
|
+
children: ({ mode, cellWrapper, stickyHeader, stickyFooter, columns, measuredColumnWidths })=>{
|
|
59
59
|
/**
|
|
60
60
|
* Determine if this row is inside a sticky header/footer. Sticky elements
|
|
61
61
|
* are absolutely positioned and outside the main grid flow, so they can't
|
|
@@ -68,8 +68,9 @@ const getRowClasses = ({ mode, className, cellWrapper })=>{
|
|
|
68
68
|
* sticky header/footer), use CSS subgrid to inherit the column sizing from
|
|
69
69
|
* the parent grid.
|
|
70
70
|
*
|
|
71
|
-
* For sticky headers/footers, use
|
|
72
|
-
*
|
|
71
|
+
* For sticky headers/footers, use measured pixel widths from the body if
|
|
72
|
+
* available. This syncs the header/footer columns with the body columns
|
|
73
|
+
* since absolutely positioned elements can't use subgrid.
|
|
73
74
|
*
|
|
74
75
|
* When columns are not provided, fall back to the original behavior where
|
|
75
76
|
* each row defines its own equal-width columns.
|
|
@@ -77,10 +78,21 @@ const getRowClasses = ({ mode, className, cellWrapper })=>{
|
|
|
77
78
|
*/ let rowStyle;
|
|
78
79
|
if (columns) {
|
|
79
80
|
if (isInStickyContext) {
|
|
80
|
-
// Sticky elements can't use subgrid
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
81
|
+
// Sticky elements can't use subgrid.
|
|
82
|
+
// Use measured widths from body if available for perfect alignment.
|
|
83
|
+
// Also check that widths are valid (non-zero) - in test environments
|
|
84
|
+
// or before layout, measurements may be zero.
|
|
85
|
+
const hasValidMeasurements = measuredColumnWidths && measuredColumnWidths.length === columns.length && measuredColumnWidths.some((w)=>w > 0);
|
|
86
|
+
if (hasValidMeasurements) {
|
|
87
|
+
rowStyle = {
|
|
88
|
+
gridTemplateColumns: measuredColumnWidths.map((w)=>`${w}px`).join(" ")
|
|
89
|
+
};
|
|
90
|
+
} else {
|
|
91
|
+
// Fallback to explicit template while measurements are pending.
|
|
92
|
+
rowStyle = {
|
|
93
|
+
gridTemplateColumns: columns.join(" ")
|
|
94
|
+
};
|
|
95
|
+
}
|
|
84
96
|
} else {
|
|
85
97
|
// Normal flow: use subgrid to inherit from parent grid.
|
|
86
98
|
rowStyle = {
|
package/dist/common/utilities.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@versini/ui-datagrid",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.4",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"author": "Arno Versini",
|
|
6
6
|
"publishConfig": {
|
|
@@ -94,5 +94,5 @@
|
|
|
94
94
|
"sideEffects": [
|
|
95
95
|
"**/*.css"
|
|
96
96
|
],
|
|
97
|
-
"gitHead": "
|
|
97
|
+
"gitHead": "d86931bf547783849423664618ad1e04635ef79b"
|
|
98
98
|
}
|