@versini/ui-datagrid 0.1.0 → 0.2.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.
Files changed (43) hide show
  1. package/README.md +3 -43
  2. package/dist/DataGrid/DataGrid.d.ts +1 -1
  3. package/dist/DataGrid/DataGrid.js +41 -36
  4. package/dist/DataGrid/DataGridContext.js +1 -1
  5. package/dist/DataGrid/index.js +1 -1
  6. package/dist/DataGrid/utilities.d.ts +19 -3
  7. package/dist/DataGrid/utilities.js +38 -12
  8. package/dist/DataGridAnimated/AnimatedWrapper.js +1 -1
  9. package/dist/DataGridAnimated/index.js +1 -1
  10. package/dist/DataGridAnimated/useAnimatedHeight.js +1 -1
  11. package/dist/DataGridBody/DataGridBody.js +16 -5
  12. package/dist/DataGridBody/index.js +1 -1
  13. package/dist/DataGridCell/DataGridCell.d.ts +2 -5
  14. package/dist/DataGridCell/DataGridCell.js +27 -18
  15. package/dist/DataGridCell/index.js +1 -1
  16. package/dist/DataGridCellSort/DataGridCellSort.d.ts +1 -1
  17. package/dist/DataGridCellSort/DataGridCellSort.js +16 -11
  18. package/dist/DataGridCellSort/index.js +1 -1
  19. package/dist/DataGridConstants/DataGridConstants.js +1 -1
  20. package/dist/DataGridConstants/index.js +1 -1
  21. package/dist/DataGridFooter/DataGridFooter.d.ts +5 -1
  22. package/dist/DataGridFooter/DataGridFooter.js +17 -6
  23. package/dist/DataGridFooter/index.js +1 -1
  24. package/dist/DataGridHeader/DataGridHeader.d.ts +6 -1
  25. package/dist/DataGridHeader/DataGridHeader.js +32 -28
  26. package/dist/DataGridHeader/index.js +1 -1
  27. package/dist/DataGridInfinite/InfiniteScrollMarker.d.ts +2 -6
  28. package/dist/DataGridInfinite/InfiniteScrollMarker.js +7 -6
  29. package/dist/DataGridInfinite/index.js +1 -1
  30. package/dist/DataGridInfinite/useInfiniteScroll.d.ts +12 -1
  31. package/dist/DataGridInfinite/useInfiniteScroll.js +23 -4
  32. package/dist/DataGridRow/DataGridRow.d.ts +1 -1
  33. package/dist/DataGridRow/DataGridRow.js +61 -9
  34. package/dist/DataGridRow/index.js +1 -1
  35. package/dist/DataGridSorting/index.js +1 -1
  36. package/dist/DataGridSorting/sortingUtils.js +1 -1
  37. package/package.json +2 -7
  38. package/dist/DataGridVirtual/VirtualDataGrid.d.ts +0 -114
  39. package/dist/DataGridVirtual/VirtualDataGrid.js +0 -181
  40. package/dist/DataGridVirtual/index.d.ts +0 -6
  41. package/dist/DataGridVirtual/index.js +0 -22
  42. package/dist/DataGridVirtual/useVirtualDataGrid.d.ts +0 -112
  43. package/dist/DataGridVirtual/useVirtualDataGrid.js +0 -89
package/README.md CHANGED
@@ -1,8 +1,9 @@
1
1
  # @versini/ui-datagrid
2
2
 
3
- A high-performance data grid component library for React with support for:
3
+ A data grid component library for React built with div-based ARIA grid layout for maximum flexibility and accessibility. Features include:
4
4
 
5
- - **Virtualization**: Efficiently render thousands of rows using TanStack Virtual
5
+ - **Accessible**: Uses ARIA grid roles for screen reader support
6
+ - **Flexible Layout**: Div-based structure allows for complex styling
6
7
  - **Infinite Scrolling**: Progressive loading with IntersectionObserver
7
8
  - **Animated Height**: Smooth height transitions when content changes
8
9
  - **Sorting**: Built-in sorting utilities and sortable column headers
@@ -39,12 +40,6 @@ import {
39
40
  InfiniteScrollMarker
40
41
  } from "@versini/ui-datagrid/infinite";
41
42
 
42
- // True virtualization for large datasets
43
- import {
44
- VirtualDataGrid,
45
- useVirtualDataGrid
46
- } from "@versini/ui-datagrid/virtual";
47
-
48
43
  // Animated height wrapper
49
44
  import {
50
45
  AnimatedWrapper,
@@ -152,31 +147,6 @@ function MyInfiniteTable({ data }) {
152
147
  }
153
148
  ```
154
149
 
155
- ## Virtualization for Large Datasets
156
-
157
- For datasets with 1000+ rows, use true virtualization:
158
-
159
- ```tsx
160
- import { VirtualDataGrid } from "@versini/ui-datagrid/virtual";
161
-
162
- function MyVirtualTable({ data }) {
163
- return (
164
- <VirtualDataGrid
165
- data={data}
166
- height="500px"
167
- columns={[
168
- { id: "name", header: "Name", cell: (item) => item.name },
169
- { id: "email", header: "Email", cell: (item) => item.email },
170
- { id: "date", header: "Date", cell: (item) => formatDate(item.date) }
171
- ]}
172
- getRowKey={(item) => item.id}
173
- estimateSize={48}
174
- overscan={10}
175
- />
176
- );
177
- }
178
- ```
179
-
180
150
  ## Sorting
181
151
 
182
152
  ```tsx
@@ -279,16 +249,6 @@ function MySortableTable({ data }) {
279
249
  | `threshold` | `number` | `5` | Items before end to trigger load |
280
250
  | `rootMargin` | `string` | `'20px'` | IntersectionObserver margin |
281
251
 
282
- ### VirtualDataGrid
283
-
284
- | Prop | Type | Default | Description |
285
- | -------------- | ---------------------------- | ------------ | ------------------------------- |
286
- | `data` | `T[]` | **required** | Array of data items |
287
- | `columns` | `VirtualDataGridColumn<T>[]` | **required** | Column definitions |
288
- | `height` | `string \| number` | **required** | Container height |
289
- | `estimateSize` | `number` | `40` | Estimated row height |
290
- | `overscan` | `number` | `5` | Rows to render outside viewport |
291
-
292
252
  ## License
293
253
 
294
254
  MIT
@@ -1,2 +1,2 @@
1
1
  import type { DataGridProps } from "./DataGridTypes";
2
- export declare const DataGrid: ({ caption, className, wrapperClassName, children, mode, compact, stickyHeader, stickyFooter, blurEffect, maxHeight, disabled, ...rest }: DataGridProps) => import("react/jsx-runtime").JSX.Element;
2
+ export declare const DataGrid: ({ caption, className, wrapperClassName, children, mode, compact, stickyHeader, stickyFooter, blurEffect, maxHeight, disabled, columns, ...rest }: DataGridProps) => import("react/jsx-runtime").JSX.Element;
@@ -1,5 +1,5 @@
1
1
  /*!
2
- @versini/ui-datagrid v0.1.0
2
+ @versini/ui-datagrid v0.2.0
3
3
  © 2026 gizmette.com
4
4
  */
5
5
 
@@ -27,7 +27,7 @@ import { getDataGridClasses } from "./utilities.js";
27
27
 
28
28
  /* =============================================================================
29
29
  * DataGrid (main component)
30
- * ========================================================================== */ const DataGrid = ({ caption, className, wrapperClassName, children, mode = "system", compact = false, stickyHeader = false, stickyFooter = false, blurEffect = BlurEffects.NONE, maxHeight, disabled = false, ...rest })=>{
30
+ * ========================================================================== */ const DataGrid = ({ caption, className, wrapperClassName, children, mode = "system", compact = false, stickyHeader = false, stickyFooter = false, blurEffect = BlurEffects.NONE, maxHeight, disabled = false, columns, ...rest })=>{
31
31
  const captionId = useId();
32
32
  const classes = useMemo(()=>getDataGridClasses({
33
33
  mode,
@@ -35,14 +35,18 @@ import { getDataGridClasses } from "./utilities.js";
35
35
  wrapperClassName,
36
36
  stickyHeader,
37
37
  stickyFooter,
38
- disabled
38
+ disabled,
39
+ hasCaption: Boolean(caption),
40
+ hasColumns: Boolean(columns)
39
41
  }), [
40
42
  mode,
41
43
  className,
42
44
  wrapperClassName,
43
45
  stickyHeader,
44
46
  stickyFooter,
45
- disabled
47
+ disabled,
48
+ caption,
49
+ columns
46
50
  ]);
47
51
  const contextValue = useMemo(()=>({
48
52
  mode,
@@ -50,14 +54,18 @@ import { getDataGridClasses } from "./utilities.js";
50
54
  stickyHeader,
51
55
  stickyFooter,
52
56
  blurEffect,
53
- disabled
57
+ disabled,
58
+ hasCaption: Boolean(caption),
59
+ columns
54
60
  }), [
55
61
  mode,
56
62
  compact,
57
63
  stickyHeader,
58
64
  stickyFooter,
59
65
  blurEffect,
60
- disabled
66
+ disabled,
67
+ caption,
68
+ columns
61
69
  ]);
62
70
  const wrapperStyle = maxHeight ? {
63
71
  maxHeight: typeof maxHeight === "number" ? `${maxHeight}px` : maxHeight
@@ -67,6 +75,20 @@ import { getDataGridClasses } from "./utilities.js";
67
75
  * wrapper has overflow-hidden - Scrollable content area in the middle with
68
76
  * padding - Header/footer are absolutely positioned.
69
77
  */ const hasSticky = stickyHeader || stickyFooter;
78
+ /**
79
+ * When columns are provided, apply grid-template-columns at the grid level
80
+ * so all rows can use subgrid to inherit the same column sizing.
81
+ */ const gridStyle = columns ? {
82
+ gridTemplateColumns: columns.join(" ")
83
+ } : undefined;
84
+ const gridContent = /*#__PURE__*/ jsx("div", {
85
+ role: "grid",
86
+ className: classes.grid,
87
+ "aria-labelledby": caption ? captionId : undefined,
88
+ style: gridStyle,
89
+ ...rest,
90
+ children: children
91
+ });
70
92
  return /*#__PURE__*/ jsx(DataGridContext.Provider, {
71
93
  value: contextValue,
72
94
  children: /*#__PURE__*/ jsxs("div", {
@@ -91,38 +113,21 @@ import { getDataGridClasses } from "./utilities.js";
91
113
  })
92
114
  ]
93
115
  }),
94
- /*#__PURE__*/ jsx("div", {
116
+ /*#__PURE__*/ jsxs("div", {
95
117
  className: classes.wrapper,
96
118
  style: wrapperStyle,
97
- children: hasSticky ? /*#__PURE__*/ jsx("div", {
98
- className: classes.scrollableContent,
99
- style: wrapperStyle,
100
- children: /*#__PURE__*/ jsxs("table", {
101
- className: classes.table,
102
- "aria-describedby": caption ? captionId : undefined,
103
- ...rest,
104
- children: [
105
- caption && /*#__PURE__*/ jsx("caption", {
106
- id: captionId,
107
- className: classes.caption,
108
- children: caption
109
- }),
110
- children
111
- ]
112
- })
113
- }) : /*#__PURE__*/ jsxs("table", {
114
- className: classes.table,
115
- "aria-describedby": caption ? captionId : undefined,
116
- ...rest,
117
- children: [
118
- caption && /*#__PURE__*/ jsx("caption", {
119
- id: captionId,
120
- className: classes.caption,
121
- children: caption
122
- }),
123
- children
124
- ]
125
- })
119
+ children: [
120
+ caption && /*#__PURE__*/ jsx("div", {
121
+ id: captionId,
122
+ className: classes.caption,
123
+ children: caption
124
+ }),
125
+ hasSticky ? /*#__PURE__*/ jsx("div", {
126
+ className: classes.scrollableContent,
127
+ style: wrapperStyle,
128
+ children: gridContent
129
+ }) : gridContent
130
+ ]
126
131
  })
127
132
  ]
128
133
  })
@@ -1,5 +1,5 @@
1
1
  /*!
2
- @versini/ui-datagrid v0.1.0
2
+ @versini/ui-datagrid v0.2.0
3
3
  © 2026 gizmette.com
4
4
  */
5
5
 
@@ -1,5 +1,5 @@
1
1
  /*!
2
- @versini/ui-datagrid v0.1.0
2
+ @versini/ui-datagrid v0.2.0
3
3
  © 2026 gizmette.com
4
4
  */
5
5
 
@@ -5,17 +5,28 @@ import { type BlurEffect, type ThemeMode } from "../DataGridConstants/DataGridCo
5
5
  export declare const getStickyBlurClasses: ({ blurEffect, }: {
6
6
  blurEffect?: BlurEffect;
7
7
  }) => string;
8
+ export declare const getCaptionBackgroundClasses: ({ mode }: {
9
+ mode: ThemeMode;
10
+ }) => string;
11
+ export declare const getCaptionCopyClasses: ({ mode }: {
12
+ mode: ThemeMode;
13
+ }) => string;
8
14
  /**
9
- * Generates classes for the main DataGrid wrapper and table. When sticky
15
+ * Generates classes for the main DataGrid wrapper and grid. When sticky
10
16
  * header/footer is enabled, uses the Panel-like approach:
11
17
  * - Outer wrapper has overflow-hidden
12
18
  * - Scrollable area is a separate inner container
13
19
  * - Header/footer are absolutely positioned overlays
20
+ *
21
+ * When columns prop is provided, the grid uses CSS Grid layout with subgrid
22
+ * support for proper column alignment across all rows.
14
23
  */
15
- export declare const getDataGridClasses: ({ mode, className, wrapperClassName, stickyHeader, stickyFooter, disabled, }: {
24
+ export declare const getDataGridClasses: ({ mode, className, wrapperClassName, stickyHeader, stickyFooter, disabled, hasCaption, hasColumns, }: {
16
25
  mode: ThemeMode;
17
26
  className?: string;
18
27
  disabled?: boolean;
28
+ hasCaption?: boolean;
29
+ hasColumns?: boolean;
19
30
  stickyFooter?: boolean;
20
31
  stickyHeader?: boolean;
21
32
  wrapperClassName?: string;
@@ -29,8 +40,13 @@ export declare const getDataGridClasses: ({ mode, className, wrapperClassName, s
29
40
  * Scrollable content area - like Panel's scrollableContent Has padding to
30
41
  * make room for absolutely positioned header/footer rounded-[inherit] clips
31
42
  * the scrollbar at the rounded corners.
43
+ * When there's a caption, add extra padding for caption (~36px) + header (~40px).
32
44
  */
33
45
  scrollableContent: string;
34
- table: string;
46
+ /**
47
+ * When columns are provided, use CSS Grid so rows can use subgrid for
48
+ * consistent column alignment. Otherwise, use flexbox.
49
+ */
50
+ grid: string;
35
51
  caption: string;
36
52
  };
@@ -1,5 +1,5 @@
1
1
  /*!
2
- @versini/ui-datagrid v0.1.0
2
+ @versini/ui-datagrid v0.2.0
3
3
  © 2026 gizmette.com
4
4
  */
5
5
 
@@ -44,13 +44,32 @@ import { BlurEffects } from "../DataGridConstants/DataGridConstants.js";
44
44
  "backdrop-blur-lg": blurEffect === BlurEffects.LARGE
45
45
  });
46
46
  };
47
+ const getCaptionBackgroundClasses = ({ mode })=>{
48
+ return clsx({
49
+ "bg-surface-darker": mode === "dark" || mode === "system",
50
+ "bg-surface-light": mode === "light" || mode === "alt-system",
51
+ "dark:bg-surface-light": mode === "system",
52
+ "dark:bg-surface-darker": mode === "alt-system"
53
+ });
54
+ };
55
+ const getCaptionCopyClasses = ({ mode })=>{
56
+ return clsx({
57
+ "text-copy-light": mode === "dark",
58
+ "text-copy-dark": mode === "light",
59
+ "text-copy-light dark:text-copy-dark": mode === "system",
60
+ "text-copy-dark dark:text-copy-light": mode === "alt-system"
61
+ });
62
+ };
47
63
  /**
48
- * Generates classes for the main DataGrid wrapper and table. When sticky
64
+ * Generates classes for the main DataGrid wrapper and grid. When sticky
49
65
  * header/footer is enabled, uses the Panel-like approach:
50
66
  * - Outer wrapper has overflow-hidden
51
67
  * - Scrollable area is a separate inner container
52
68
  * - Header/footer are absolutely positioned overlays
53
- */ const getDataGridClasses = ({ mode, className, wrapperClassName, stickyHeader, stickyFooter, disabled })=>{
69
+ *
70
+ * When columns prop is provided, the grid uses CSS Grid layout with subgrid
71
+ * support for proper column alignment across all rows.
72
+ */ const getDataGridClasses = ({ mode, className, wrapperClassName, stickyHeader, stickyFooter, disabled, hasCaption, hasColumns })=>{
54
73
  const overlayClasses = disabled ? getOverlayClasses({
55
74
  mode
56
75
  }) : null;
@@ -77,23 +96,30 @@ import { BlurEffects } from "../DataGridConstants/DataGridConstants.js";
77
96
  * Scrollable content area - like Panel's scrollableContent Has padding to
78
97
  * make room for absolutely positioned header/footer rounded-[inherit] clips
79
98
  * the scrollbar at the rounded corners.
99
+ * When there's a caption, add extra padding for caption (~36px) + header (~40px).
80
100
  */ scrollableContent: clsx("overflow-y-auto overflow-x-hidden rounded-[inherit]", {
81
- "pt-10": stickyHeader,
101
+ "pt-10": stickyHeader && !hasCaption,
102
+ "pt-19": stickyHeader && hasCaption,
82
103
  "pb-10": stickyFooter
83
104
  }),
84
- table: clsx("my-0 w-full text-left text-sm", className, {
105
+ /**
106
+ * When columns are provided, use CSS Grid so rows can use subgrid for
107
+ * consistent column alignment. Otherwise, use flexbox.
108
+ */ grid: clsx("my-0 w-full text-left text-sm", hasColumns ? "grid" : "flex flex-col", className, {
85
109
  "text-copy-light": mode === "dark",
86
110
  "text-copy-dark": mode === "light",
87
111
  "text-copy-light dark:text-copy-dark": mode === "system",
88
112
  "text-copy-dark dark:text-copy-light": mode === "alt-system"
89
113
  }),
90
- caption: clsx("py-2 text-sm font-bold", {
91
- "text-copy-light": mode === "dark",
92
- "text-copy-dark": mode === "light",
93
- "text-copy-light dark:text-copy-dark": mode === "system",
94
- "text-copy-dark dark:text-copy-light": mode === "alt-system"
95
- })
114
+ caption: clsx("py-2 text-sm text-center font-bold", {
115
+ // When stickyHeader is enabled, caption is absolutely positioned at top
116
+ "absolute left-0 right-0 z-20 top-0 rounded-t-lg": stickyHeader
117
+ }, getCaptionBackgroundClasses({
118
+ mode
119
+ }), getCaptionCopyClasses({
120
+ mode
121
+ }))
96
122
  };
97
123
  };
98
124
 
99
- export { getDataGridClasses, getStickyBlurClasses };
125
+ export { getCaptionBackgroundClasses, getCaptionCopyClasses, getDataGridClasses, getStickyBlurClasses };
@@ -1,5 +1,5 @@
1
1
  /*!
2
- @versini/ui-datagrid v0.1.0
2
+ @versini/ui-datagrid v0.2.0
3
3
  © 2026 gizmette.com
4
4
  */
5
5
 
@@ -1,5 +1,5 @@
1
1
  /*!
2
- @versini/ui-datagrid v0.1.0
2
+ @versini/ui-datagrid v0.2.0
3
3
  © 2026 gizmette.com
4
4
  */
5
5
 
@@ -1,5 +1,5 @@
1
1
  /*!
2
- @versini/ui-datagrid v0.1.0
2
+ @versini/ui-datagrid v0.2.0
3
3
  © 2026 gizmette.com
4
4
  */
5
5
 
@@ -1,14 +1,17 @@
1
1
  /*!
2
- @versini/ui-datagrid v0.1.0
2
+ @versini/ui-datagrid v0.2.0
3
3
  © 2026 gizmette.com
4
4
  */
5
5
 
6
6
  import { jsx } from "react/jsx-runtime";
7
+ import clsx from "clsx";
7
8
  import { DataGridContext } from "../DataGrid/DataGridContext.js";
8
9
  import { CellWrapper } from "../DataGridConstants/index.js";
9
10
 
10
11
  ;// CONCATENATED MODULE: external "react/jsx-runtime"
11
12
 
13
+ ;// CONCATENATED MODULE: external "clsx"
14
+
12
15
  ;// CONCATENATED MODULE: external "../DataGrid/DataGridContext.js"
13
16
 
14
17
  ;// CONCATENATED MODULE: external "../DataGridConstants/index.js"
@@ -17,21 +20,29 @@ import { CellWrapper } from "../DataGridConstants/index.js";
17
20
 
18
21
 
19
22
 
23
+
20
24
  /* =============================================================================
21
25
  * DataGridBody
22
26
  * ========================================================================== */ const DataGridBody = ({ className, children, ...rest })=>{
23
27
  return /*#__PURE__*/ jsx(DataGridContext.Consumer, {
24
- children: (ctx)=>/*#__PURE__*/ jsx(DataGridContext.Provider, {
28
+ children: (ctx)=>{
29
+ /**
30
+ * When columns are provided, use display:contents so the body
31
+ * doesn't interfere with the grid flow. Rows will use subgrid.
32
+ */ const bodyClass = ctx.columns ? clsx("contents", className) : clsx("flex flex-col", className);
33
+ return /*#__PURE__*/ jsx(DataGridContext.Provider, {
25
34
  value: {
26
35
  ...ctx,
27
36
  cellWrapper: CellWrapper.BODY
28
37
  },
29
- children: /*#__PURE__*/ jsx("tbody", {
30
- className: className,
38
+ children: /*#__PURE__*/ jsx("div", {
39
+ role: "rowgroup",
40
+ className: bodyClass,
31
41
  ...rest,
32
42
  children: children
33
43
  })
34
- })
44
+ });
45
+ }
35
46
  });
36
47
  };
37
48
 
@@ -1,5 +1,5 @@
1
1
  /*!
2
- @versini/ui-datagrid v0.1.0
2
+ @versini/ui-datagrid v0.2.0
3
3
  © 2026 gizmette.com
4
4
  */
5
5
 
@@ -7,8 +7,5 @@ export declare const getCellClasses: ({ cellWrapper, className, compact, align,
7
7
  compact?: boolean;
8
8
  align?: "left" | "center" | "right";
9
9
  active?: boolean;
10
- }) => {
11
- mainClasses: string;
12
- alignClasses: string;
13
- };
14
- export declare const DataGridCell: ({ className, children, align, active, component, ...rest }: DataGridCellProps) => import("react/jsx-runtime").JSX.Element;
10
+ }) => string;
11
+ export declare const DataGridCell: ({ className, children, align, active, colSpan, style, ...rest }: DataGridCellProps) => import("react/jsx-runtime").JSX.Element;
@@ -1,5 +1,5 @@
1
1
  /*!
2
- @versini/ui-datagrid v0.1.0
2
+ @versini/ui-datagrid v0.2.0
3
3
  © 2026 gizmette.com
4
4
  */
5
5
 
@@ -27,6 +27,11 @@ const getCellClasses = ({ cellWrapper, className, compact, align, active, mode }
27
27
  {
28
28
  "px-2 py-1": compact,
29
29
  "px-4 py-3": !compact
30
+ }, // Text alignment.
31
+ {
32
+ "text-left": align === "left" || !align,
33
+ "text-center": align === "center",
34
+ "text-right": align === "right"
30
35
  }, // Header/footer specific styles.
31
36
  {
32
37
  "font-semibold": isHeader
@@ -38,22 +43,22 @@ const getCellClasses = ({ cellWrapper, className, compact, align, active, mode }
38
43
  "before:bg-table-active-dark dark:before:bg-table-active-light": active && mode === "system",
39
44
  "before:bg-table-active-light dark:before:bg-table-active-dark": active && mode === "alt-system"
40
45
  }, className);
41
- const alignClasses = clsx("flex", {
42
- "justify-start": align === "left" || !align,
43
- "justify-center": align === "center",
44
- "justify-end": align === "right"
45
- });
46
- return {
47
- mainClasses,
48
- alignClasses
49
- };
46
+ return mainClasses;
47
+ };
48
+ /**
49
+ * Returns the appropriate ARIA role for the cell based on the cell wrapper type.
50
+ */ const getCellRole = (cellWrapper)=>{
51
+ if (cellWrapper === CellWrapper.HEADER) {
52
+ return "columnheader";
53
+ }
54
+ return "gridcell";
50
55
  };
51
56
  /* =============================================================================
52
57
  * DataGridCell
53
- * ========================================================================== */ const DataGridCell = ({ className, children, align, active, component, ...rest })=>{
58
+ * ========================================================================== */ const DataGridCell = ({ className, children, align, active, colSpan, style, ...rest })=>{
54
59
  return /*#__PURE__*/ jsx(DataGridContext.Consumer, {
55
60
  children: ({ mode, compact, cellWrapper })=>{
56
- const { mainClasses, alignClasses } = getCellClasses({
61
+ const mainClasses = getCellClasses({
57
62
  cellWrapper,
58
63
  className,
59
64
  mode,
@@ -61,14 +66,18 @@ const getCellClasses = ({ cellWrapper, className, compact, align, active, mode }
61
66
  align,
62
67
  active
63
68
  });
64
- const Component = component || (cellWrapper === CellWrapper.HEADER || cellWrapper === CellWrapper.FOOTER ? "th" : "td");
65
- return /*#__PURE__*/ jsx(Component, {
69
+ const role = getCellRole(cellWrapper);
70
+ // Apply grid-column span for colSpan > 1
71
+ const cellStyle = colSpan && colSpan > 1 ? {
72
+ ...style,
73
+ gridColumn: `span ${colSpan}`
74
+ } : style;
75
+ return /*#__PURE__*/ jsx("div", {
76
+ role: role,
66
77
  className: mainClasses,
78
+ style: cellStyle,
67
79
  ...rest,
68
- children: /*#__PURE__*/ jsx("div", {
69
- className: alignClasses,
70
- children: children
71
- })
80
+ children: children
72
81
  });
73
82
  }
74
83
  });
@@ -1,5 +1,5 @@
1
1
  /*!
2
- @versini/ui-datagrid v0.1.0
2
+ @versini/ui-datagrid v0.2.0
3
3
  © 2026 gizmette.com
4
4
  */
5
5
 
@@ -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, focusMode, ...rest }: DataGridCellSortProps) => import("react/jsx-runtime").JSX.Element;
2
+ export declare const DataGridCellSort: ({ className, children, cellId, onSort, sortDirection, sortedCell, slotLeft, slotRight, buttonClassName, focusMode, align, ...rest }: DataGridCellSortProps) => import("react/jsx-runtime").JSX.Element;
@@ -1,14 +1,14 @@
1
1
  /*!
2
- @versini/ui-datagrid v0.1.0
2
+ @versini/ui-datagrid v0.2.0
3
3
  © 2026 gizmette.com
4
4
  */
5
5
 
6
6
  import { jsx, jsxs } from "react/jsx-runtime";
7
7
  import { ButtonSort_private } from "@versini/ui-button/private";
8
8
  import { IconSort, IconSortDown, IconSortUp } from "@versini/ui-icons";
9
+ import clsx from "clsx";
9
10
  import { DataGridContext } from "../DataGrid/DataGridContext.js";
10
11
  import { getCellClasses } from "../DataGridCell/DataGridCell.js";
11
- import { CellWrapper } from "../DataGridConstants/index.js";
12
12
 
13
13
  ;// CONCATENATED MODULE: external "react/jsx-runtime"
14
14
 
@@ -16,12 +16,12 @@ import { CellWrapper } from "../DataGridConstants/index.js";
16
16
 
17
17
  ;// CONCATENATED MODULE: external "@versini/ui-icons"
18
18
 
19
+ ;// CONCATENATED MODULE: external "clsx"
20
+
19
21
  ;// CONCATENATED MODULE: external "../DataGrid/DataGridContext.js"
20
22
 
21
23
  ;// CONCATENATED MODULE: external "../DataGridCell/DataGridCell.js"
22
24
 
23
- ;// CONCATENATED MODULE: external "../DataGridConstants/index.js"
24
-
25
25
  ;// CONCATENATED MODULE: ./src/DataGridCellSort/DataGridCellSort.tsx
26
26
 
27
27
 
@@ -31,7 +31,7 @@ import { CellWrapper } from "../DataGridConstants/index.js";
31
31
 
32
32
  /* =============================================================================
33
33
  * DataGridCellSort
34
- * ========================================================================== */ const DataGridCellSort = ({ className, children, cellId, onSort, sortDirection, sortedCell, slotLeft, slotRight, buttonClassName, focusMode = "alt-system", ...rest })=>{
34
+ * ========================================================================== */ const DataGridCellSort = ({ className, children, cellId, onSort, sortDirection, sortedCell, slotLeft, slotRight, buttonClassName, focusMode = "alt-system", align, ...rest })=>{
35
35
  const isSorted = sortedCell === cellId;
36
36
  const handleSort = ()=>{
37
37
  if (onSort) {
@@ -69,20 +69,26 @@ import { CellWrapper } from "../DataGridConstants/index.js";
69
69
  };
70
70
  return /*#__PURE__*/ jsx(DataGridContext.Consumer, {
71
71
  children: ({ mode, compact, cellWrapper })=>{
72
- const { mainClasses, alignClasses } = getCellClasses({
72
+ const mainClasses = getCellClasses({
73
73
  cellWrapper,
74
74
  className,
75
75
  mode,
76
- compact
76
+ compact,
77
+ align
78
+ });
79
+ // Flex container for alignment of button within the cell
80
+ const contentClasses = clsx("flex", {
81
+ "justify-start": align === "left" || !align,
82
+ "justify-center": align === "center",
83
+ "justify-end": align === "right"
77
84
  });
78
- const Component = cellWrapper === CellWrapper.HEADER || cellWrapper === CellWrapper.FOOTER ? "th" : "td";
79
- return /*#__PURE__*/ jsx(Component, {
85
+ return /*#__PURE__*/ jsx("div", {
80
86
  className: mainClasses,
81
87
  role: "columnheader",
82
88
  "aria-sort": getAriaSort(),
83
89
  ...rest,
84
90
  children: /*#__PURE__*/ jsxs("div", {
85
- className: alignClasses,
91
+ className: contentClasses,
86
92
  children: [
87
93
  slotLeft,
88
94
  /*#__PURE__*/ jsx(ButtonSort_private, {
@@ -92,7 +98,6 @@ import { CellWrapper } from "../DataGridConstants/index.js";
92
98
  noBorder: true,
93
99
  focusMode: focusMode,
94
100
  mode: mode,
95
- fullWidth: true,
96
101
  labelRight: children,
97
102
  children: getSortIcon()
98
103
  }),
@@ -1,5 +1,5 @@
1
1
  /*!
2
- @versini/ui-datagrid v0.1.0
2
+ @versini/ui-datagrid v0.2.0
3
3
  © 2026 gizmette.com
4
4
  */
5
5
 
@@ -1,5 +1,5 @@
1
1
  /*!
2
- @versini/ui-datagrid v0.1.0
2
+ @versini/ui-datagrid v0.2.0
3
3
  © 2026 gizmette.com
4
4
  */
5
5
 
@@ -1,5 +1,5 @@
1
1
  /*!
2
- @versini/ui-datagrid v0.1.0
2
+ @versini/ui-datagrid v0.2.0
3
3
  © 2026 gizmette.com
4
4
  */
5
5