@versini/ui-datagrid 3.1.0 → 3.1.2

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/197.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /*!
2
- @versini/ui-datagrid v3.1.0
2
+ @versini/ui-datagrid v3.1.2
3
3
  © 2026 gizmette.com
4
4
  */
5
5
 
package/dist/430.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /*!
2
- @versini/ui-datagrid v3.1.0
2
+ @versini/ui-datagrid v3.1.2
3
3
  © 2026 gizmette.com
4
4
  */
5
5
 
package/dist/799.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /*!
2
- @versini/ui-datagrid v3.1.0
2
+ @versini/ui-datagrid v3.1.2
3
3
  © 2026 gizmette.com
4
4
  */
5
5
 
package/dist/91.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /*!
2
- @versini/ui-datagrid v3.1.0
2
+ @versini/ui-datagrid v3.1.2
3
3
  © 2026 gizmette.com
4
4
  */
5
5
 
@@ -1,2 +1,2 @@
1
1
  import type { DataGridProps } from "./DataGridTypes";
2
- export declare const DataGrid: ({ className, wrapperClassName, children, mode, compact, stickyHeader, stickyFooter, blurEffect, maxHeight, loading, columns, ...rest }: DataGridProps) => import("react/jsx-runtime").JSX.Element;
2
+ export declare const DataGrid: ({ className, wrapperClassName, children, mode, compact, stickyHeader, stickyFooter, blurEffect, maxHeight, loading, columns, ...rest }: DataGridProps) => import("react").JSX.Element;
@@ -1,5 +1,5 @@
1
1
  /*!
2
- @versini/ui-datagrid v3.1.0
2
+ @versini/ui-datagrid v3.1.2
3
3
  © 2026 gizmette.com
4
4
  */
5
5
 
@@ -48,4 +48,4 @@ export type AnimatedWrapperProps = {
48
48
  * ```
49
49
  *
50
50
  */
51
- export declare const AnimatedWrapper: ({ children, dependency, duration, enabled, className, }: AnimatedWrapperProps) => import("react/jsx-runtime").JSX.Element;
51
+ export declare const AnimatedWrapper: ({ children, dependency, duration, enabled, className, }: AnimatedWrapperProps) => import("react").JSX.Element;
@@ -1,5 +1,5 @@
1
1
  /*!
2
- @versini/ui-datagrid v3.1.0
2
+ @versini/ui-datagrid v3.1.2
3
3
  © 2026 gizmette.com
4
4
  */
5
5
 
@@ -1,2 +1,2 @@
1
1
  import type { DataGridBodyProps } from "../DataGrid/DataGridTypes";
2
- export declare const DataGridBody: ({ className, children, noData, noDataText, ...rest }: DataGridBodyProps) => import("react/jsx-runtime").JSX.Element;
2
+ export declare const DataGridBody: ({ className, children, noData, noDataText, ...rest }: DataGridBodyProps) => import("react").JSX.Element;
@@ -1,5 +1,5 @@
1
1
  /*!
2
- @versini/ui-datagrid v3.1.0
2
+ @versini/ui-datagrid v3.1.2
3
3
  © 2026 gizmette.com
4
4
  */
5
5
 
@@ -1,2 +1,2 @@
1
1
  import type { DataGridCellProps } from "../DataGrid/DataGridTypes";
2
- export declare const DataGridCell: ({ className, children, align, borderLeft, borderRight, colSpan, style, ...rest }: DataGridCellProps) => import("react/jsx-runtime").JSX.Element;
2
+ export declare const DataGridCell: ({ className, children, align, borderLeft, borderRight, colSpan, style, ...rest }: DataGridCellProps) => import("react").JSX.Element;
@@ -1,5 +1,5 @@
1
1
  /*!
2
- @versini/ui-datagrid v3.1.0
2
+ @versini/ui-datagrid v3.1.2
3
3
  © 2026 gizmette.com
4
4
  */
5
5
 
@@ -4,5 +4,5 @@ type ButtonSortProps = Pick<ButtonSortTypes.Props, "active" | "className" | "onC
4
4
  export declare const ButtonSort: ({ active, className, onClick, labelRight, children, blurEffect, mode, }: ButtonSortProps & {
5
5
  mode: ThemeMode;
6
6
  blurEffect?: BlurEffect;
7
- }) => import("react/jsx-runtime").JSX.Element;
7
+ }) => import("react").JSX.Element;
8
8
  export {};
@@ -1,2 +1,2 @@
1
1
  import type { DataGridCellSortProps } from "../DataGrid/DataGridTypes";
2
- export declare const DataGridCellSort: ({ className, children, cellId, onSort, sortDirection, sortedCell, slotLeft, slotRight, buttonClassName, align, ...rest }: DataGridCellSortProps) => import("react/jsx-runtime").JSX.Element;
2
+ export declare const DataGridCellSort: ({ className, children, cellId, onSort, sortDirection, sortedCell, slotLeft, slotRight, buttonClassName, align, ...rest }: DataGridCellSortProps) => import("react").JSX.Element;
@@ -1,5 +1,5 @@
1
1
  /*!
2
- @versini/ui-datagrid v3.1.0
2
+ @versini/ui-datagrid v3.1.2
3
3
  © 2026 gizmette.com
4
4
  */
5
5
 
@@ -1,5 +1,5 @@
1
1
  /*!
2
- @versini/ui-datagrid v3.1.0
2
+ @versini/ui-datagrid v3.1.2
3
3
  © 2026 gizmette.com
4
4
  */
5
5
 
@@ -1,5 +1,5 @@
1
1
  import type { DataGridFooterProps } from "../DataGrid/DataGridTypes";
2
2
  export declare const DataGridFooter: {
3
- ({ className, children, ...rest }: DataGridFooterProps): import("react/jsx-runtime").JSX.Element;
3
+ ({ className, children, ...rest }: DataGridFooterProps): import("react").JSX.Element;
4
4
  displayName: string;
5
5
  };
@@ -1,10 +1,10 @@
1
1
  /*!
2
- @versini/ui-datagrid v3.1.0
2
+ @versini/ui-datagrid v3.1.2
3
3
  © 2026 gizmette.com
4
4
  */
5
5
 
6
6
  import { jsx } from "react/jsx-runtime";
7
- import { useEffect, useLayoutEffect, useRef } from "react";
7
+ import { useLayoutEffect, useRef } from "react";
8
8
  import { DataGridContext } from "../430.js";
9
9
  import { CellWrapper } from "../799.js";
10
10
  import { getFooterClasses } from "../91.js";
@@ -37,7 +37,14 @@ DataGridFooter.displayName = "DataGridFooter";
37
37
  /**
38
38
  * Register this footer with the parent DataGrid on mount. This enables sticky
39
39
  * footer behavior regardless of nesting depth.
40
- */ useEffect(()=>{
40
+ *
41
+ * useLayoutEffect (not useEffect) so registration — and therefore
42
+ * effectiveStickyFooter — happens BEFORE the first paint. React flushes the
43
+ * resulting parent state update synchronously before paint, so the grid's
44
+ * first paint is already the sticky layout. With a passive effect the first
45
+ * paint would be the non-sticky layout and flip one frame later, producing a
46
+ * visible reposition on load.
47
+ */ useLayoutEffect(()=>{
41
48
  ctx.registerFooter?.();
42
49
  return ()=>{
43
50
  ctx.unregisterFooter?.();
@@ -54,10 +61,23 @@ DataGridFooter.displayName = "DataGridFooter";
54
61
  if (!element || !ctx.stickyFooter || !ctx.setFooterHeight) {
55
62
  return;
56
63
  }
64
+ /**
65
+ * Initial synchronous measurement so the scrollable content's
66
+ * paddingBottom is correct on the FIRST paint. React flushes this state
67
+ * update before paint, so there is no one-frame layout shift (the same
68
+ * approach useColumnMeasurement uses for column widths). The
69
+ * ResizeObserver below still handles later dynamic changes.
70
+ *
71
+ * Both paths round to integer px. getBoundingClientRect().height (here)
72
+ * and the observer's borderBoxSize.blockSize (below) can report slightly
73
+ * different sub-pixel values for the same box; rounding keeps them in
74
+ * agreement so the observer's first callback doesn't overwrite this value
75
+ * with a fractional one and trigger a second shift.
76
+ */ ctx.setFooterHeight(Math.round(element.getBoundingClientRect().height));
57
77
  const observer = new ResizeObserver((entries)=>{
58
78
  const height = entries[0]?.borderBoxSize?.[0]?.blockSize;
59
79
  if (height !== undefined) {
60
- ctx.setFooterHeight?.(height);
80
+ ctx.setFooterHeight?.(Math.round(height));
61
81
  }
62
82
  });
63
83
  observer.observe(element);
@@ -1,5 +1,5 @@
1
1
  import type { DataGridHeaderProps } from "../DataGrid/DataGridTypes";
2
2
  export declare const DataGridHeader: {
3
- ({ caption, captionClassName, className, children, ...rest }: DataGridHeaderProps): import("react/jsx-runtime").JSX.Element;
3
+ ({ caption, captionClassName, className, children, ...rest }: DataGridHeaderProps): import("react").JSX.Element;
4
4
  displayName: string;
5
5
  };
@@ -1,5 +1,5 @@
1
1
  /*!
2
- @versini/ui-datagrid v3.1.0
2
+ @versini/ui-datagrid v3.1.2
3
3
  © 2026 gizmette.com
4
4
  */
5
5
 
@@ -41,7 +41,14 @@ DataGridHeader.displayName = "DataGridHeader";
41
41
  /**
42
42
  * Register this header with the parent DataGrid on mount. This enables sticky
43
43
  * header behavior regardless of nesting depth.
44
- */ useEffect(()=>{
44
+ *
45
+ * useLayoutEffect (not useEffect) so registration — and therefore
46
+ * effectiveStickyHeader — happens BEFORE the first paint. React flushes the
47
+ * resulting parent state update synchronously before paint, so the grid's
48
+ * first paint is already the sticky layout. With a passive effect the first
49
+ * paint would be the non-sticky layout and flip one frame later, producing a
50
+ * visible reposition on load.
51
+ */ useLayoutEffect(()=>{
45
52
  ctx.registerHeader?.();
46
53
  return ()=>{
47
54
  ctx.unregisterHeader?.();
@@ -73,10 +80,25 @@ DataGridHeader.displayName = "DataGridHeader";
73
80
  if (!element || !ctx.stickyHeader || !ctx.setHeaderHeight) {
74
81
  return;
75
82
  }
83
+ /**
84
+ * Initial synchronous measurement so the scrollable content's paddingTop
85
+ * is correct on the FIRST paint. React flushes this state update before
86
+ * paint, so there is no one-frame layout shift (the same approach
87
+ * useColumnMeasurement uses for column widths). The ResizeObserver below
88
+ * still handles later dynamic changes (text wrap, font load, etc.).
89
+ *
90
+ * Both paths round to integer px. getBoundingClientRect().height (here)
91
+ * and the observer's borderBoxSize.blockSize (below) can report slightly
92
+ * different sub-pixel values for the same box; rounding keeps them in
93
+ * agreement so the observer's first callback doesn't overwrite this value
94
+ * with a fractional one and trigger a second shift. Integer rounding is
95
+ * coarser than useColumnMeasurement's device-pixel snapping (1 / DPR), but
96
+ * it is enough here: padding only needs to be stable, not pixel-perfect.
97
+ */ ctx.setHeaderHeight(Math.round(element.getBoundingClientRect().height));
76
98
  const observer = new ResizeObserver((entries)=>{
77
99
  const height = entries[0]?.borderBoxSize?.[0]?.blockSize;
78
100
  if (height !== undefined) {
79
- ctx.setHeaderHeight?.(height);
101
+ ctx.setHeaderHeight?.(Math.round(height));
80
102
  }
81
103
  });
82
104
  observer.observe(element);
@@ -117,4 +117,4 @@ export type DataGridInfiniteBodyRef = {
117
117
  */
118
118
  export declare function DataGridInfiniteBody<T>({ data, children: renderRow, batchSize, threshold, rootMargin, onVisibleCountChange, className, noData, noDataText, ref, }: DataGridInfiniteBodyProps<T> & {
119
119
  ref?: React.Ref<DataGridInfiniteBodyRef>;
120
- }): import("react/jsx-runtime").JSX.Element;
120
+ }): import("react").JSX.Element;
@@ -1,5 +1,5 @@
1
1
  /*!
2
- @versini/ui-datagrid v3.1.0
2
+ @versini/ui-datagrid v3.1.2
3
3
  © 2026 gizmette.com
4
4
  */
5
5
 
@@ -1,2 +1,3 @@
1
+ import React from "react";
1
2
  import type { DataGridRowProps } from "../DataGrid/DataGridTypes";
2
- export declare const DataGridRow: ({ className, children, active, style: userStyle, ...rest }: DataGridRowProps) => import("react/jsx-runtime").JSX.Element;
3
+ export declare const DataGridRow: ({ className, children, active, style: userStyle, ...rest }: DataGridRowProps) => React.JSX.Element;
@@ -1,5 +1,5 @@
1
1
  /*!
2
- @versini/ui-datagrid v3.1.0
2
+ @versini/ui-datagrid v3.1.2
3
3
  © 2026 gizmette.com
4
4
  */
5
5
 
@@ -1,5 +1,5 @@
1
1
  /*!
2
- @versini/ui-datagrid v3.1.0
2
+ @versini/ui-datagrid v3.1.2
3
3
  © 2026 gizmette.com
4
4
  */
5
5
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@versini/ui-datagrid",
3
- "version": "3.1.0",
3
+ "version": "3.1.2",
4
4
  "license": "MIT",
5
5
  "author": "Arno Versini",
6
6
  "publishConfig": {
@@ -87,16 +87,16 @@
87
87
  },
88
88
  "devDependencies": {
89
89
  "@testing-library/jest-dom": "6.9.1",
90
- "@versini/ui-button": "15.0.4",
90
+ "@versini/ui-button": "15.0.5",
91
91
  "@versini/ui-types": "10.0.0"
92
92
  },
93
93
  "dependencies": {
94
- "@versini/ui-icons": "4.28.0",
94
+ "@versini/ui-icons": "4.29.0",
95
95
  "clsx": "2.1.1",
96
- "tailwindcss": "4.3.0"
96
+ "tailwindcss": "4.3.1"
97
97
  },
98
98
  "sideEffects": [
99
99
  "**/*.css"
100
100
  ],
101
- "gitHead": "8ae610468c121bc5ed1438573a4d2ab7068c053d"
101
+ "gitHead": "f25e4b557175f745705c249d10e2e77dc02ed462"
102
102
  }