@versini/ui-datagrid 4.2.12 → 4.2.13

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.
@@ -1,5 +1,5 @@
1
1
  /*!
2
- @versini/ui-datagrid v4.2.12
2
+ @versini/ui-datagrid v4.2.13
3
3
  © 2026 gizmette.com
4
4
  */
5
5
 
@@ -9,56 +9,29 @@ import clsx from "clsx";
9
9
  import { BlurEffects } from "../7.js";
10
10
  import { getCellClasses, getTextColorClassesForHeaderFooter } from "../y.js";
11
11
  import { DataGridContext } from "../8.js";
12
-
13
-
14
-
15
-
16
-
17
-
18
-
19
-
20
-
21
-
22
12
  const getActiveIndicatorClasses = (active)=>{
23
- if (!active) {
24
- return "";
25
- }
26
- return clsx("relative", /**
27
- * Gated on :focus-visible, not :focus-within: the underline is hidden to make
28
- * room for the focus ring, and the ring itself is keyboard-only. On
29
- * :focus-within the underline would also vanish on a mouse click, with no
30
- * ring taking its place.
31
- */ "has-[:focus-visible]:static", "has-[:focus-visible]:after:border-transparent", "after:absolute", "after:content-['']", "after:border-b-2", "after:-bottom-1", "after:left-0", "after:right-0", // the small border at the bottom of the button when it is active (sorted).
32
- "after:border-table-light");
13
+ if (!active) return "";
14
+ return clsx("relative", "has-[:focus-visible]:static", "has-[:focus-visible]:after:border-transparent", "after:absolute", "after:content-['']", "after:border-b-2", "after:-bottom-1", "after:left-0", "after:right-0", "after:border-table-light");
33
15
  };
34
16
  const ButtonSort = ({ active = false, className, onClick, labelRight, children, blurEffect, mode })=>{
35
17
  const hasBlur = Boolean(blurEffect && blurEffect !== BlurEffects.NONE);
36
- const buttonClasses = clsx(// Base styles.
37
- "flex items-center cursor-pointer", // Size - small.
38
- "h-6 px-1 sm:px-2", // Font.
39
- "text-sm font-bold", // Radius - small.
40
- "rounded-xs", // Text color.
41
- getTextColorClassesForHeaderFooter({
18
+ const buttonClasses = clsx("flex items-center cursor-pointer", "h-6 px-1 sm:px-2", "text-sm font-bold", "rounded-xs", getTextColorClassesForHeaderFooter({
42
19
  mode,
43
20
  hasBlur
44
- }), // Focus styles.
45
- "focus-visible:outline", "focus-visible:outline-2", "focus-visible:outline-offset-2", "focus-visible:outline-focus-medium", // Hover styles.
46
- "hover:text-copy-light-hover", "hover:bg-action-darker-hover", // Active styles.
47
- "active:text-copy-medium-active", "active:bg-action-dark-active", // Custom className.
48
- className);
21
+ }), "focus-visible:outline", "focus-visible:outline-2", "focus-visible:outline-offset-2", "focus-visible:outline-focus-medium", "hover:text-copy-light-hover", "hover:bg-action-darker-hover", "active:text-copy-medium-active", "active:bg-action-dark-active", className);
49
22
  const wrapperClasses = getActiveIndicatorClasses(active);
50
- return /*#__PURE__*/ jsx("div", {
23
+ return jsx("div", {
51
24
  className: wrapperClasses,
52
- children: /*#__PURE__*/ jsxs("button", {
25
+ children: jsxs("button", {
53
26
  className: buttonClasses,
54
27
  type: "button",
55
28
  onClick: onClick,
56
29
  children: [
57
- /*#__PURE__*/ jsx("span", {
30
+ jsx("span", {
58
31
  className: "text-copy-light",
59
32
  children: children
60
33
  }),
61
- labelRight && /*#__PURE__*/ jsx("span", {
34
+ labelRight && jsx("span", {
62
35
  className: "pl-2",
63
36
  children: labelRight
64
37
  })
@@ -66,52 +39,34 @@ const ButtonSort = ({ active = false, className, onClick, labelRight, children,
66
39
  })
67
40
  });
68
41
  };
69
-
70
-
71
-
72
-
73
-
74
-
75
-
76
- /* =============================================================================
77
- * DataGridCellSort
78
- * ========================================================================== */ const DataGridCellSort = ({ className, children, cellId, onSort, sortDirection, sortedCell, slotLeft, slotRight, buttonClassName, align, ...rest })=>{
42
+ const DataGridCellSort = ({ className, children, cellId, onSort, sortDirection, sortedCell, slotLeft, slotRight, buttonClassName, align, ...rest })=>{
79
43
  const isSorted = sortedCell === cellId;
80
44
  const handleSort = ()=>{
81
45
  if (onSort) {
82
- // Convert false to undefined for the callback.
83
- const currentDirection = isSorted && sortDirection ? sortDirection : undefined;
46
+ const currentDirection = isSorted && sortDirection ? sortDirection : void 0;
84
47
  onSort(cellId, currentDirection);
85
48
  }
86
49
  };
87
50
  const getSortIcon = ()=>{
88
- if (isSorted && sortDirection === "asc") {
89
- return /*#__PURE__*/ jsx(IconSortUp, {
90
- size: "size-4",
91
- monotone: true
92
- });
93
- }
94
- if (isSorted && sortDirection === "desc") {
95
- return /*#__PURE__*/ jsx(IconSortDown, {
96
- size: "size-4",
97
- monotone: true
98
- });
99
- }
100
- return /*#__PURE__*/ jsx(IconSort, {
51
+ if (isSorted && "asc" === sortDirection) return jsx(IconSortUp, {
52
+ size: "size-4",
53
+ monotone: true
54
+ });
55
+ if (isSorted && "desc" === sortDirection) return jsx(IconSortDown, {
56
+ size: "size-4",
57
+ monotone: true
58
+ });
59
+ return jsx(IconSort, {
101
60
  size: "size-4",
102
61
  monotone: true
103
62
  });
104
63
  };
105
64
  const getAriaSort = ()=>{
106
- if (isSorted && sortDirection === "asc") {
107
- return "ascending";
108
- }
109
- if (isSorted && sortDirection === "desc") {
110
- return "descending";
111
- }
65
+ if (isSorted && "asc" === sortDirection) return "ascending";
66
+ if (isSorted && "desc" === sortDirection) return "descending";
112
67
  return "other";
113
68
  };
114
- return /*#__PURE__*/ jsx(DataGridContext.Consumer, {
69
+ return jsx(DataGridContext.Consumer, {
115
70
  children: ({ mode, compact, cellWrapper, blurEffect })=>{
116
71
  const mainClasses = getCellClasses({
117
72
  cellWrapper,
@@ -120,22 +75,21 @@ const ButtonSort = ({ active = false, className, onClick, labelRight, children,
120
75
  compact,
121
76
  align
122
77
  });
123
- // Flex container for alignment of button within the cell.
124
78
  const contentClasses = clsx("flex", {
125
- "justify-start": align === "left" || !align,
126
- "justify-center": align === "center",
127
- "justify-end": align === "right"
79
+ "justify-start": "left" === align || !align,
80
+ "justify-center": "center" === align,
81
+ "justify-end": "right" === align
128
82
  });
129
- return /*#__PURE__*/ jsx("div", {
83
+ return jsx("div", {
130
84
  className: mainClasses,
131
85
  role: "columnheader",
132
86
  "aria-sort": getAriaSort(),
133
87
  ...rest,
134
- children: /*#__PURE__*/ jsxs("div", {
88
+ children: jsxs("div", {
135
89
  className: contentClasses,
136
90
  children: [
137
91
  slotLeft,
138
- /*#__PURE__*/ jsx(ButtonSort, {
92
+ jsx(ButtonSort, {
139
93
  mode: mode,
140
94
  blurEffect: blurEffect,
141
95
  active: isSorted,
@@ -151,7 +105,4 @@ const ButtonSort = ({ active = false, className, onClick, labelRight, children,
151
105
  }
152
106
  });
153
107
  };
154
-
155
-
156
-
157
108
  export { DataGridCellSort };
@@ -1,9 +1,6 @@
1
1
  /*!
2
- @versini/ui-datagrid v4.2.12
2
+ @versini/ui-datagrid v4.2.13
3
3
  © 2026 gizmette.com
4
4
  */
5
5
 
6
-
7
-
8
-
9
6
  export { BlurEffects, CellWrapper, SortDirections, ThemeModes } from "../7.js";
@@ -1,5 +1,5 @@
1
1
  /*!
2
- @versini/ui-datagrid v4.2.12
2
+ @versini/ui-datagrid v4.2.13
3
3
  © 2026 gizmette.com
4
4
  */
5
5
 
@@ -8,43 +8,18 @@ import { useLayoutEffect, useRef } from "react";
8
8
  import { DataGridContext } from "../8.js";
9
9
  import { CellWrapper } from "../7.js";
10
10
  import { getFooterClasses } from "../y.js";
11
-
12
-
13
-
14
-
15
-
16
-
17
-
18
-
19
- /* =============================================================================
20
- * DataGridFooter
21
- * ========================================================================== */ const DataGridFooter = ({ className, children, ...rest })=>{
22
- return /*#__PURE__*/ jsx(DataGridContext.Consumer, {
23
- children: (ctx)=>/*#__PURE__*/ jsx(DataGridFooterInner, {
11
+ const DataGridFooter = ({ className, children, ...rest })=>jsx(DataGridContext.Consumer, {
12
+ children: (ctx)=>jsx(DataGridFooterInner, {
24
13
  className: className,
25
14
  ctx: ctx,
26
15
  ...rest,
27
16
  children: children
28
17
  })
29
18
  });
30
- };
31
19
  DataGridFooter.displayName = "DataGridFooter";
32
- /**
33
- * Inner component to handle the useEffect for registering footer. Separated to
34
- * avoid hooks inside Consumer render prop.
35
- */ const DataGridFooterInner = ({ className, ctx, children, ...rest })=>{
20
+ const DataGridFooterInner = ({ className, ctx, children, ...rest })=>{
36
21
  const footerRef = useRef(null);
37
- /**
38
- * Register this footer with the parent DataGrid on mount. This enables sticky
39
- * footer behavior regardless of nesting depth.
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(()=>{
22
+ useLayoutEffect(()=>{
48
23
  ctx.registerFooter?.();
49
24
  return ()=>{
50
25
  ctx.unregisterFooter?.();
@@ -53,32 +28,13 @@ DataGridFooter.displayName = "DataGridFooter";
53
28
  ctx.registerFooter,
54
29
  ctx.unregisterFooter
55
30
  ]);
56
- /**
57
- * Measure and report footer height for dynamic padding calculation. Uses
58
- * ResizeObserver to handle dynamic content changes.
59
- */ useLayoutEffect(()=>{
31
+ useLayoutEffect(()=>{
60
32
  const element = footerRef.current;
61
- if (!element || !ctx.stickyFooter || !ctx.setFooterHeight) {
62
- return;
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));
33
+ if (!element || !ctx.stickyFooter || !ctx.setFooterHeight) return;
34
+ ctx.setFooterHeight(Math.round(element.getBoundingClientRect().height));
77
35
  const observer = new ResizeObserver((entries)=>{
78
36
  const height = entries[0]?.borderBoxSize?.[0]?.blockSize;
79
- if (height !== undefined) {
80
- ctx.setFooterHeight?.(Math.round(height));
81
- }
37
+ if (void 0 !== height) ctx.setFooterHeight?.(Math.round(height));
82
38
  });
83
39
  observer.observe(element);
84
40
  return ()=>observer.disconnect();
@@ -86,14 +42,13 @@ DataGridFooter.displayName = "DataGridFooter";
86
42
  ctx.stickyFooter,
87
43
  ctx.setFooterHeight
88
44
  ]);
89
- return /*#__PURE__*/ jsx(DataGridContext.Provider, {
45
+ return jsx(DataGridContext.Provider, {
90
46
  value: {
91
47
  ...ctx,
92
48
  cellWrapper: CellWrapper.FOOTER,
93
- // Footer is the last row (= total rowCount) when virtualized.
94
- ariaRowIndex: ctx.rowCount != null ? ctx.rowCount : undefined
49
+ ariaRowIndex: null != ctx.rowCount ? ctx.rowCount : void 0
95
50
  },
96
- children: /*#__PURE__*/ jsx("div", {
51
+ children: jsx("div", {
97
52
  ref: footerRef,
98
53
  role: "rowgroup",
99
54
  className: getFooterClasses({
@@ -107,7 +62,4 @@ DataGridFooter.displayName = "DataGridFooter";
107
62
  })
108
63
  });
109
64
  };
110
-
111
-
112
-
113
65
  export { DataGridFooter };
@@ -1,5 +1,5 @@
1
1
  /*!
2
- @versini/ui-datagrid v4.2.12
2
+ @versini/ui-datagrid v4.2.13
3
3
  © 2026 gizmette.com
4
4
  */
5
5
 
@@ -8,20 +8,10 @@ import { useEffect, useId, useLayoutEffect, useRef } from "react";
8
8
  import { DataGridContext } from "../8.js";
9
9
  import { CellWrapper } from "../7.js";
10
10
  import { getCaptionClasses, getHeaderClasses } from "../y.js";
11
-
12
-
13
-
14
-
15
-
16
-
17
-
18
-
19
- /* =============================================================================
20
- * DataGridHeader
21
- * ========================================================================== */ const DataGridHeader = ({ caption, captionClassName, className, children, ...rest })=>{
11
+ const DataGridHeader = ({ caption, captionClassName, className, children, ...rest })=>{
22
12
  const captionId = useId();
23
- return /*#__PURE__*/ jsx(DataGridContext.Consumer, {
24
- children: (ctx)=>/*#__PURE__*/ jsx(DataGridHeaderInner, {
13
+ return jsx(DataGridContext.Consumer, {
14
+ children: (ctx)=>jsx(DataGridHeaderInner, {
25
15
  caption: caption,
26
16
  captionClassName: captionClassName,
27
17
  captionId: captionId,
@@ -33,22 +23,9 @@ import { getCaptionClasses, getHeaderClasses } from "../y.js";
33
23
  });
34
24
  };
35
25
  DataGridHeader.displayName = "DataGridHeader";
36
- /**
37
- * Inner component to handle the useEffect for registering captionId and header.
38
- * Separated to avoid hooks inside Consumer render prop.
39
- */ const DataGridHeaderInner = ({ caption, captionClassName, captionId, className, ctx, children, ...rest })=>{
26
+ const DataGridHeaderInner = ({ caption, captionClassName, captionId, className, ctx, children, ...rest })=>{
40
27
  const headerRef = useRef(null);
41
- /**
42
- * Register this header with the parent DataGrid on mount. This enables sticky
43
- * header behavior regardless of nesting depth.
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(()=>{
28
+ useLayoutEffect(()=>{
52
29
  ctx.registerHeader?.();
53
30
  return ()=>{
54
31
  ctx.unregisterHeader?.();
@@ -57,49 +34,23 @@ DataGridHeader.displayName = "DataGridHeader";
57
34
  ctx.registerHeader,
58
35
  ctx.unregisterHeader
59
36
  ]);
60
- // Register the caption ID with the parent DataGrid for aria-labelledby.
61
37
  useEffect(()=>{
62
- if (caption && ctx.setCaptionId) {
63
- ctx.setCaptionId(captionId);
64
- }
38
+ if (caption && ctx.setCaptionId) ctx.setCaptionId(captionId);
65
39
  return ()=>{
66
- if (ctx.setCaptionId) {
67
- ctx.setCaptionId(undefined);
68
- }
40
+ if (ctx.setCaptionId) ctx.setCaptionId(void 0);
69
41
  };
70
42
  }, [
71
43
  caption,
72
44
  captionId,
73
45
  ctx.setCaptionId
74
46
  ]);
75
- /**
76
- * Measure and report header height for dynamic padding calculation. Uses
77
- * ResizeObserver to handle dynamic content changes (text wrapping, etc.).
78
- */ useLayoutEffect(()=>{
47
+ useLayoutEffect(()=>{
79
48
  const element = headerRef.current;
80
- if (!element || !ctx.stickyHeader || !ctx.setHeaderHeight) {
81
- return;
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));
49
+ if (!element || !ctx.stickyHeader || !ctx.setHeaderHeight) return;
50
+ ctx.setHeaderHeight(Math.round(element.getBoundingClientRect().height));
98
51
  const observer = new ResizeObserver((entries)=>{
99
52
  const height = entries[0]?.borderBoxSize?.[0]?.blockSize;
100
- if (height !== undefined) {
101
- ctx.setHeaderHeight?.(Math.round(height));
102
- }
53
+ if (void 0 !== height) ctx.setHeaderHeight?.(Math.round(height));
103
54
  });
104
55
  observer.observe(element);
105
56
  return ()=>observer.disconnect();
@@ -107,14 +58,13 @@ DataGridHeader.displayName = "DataGridHeader";
107
58
  ctx.stickyHeader,
108
59
  ctx.setHeaderHeight
109
60
  ]);
110
- return /*#__PURE__*/ jsx(DataGridContext.Provider, {
61
+ return jsx(DataGridContext.Provider, {
111
62
  value: {
112
63
  ...ctx,
113
64
  cellWrapper: CellWrapper.HEADER,
114
- // Header is row 1 when the grid is virtualized (rowCount set).
115
- ariaRowIndex: ctx.rowCount != null ? 1 : undefined
65
+ ariaRowIndex: null != ctx.rowCount ? 1 : void 0
116
66
  },
117
- children: /*#__PURE__*/ jsxs("div", {
67
+ children: jsxs("div", {
118
68
  ref: headerRef,
119
69
  role: "rowgroup",
120
70
  className: getHeaderClasses({
@@ -125,12 +75,12 @@ DataGridHeader.displayName = "DataGridHeader";
125
75
  }),
126
76
  ...rest,
127
77
  children: [
128
- caption && /*#__PURE__*/ jsx("div", {
78
+ caption && jsx("div", {
129
79
  id: captionId,
130
80
  className: getCaptionClasses({
131
81
  captionClassName,
132
82
  mode: ctx.mode,
133
- hasBlur: Boolean(ctx.blurEffect && ctx.blurEffect !== "none"),
83
+ hasBlur: Boolean(ctx.blurEffect && "none" !== ctx.blurEffect),
134
84
  stickyHeader: Boolean(ctx.stickyHeader)
135
85
  }),
136
86
  children: caption
@@ -140,7 +90,4 @@ DataGridHeader.displayName = "DataGridHeader";
140
90
  })
141
91
  });
142
92
  };
143
-
144
-
145
-
146
93
  export { DataGridHeader };