@jmruthers/pace-core 0.2.5 → 0.2.7

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 (167) hide show
  1. package/dist/{DataTable-BHlzyKZP.d.ts → DataTable-C1AEm9Cx.d.ts} +1 -1
  2. package/dist/{DataTable-GEY5U7OI.js → DataTable-EEUDXPE5.js} +2 -8
  3. package/dist/{api-T6CBS7IO.js → api-ETQ6YJ3C.js} +2 -3
  4. package/dist/{chunk-DY5E3AT7.js → chunk-BEZRLNK3.js} +13 -3
  5. package/dist/chunk-BEZRLNK3.js.map +1 -0
  6. package/dist/{chunk-ANE4PDC2.js → chunk-C5G2A4PO.js} +159 -6
  7. package/dist/chunk-C5G2A4PO.js.map +1 -0
  8. package/dist/{chunk-WYB6MBZA.js → chunk-EWKPTNPO.js} +579 -973
  9. package/dist/chunk-EWKPTNPO.js.map +1 -0
  10. package/dist/{chunk-TMRLB2LA.js → chunk-HEMJ4SUJ.js} +2 -2
  11. package/dist/{chunk-O4T53L7X.js → chunk-HNDFPXUU.js} +5 -5
  12. package/dist/{chunk-UY7AM4QG.js → chunk-RRUYHORU.js} +161 -74
  13. package/dist/chunk-RRUYHORU.js.map +1 -0
  14. package/dist/{chunk-PFRRIDYA.js → chunk-TIVL4UQ7.js} +2 -2
  15. package/dist/{chunk-2MKP6IYD.js → chunk-VYG4AXYW.js} +2 -2
  16. package/dist/components.d.ts +2 -2
  17. package/dist/components.js +15 -16
  18. package/dist/components.js.map +1 -1
  19. package/dist/hooks.d.ts +1 -1
  20. package/dist/hooks.js +4 -4
  21. package/dist/index.d.ts +2 -2
  22. package/dist/index.js +16 -17
  23. package/dist/index.js.map +1 -1
  24. package/dist/providers.js +2 -2
  25. package/dist/rbac/index.js +25 -20
  26. package/dist/rbac/index.js.map +1 -1
  27. package/dist/styles/core.css +83 -62
  28. package/dist/{types-CInEi-ng.d.ts → types-DiRQsGJs.d.ts} +0 -2
  29. package/dist/utils.d.ts +2 -2
  30. package/dist/utils.js +1 -1
  31. package/docs/api/classes/ErrorBoundary.md +1 -1
  32. package/docs/api/classes/PublicErrorBoundary.md +1 -1
  33. package/docs/api/interfaces/AggregateConfig.md +1 -1
  34. package/docs/api/interfaces/ButtonProps.md +1 -1
  35. package/docs/api/interfaces/CardProps.md +1 -1
  36. package/docs/api/interfaces/ColorPalette.md +1 -1
  37. package/docs/api/interfaces/ColorShade.md +1 -1
  38. package/docs/api/interfaces/DataTableAction.md +1 -1
  39. package/docs/api/interfaces/DataTableColumn.md +1 -1
  40. package/docs/api/interfaces/DataTableProps.md +33 -33
  41. package/docs/api/interfaces/DataTableToolbarButton.md +1 -1
  42. package/docs/api/interfaces/EmptyStateConfig.md +1 -1
  43. package/docs/api/interfaces/EventContextType.md +1 -1
  44. package/docs/api/interfaces/EventLogoProps.md +1 -1
  45. package/docs/api/interfaces/EventProviderProps.md +1 -1
  46. package/docs/api/interfaces/FileSizeLimits.md +1 -1
  47. package/docs/api/interfaces/FileUploadProps.md +1 -1
  48. package/docs/api/interfaces/FooterProps.md +1 -1
  49. package/docs/api/interfaces/InactivityWarningModalProps.md +1 -1
  50. package/docs/api/interfaces/InputProps.md +1 -1
  51. package/docs/api/interfaces/LabelProps.md +1 -1
  52. package/docs/api/interfaces/LoginFormProps.md +1 -1
  53. package/docs/api/interfaces/NavigationItem.md +1 -1
  54. package/docs/api/interfaces/NavigationMenuProps.md +1 -1
  55. package/docs/api/interfaces/Organisation.md +1 -1
  56. package/docs/api/interfaces/OrganisationContextType.md +1 -1
  57. package/docs/api/interfaces/OrganisationMembership.md +1 -1
  58. package/docs/api/interfaces/OrganisationProviderProps.md +1 -1
  59. package/docs/api/interfaces/OrganisationSecurityError.md +1 -1
  60. package/docs/api/interfaces/PaceAppLayoutProps.md +1 -1
  61. package/docs/api/interfaces/PaceLoginPageProps.md +1 -1
  62. package/docs/api/interfaces/PaletteData.md +1 -1
  63. package/docs/api/interfaces/PublicErrorBoundaryProps.md +1 -1
  64. package/docs/api/interfaces/PublicErrorBoundaryState.md +1 -1
  65. package/docs/api/interfaces/PublicLoadingSpinnerProps.md +1 -1
  66. package/docs/api/interfaces/PublicPageFooterProps.md +1 -1
  67. package/docs/api/interfaces/PublicPageHeaderProps.md +1 -1
  68. package/docs/api/interfaces/PublicPageLayoutProps.md +1 -1
  69. package/docs/api/interfaces/StorageConfig.md +1 -1
  70. package/docs/api/interfaces/StorageFileInfo.md +1 -1
  71. package/docs/api/interfaces/StorageFileMetadata.md +1 -1
  72. package/docs/api/interfaces/StorageListOptions.md +1 -1
  73. package/docs/api/interfaces/StorageListResult.md +1 -1
  74. package/docs/api/interfaces/StorageUploadOptions.md +1 -1
  75. package/docs/api/interfaces/StorageUploadResult.md +1 -1
  76. package/docs/api/interfaces/StorageUrlOptions.md +1 -1
  77. package/docs/api/interfaces/StyleImport.md +1 -1
  78. package/docs/api/interfaces/ToastActionElement.md +1 -1
  79. package/docs/api/interfaces/ToastProps.md +1 -1
  80. package/docs/api/interfaces/UnifiedAuthContextType.md +1 -1
  81. package/docs/api/interfaces/UnifiedAuthProviderProps.md +1 -1
  82. package/docs/api/interfaces/UseInactivityTrackerOptions.md +1 -1
  83. package/docs/api/interfaces/UseInactivityTrackerReturn.md +1 -1
  84. package/docs/api/interfaces/UsePublicEventLogoOptions.md +1 -1
  85. package/docs/api/interfaces/UsePublicEventLogoReturn.md +1 -1
  86. package/docs/api/interfaces/UsePublicEventOptions.md +1 -1
  87. package/docs/api/interfaces/UsePublicEventReturn.md +1 -1
  88. package/docs/api/interfaces/UsePublicRouteParamsReturn.md +1 -1
  89. package/docs/api/interfaces/UserEventAccess.md +1 -1
  90. package/docs/api/interfaces/UserMenuProps.md +1 -1
  91. package/docs/api/interfaces/UserProfile.md +1 -1
  92. package/docs/api/modules.md +10 -10
  93. package/docs/architecture/README.md +1 -1
  94. package/package.json +1 -1
  95. package/src/__tests__/shared/testUtils.optimized.tsx +65 -7
  96. package/src/components/DataTable/DataTable.tsx +1 -3
  97. package/src/components/DataTable/__tests__/DataTable.errorHandling.test.tsx +0 -8
  98. package/src/components/DataTable/__tests__/DataTable.hierarchical.test.tsx +17 -12
  99. package/src/components/DataTable/__tests__/DataTable.infinite-loop.test.tsx +0 -1
  100. package/src/components/DataTable/__tests__/DataTable.integration.test.tsx +4 -12
  101. package/src/components/DataTable/__tests__/DataTable.performance.test.tsx +0 -8
  102. package/src/components/DataTable/__tests__/DataTable.permissions.test.tsx +21 -11
  103. package/src/components/DataTable/__tests__/DataTable.sorting.test.tsx +321 -0
  104. package/src/components/DataTable/__tests__/DataTable.userWorkflows.test.tsx +21 -11
  105. package/src/components/DataTable/__tests__/DataTable.workflowValidation.test.tsx +94 -0
  106. package/src/components/DataTable/__tests__/DataTable.workflows.test.tsx +25 -15
  107. package/src/components/DataTable/__tests__/README.md +11 -2
  108. package/src/components/DataTable/__tests__/performance-regression.test.tsx +0 -11
  109. package/src/components/DataTable/__tests__/test-utils/sharedTestUtils.tsx +0 -1
  110. package/src/components/DataTable/components/ColumnVisibilityDropdown.tsx +2 -2
  111. package/src/components/DataTable/components/DataTableBody.tsx +34 -35
  112. package/src/components/DataTable/components/DataTableCore.tsx +205 -133
  113. package/src/components/DataTable/components/DataTableToolbar.tsx +9 -10
  114. package/src/components/DataTable/components/DraggableColumnHeader.tsx +3 -7
  115. package/src/components/DataTable/components/EditableRow.tsx +6 -7
  116. package/src/components/DataTable/components/FilterRow.tsx +0 -1
  117. package/src/components/DataTable/components/GroupingDropdown.tsx +2 -2
  118. package/src/components/DataTable/components/UnifiedTableBody.tsx +83 -281
  119. package/src/components/DataTable/components/VirtualizedDataTable.tsx +9 -89
  120. package/src/components/DataTable/components/__tests__/DataTable.accessibility.test.tsx +111 -5
  121. package/src/components/DataTable/components/__tests__/DataTable.integration.test.tsx +82 -13
  122. package/src/components/DataTable/components/__tests__/DataTable.performance.test.tsx +0 -1
  123. package/src/components/DataTable/components/__tests__/DataTable.real.test.tsx +2 -2
  124. package/src/components/DataTable/components/__tests__/DataTable.security.test.tsx +0 -1
  125. package/src/components/DataTable/components/__tests__/DataTable.unit.test.tsx +2 -2
  126. package/src/components/DataTable/components/__tests__/FilteringToggle.unit.test.tsx +3 -0
  127. package/src/components/DataTable/components/index.ts +0 -1
  128. package/src/components/DataTable/core/DataTableContext.tsx +0 -1
  129. package/src/components/DataTable/index.ts +0 -2
  130. package/src/components/DataTable/types.ts +0 -2
  131. package/src/components/Input/Input.tsx +2 -2
  132. package/src/components/Input/__tests__/Input.unit.test.tsx +4 -4
  133. package/src/components/PaceAppLayout/__tests__/PaceAppLayout.integration.test.tsx +6 -2
  134. package/src/components/RBAC/PagePermissionGuard.tsx +13 -0
  135. package/src/components/RBAC/__tests__/PagePermissionGuard.unit.test.tsx +10 -1
  136. package/src/components/Select/Select.tsx +7 -1
  137. package/src/components/__tests__/EdgeCaseTesting.enhanced.test.tsx +2 -1
  138. package/src/hooks/__tests__/useRBAC.unit.test.ts +32 -24
  139. package/src/providers/RBACProvider.tsx +14 -2
  140. package/src/providers/__tests__/UnifiedAuthProvider.unit.test.tsx +11 -3
  141. package/src/rbac/__tests__/cache-invalidation.test.ts +2 -2
  142. package/src/rbac/__tests__/cache.test.ts +3 -3
  143. package/src/rbac/hooks.ts +15 -7
  144. package/src/styles/core.css +83 -62
  145. package/src/utils/__tests__/lazyLoad.unit.test.tsx +13 -18
  146. package/src/utils/storage/__tests__/helpers.unit.test.ts +9 -7
  147. package/dist/cache-I72HKDOA.js +0 -12
  148. package/dist/cache-I72HKDOA.js.map +0 -1
  149. package/dist/chunk-ANE4PDC2.js.map +0 -1
  150. package/dist/chunk-DY5E3AT7.js.map +0 -1
  151. package/dist/chunk-MRRFJ6SA.js +0 -161
  152. package/dist/chunk-MRRFJ6SA.js.map +0 -1
  153. package/dist/chunk-UY7AM4QG.js.map +0 -1
  154. package/dist/chunk-WYB6MBZA.js.map +0 -1
  155. package/src/components/DataTable/__tests__/DataTable.autoSizing.test.tsx +0 -526
  156. package/src/components/DataTable/components/DataTableHeader.tsx +0 -31
  157. package/src/components/DataTable/components/__tests__/DataTableHeader.unit.test.tsx +0 -143
  158. package/src/components/DataTable/examples/AutoSizingExample.tsx +0 -180
  159. package/src/components/DataTable/examples/ColumnSizingComparison.tsx +0 -235
  160. package/src/components/DataTable/utils/__tests__/columnSizing.test.ts +0 -237
  161. package/src/components/DataTable/utils/columnSizing.ts +0 -125
  162. /package/dist/{DataTable-GEY5U7OI.js.map → DataTable-EEUDXPE5.js.map} +0 -0
  163. /package/dist/{api-T6CBS7IO.js.map → api-ETQ6YJ3C.js.map} +0 -0
  164. /package/dist/{chunk-TMRLB2LA.js.map → chunk-HEMJ4SUJ.js.map} +0 -0
  165. /package/dist/{chunk-O4T53L7X.js.map → chunk-HNDFPXUU.js.map} +0 -0
  166. /package/dist/{chunk-PFRRIDYA.js.map → chunk-TIVL4UQ7.js.map} +0 -0
  167. /package/dist/{chunk-2MKP6IYD.js.map → chunk-VYG4AXYW.js.map} +0 -0
@@ -39,19 +39,37 @@ vi.mock('@tanstack/react-table', () => ({
39
39
  {
40
40
  id: 'name',
41
41
  isPlaceholder: false,
42
- column: { columnDef: { header: 'Name' } },
42
+ column: {
43
+ columnDef: { header: 'Name' },
44
+ getCanSort: () => true,
45
+ getToggleSortingHandler: () => vi.fn(),
46
+ getIsSorted: () => false,
47
+ getIsVisible: () => true,
48
+ },
43
49
  getContext: () => ({}),
44
50
  },
45
51
  {
46
52
  id: 'email',
47
53
  isPlaceholder: false,
48
- column: { columnDef: { header: 'Email' } },
54
+ column: {
55
+ columnDef: { header: 'Email' },
56
+ getCanSort: () => true,
57
+ getToggleSortingHandler: () => vi.fn(),
58
+ getIsSorted: () => false,
59
+ getIsVisible: () => true,
60
+ },
49
61
  getContext: () => ({}),
50
62
  },
51
63
  {
52
64
  id: 'role',
53
65
  isPlaceholder: false,
54
- column: { columnDef: { header: 'Role' } },
66
+ column: {
67
+ columnDef: { header: 'Role' },
68
+ getCanSort: () => true,
69
+ getToggleSortingHandler: () => vi.fn(),
70
+ getIsSorted: () => false,
71
+ getIsVisible: () => true,
72
+ },
55
73
  getContext: () => ({}),
56
74
  },
57
75
  ],
@@ -167,14 +185,6 @@ vi.mock('../core/DataTableContext', () => ({
167
185
  }));
168
186
 
169
187
  // Mock individual components
170
- vi.mock('../components/DataTableHeader', () => ({
171
- DataTableHeader: ({ title, description }: any) => (
172
- <div data-testid="data-table-header">
173
- {title && <h2 data-testid="table-title">{title}</h2>}
174
- {description && <p data-testid="table-description">{description}</p>}
175
- </div>
176
- ),
177
- }));
178
188
 
179
189
  vi.mock('../components/DataTableToolbar', () => ({
180
190
  DataTableToolbar: () => <div data-testid="data-table-toolbar">Toolbar</div>,
@@ -255,8 +265,8 @@ describe('DataTable Workflows Tests', () => {
255
265
  </MockRBACProvider>
256
266
  );
257
267
 
258
- expect(screen.getByTestId('table-title')).toHaveTextContent('Users Table');
259
- expect(screen.getByTestId('table-description')).toHaveTextContent('Manage user accounts');
268
+ expect(screen.getByText('Users Table')).toBeInTheDocument();
269
+ expect(screen.getByText('Manage user accounts')).toBeInTheDocument();
260
270
  });
261
271
 
262
272
  it('renders with actions when provided', () => {
@@ -650,8 +660,8 @@ describe('DataTable Workflows Tests', () => {
650
660
  );
651
661
 
652
662
  expect(screen.getByRole('table')).toBeInTheDocument();
653
- expect(screen.getByTestId('table-title')).toHaveTextContent('Comprehensive Workflow Test');
654
- expect(screen.getByTestId('table-description')).toHaveTextContent('Testing complete user workflows');
663
+ expect(screen.getByText('Comprehensive Workflow Test')).toBeInTheDocument();
664
+ expect(screen.getByText('Testing complete user workflows')).toBeInTheDocument();
655
665
  });
656
666
 
657
667
  it('handles workflow with different data types', () => {
@@ -8,7 +8,7 @@ This directory contains comprehensive tests for the DataTable component, designe
8
8
 
9
9
  - **`DataTable.workflowValidation.test.tsx`** - Comprehensive workflow validation covering all core functionality
10
10
  - **`DataTable.regressionFixes.test.tsx`** - Documents specific fixes and prevents known regressions
11
- - **`DataTable.autoSizing.test.tsx`** - Tests for automatic column width adjustment functionality
11
+ - **`DataTable.sorting.test.tsx`** - Comprehensive sorting functionality tests including visual indicators and accessibility
12
12
 
13
13
  ### Existing Tests
14
14
 
@@ -49,6 +49,12 @@ The `DataTable.workflowValidation.test.tsx` file provides comprehensive coverage
49
49
  - Filtering behavior
50
50
  - Actions preservation during search
51
51
 
52
+ - **Sorting Workflow Validation (4 tests)**
53
+ - Sortable column indicators (↕️ unsorted, ↑ ascending, ↓ descending)
54
+ - Click behavior for sorting
55
+ - Non-sortable column behavior
56
+ - Visual feedback and accessibility
57
+
52
58
  - **Data Integrity Validation (3 tests)**
53
59
  - Exact prop data display
54
60
  - Empty data handling
@@ -118,13 +124,16 @@ npm test -- src/components/DataTable/__tests__/DataTable.workflowValidation.test
118
124
  # Regression fix tests
119
125
  npm test -- src/components/DataTable/__tests__/DataTable.regressionFixes.test.tsx
120
126
 
127
+ # Sorting functionality tests
128
+ npm test -- src/components/DataTable/__tests__/DataTable.sorting.test.tsx
129
+
121
130
  # Simple integration tests
122
131
  npm test -- src/components/DataTable/__tests__/DataTable.simple.test.tsx
123
132
  ```
124
133
 
125
134
  ## Test Coverage Summary
126
135
 
127
- - **47 total tests** in new regression prevention suites
136
+ - **91 total tests** in new regression prevention suites
128
137
  - **100% pass rate** for workflow validation
129
138
  - **100% pass rate** for regression fixes
130
139
  - **100% pass rate** for auto-sizing functionality
@@ -91,7 +91,6 @@ vi.mock('@tanstack/react-table', () => ({
91
91
  getIsSorted: () => false,
92
92
  },
93
93
  getContext: () => ({}),
94
- getSize: () => 150,
95
94
  },
96
95
  {
97
96
  id: 'email',
@@ -103,7 +102,6 @@ vi.mock('@tanstack/react-table', () => ({
103
102
  getIsSorted: () => false,
104
103
  },
105
104
  getContext: () => ({}),
106
- getSize: () => 200,
107
105
  },
108
106
  {
109
107
  id: 'role',
@@ -115,7 +113,6 @@ vi.mock('@tanstack/react-table', () => ({
115
113
  getIsSorted: () => false,
116
114
  },
117
115
  getContext: () => ({}),
118
- getSize: () => 100,
119
116
  },
120
117
  ],
121
118
  }],
@@ -203,14 +200,6 @@ vi.mock('../components/EmptyState', () => ({
203
200
  }));
204
201
 
205
202
  // Mock individual components
206
- vi.mock('../components/DataTableHeader', () => ({
207
- DataTableHeader: ({ title, description }: any) => (
208
- <div data-testid="data-table-header">
209
- {title && <h2 data-testid="table-title">{title}</h2>}
210
- {description && <p data-testid="table-description">{description}</p>}
211
- </div>
212
- ),
213
- }));
214
203
 
215
204
  vi.mock('../components/DataTableToolbar', () => ({
216
205
  DataTableToolbar: ({ searchable, globalFilter, onGlobalFilterChange }: any) => (
@@ -23,7 +23,6 @@ const MockDeleteIcon = ({ className }: { className?: string }) => <div className
23
23
  */
24
24
  export const mockComponents = {
25
25
  DataTableContext: vi.fn(({ children }: any) => <div data-testid="data-table-context">{children}</div>),
26
- DataTableHeader: vi.fn(() => <div data-testid="data-table-header">Header</div>),
27
26
  DataTableToolbar: vi.fn(() => <div data-testid="data-table-toolbar">Toolbar</div>),
28
27
  DataTableBody: vi.fn(() => <div data-testid="data-table-body">Body</div>),
29
28
  DataTableModals: vi.fn(() => <div data-testid="data-table-modals">Modals</div>),
@@ -25,7 +25,7 @@ export function ColumnVisibilityDropdown<TData>({
25
25
  );
26
26
 
27
27
  return (
28
- <Select>
28
+ <Select className="w-52">
29
29
  <SelectTrigger asChild>
30
30
  <Button
31
31
  variant="outline"
@@ -34,7 +34,7 @@ export function ColumnVisibilityDropdown<TData>({
34
34
  <span className="truncate">Columns</span>
35
35
  </Button>
36
36
  </SelectTrigger>
37
- <SelectContent className="w-56 !bg-main-50 border border-sec-200 shadow-lg z-[9999]" style={{ backgroundColor: 'white' }}>
37
+ <SelectContent>
38
38
  <div className="p-2 space-y-1">
39
39
  <div className="flex gap-1 mb-2">
40
40
  <Button
@@ -58,9 +58,8 @@
58
58
 
59
59
  import React from 'react';
60
60
  import { type Table, flexRender } from '@tanstack/react-table';
61
- import { TableBody, TableHead, TableHeader, TableRow, TableCell } from '../../Table/Table';
62
61
  import { Button } from '../../Button/Button';
63
- import { ChevronUp, ChevronDown, ChevronRight } from 'lucide-react';
62
+ import { ChevronUp, ChevronDown, ChevronRight, ChevronsUpDown } from 'lucide-react';
64
63
  import { EmptyState } from './EmptyState';
65
64
  import { Input } from '../../Input/Input';
66
65
  import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '../../Select/Select';
@@ -228,12 +227,12 @@ export function DataTableBody<TData extends Record<string, any>>({
228
227
  return (
229
228
  <>
230
229
  {/* Table Header */}
231
- <TableHeader>
230
+ <thead>
232
231
  {table.getHeaderGroups().map((headerGroup) => (
233
- <TableRow key={headerGroup.id}>
232
+ <tr key={headerGroup.id}>
234
233
  {/* Expand/Collapse All Button - Only show for hierarchical tables */}
235
234
  {hierarchical?.enabled && hierarchical?.hasAnyChildren && (
236
- <TableHead className="w-12">
235
+ <th className="w-12">
237
236
  <Button
238
237
  variant="ghost"
239
238
  size="sm"
@@ -248,7 +247,7 @@ export function DataTableBody<TData extends Record<string, any>>({
248
247
  <ChevronRight className="h-4 w-4" />
249
248
  )}
250
249
  </Button>
251
- </TableHead>
250
+ </th>
252
251
  )}
253
252
 
254
253
  {headerGroup.headers.map((header) => {
@@ -261,7 +260,7 @@ export function DataTableBody<TData extends Record<string, any>>({
261
260
  : 'none')
262
261
  : undefined;
263
262
  return (
264
- <TableHead
263
+ <th
265
264
  key={header.id}
266
265
  {...(isSortable ? { 'aria-sort': ariaSort } : {})}
267
266
  >
@@ -283,7 +282,7 @@ export function DataTableBody<TData extends Record<string, any>>({
283
282
  ) : header.column.getIsSorted() === 'desc' ? (
284
283
  <ChevronDown className="h-4 w-4" />
285
284
  ) : (
286
- <div className="h-4 w-4" />
285
+ <ChevronsUpDown className="h-4 w-4" />
287
286
  )}
288
287
  </div>
289
288
  </Button>
@@ -295,20 +294,20 @@ export function DataTableBody<TData extends Record<string, any>>({
295
294
  </div>
296
295
  )
297
296
  )}
298
- </TableHead>
297
+ </th>
299
298
  );
300
299
  })}
301
- </TableRow>
300
+ </tr>
302
301
  ))}
303
- </TableHeader>
302
+ </thead>
304
303
 
305
304
  {/* Table Body */}
306
- <TableBody>
305
+ <tbody>
307
306
  {/* Creation Row */}
308
307
  {isCreating && (
309
- <TableRow>
308
+ <tr>
310
309
  {table.getVisibleFlatColumns().map((column) => (
311
- <TableCell key={column.id}>
310
+ <td key={column.id}>
312
311
  {renderEditField(column, creationData[column.id], (value) => {
313
312
  if (typeof value === 'object' && value !== null) {
314
313
  // Handle editAccessorKey case
@@ -318,9 +317,9 @@ export function DataTableBody<TData extends Record<string, any>>({
318
317
  onCreationDataChange({ ...creationData, [column.id]: value });
319
318
  }
320
319
  }, creationData)}
321
- </TableCell>
320
+ </td>
322
321
  ))}
323
- <TableCell className="flex gap-1">
322
+ <td className="flex gap-1">
324
323
  <>
325
324
  <button
326
325
  onClick={onSaveCreation}
@@ -341,14 +340,14 @@ export function DataTableBody<TData extends Record<string, any>>({
341
340
  </svg>
342
341
  </button>
343
342
  </>
344
- </TableCell>
345
- </TableRow>
343
+ </td>
344
+ </tr>
346
345
  )}
347
346
 
348
347
  {/* Table Rows */}
349
348
  {table.getRowModel().rows.length === 0 && (
350
- <TableRow>
351
- <TableCell colSpan={table.getVisibleFlatColumns().length} role="status">
349
+ <tr>
350
+ <td colSpan={table.getVisibleFlatColumns().length} role="status">
352
351
  <EmptyState
353
352
  title={emptyState?.title}
354
353
  description={emptyState?.description}
@@ -357,8 +356,8 @@ export function DataTableBody<TData extends Record<string, any>>({
357
356
  isFiltered={isFiltered}
358
357
  onClearFilters={onClearFilters}
359
358
  />
360
- </TableCell>
361
- </TableRow>
359
+ </td>
360
+ </tr>
362
361
  )}
363
362
 
364
363
  {table.getRowModel().rows.map((row) => {
@@ -374,8 +373,8 @@ export function DataTableBody<TData extends Record<string, any>>({
374
373
  return (
375
374
  <React.Fragment key={row.id}>
376
375
  {/* Group Header Row */}
377
- <TableRow className="bg-app-sec-50 hover:bg-app-sec-100">
378
- <TableCell className="flex items-center py-2 font-medium" colSpan={table.getAllColumns().length}>
376
+ <tr className="bg-app-sec-50 hover:bg-app-sec-100">
377
+ <td className="flex items-center py-2 font-medium" colSpan={table.getAllColumns().length}>
379
378
  <>
380
379
  <Button
381
380
  variant="ghost"
@@ -393,8 +392,8 @@ export function DataTableBody<TData extends Record<string, any>>({
393
392
  {String(groupValue)} ({subRowsCount} items)
394
393
  </span>
395
394
  </>
396
- </TableCell>
397
- </TableRow>
395
+ </td>
396
+ </tr>
398
397
 
399
398
  {/* Render sub-rows if expanded */}
400
399
  {isExpanded && row.subRows?.map((subRow) => {
@@ -402,9 +401,9 @@ export function DataTableBody<TData extends Record<string, any>>({
402
401
  const isSubRowEditing = editingRowId === subRowId;
403
402
 
404
403
  return (
405
- <TableRow key={subRow.id} className="border-l-2 border-l-blue-200">
404
+ <tr key={subRow.id} className="border-l-2 border-l-blue-200">
406
405
  {subRow.getVisibleCells().map((cell) => (
407
- <TableCell key={cell.id} className="pl-8">
406
+ <td key={cell.id} className="pl-8">
408
407
  {isSubRowEditing && cell.column.id !== 'actions' ? (
409
408
  renderEditField(cell.column, editingData[cell.column.id], (value) => {
410
409
  if (typeof value === 'object' && value !== null) {
@@ -418,9 +417,9 @@ export function DataTableBody<TData extends Record<string, any>>({
418
417
  ) : (
419
418
  flexRender(cell.column.columnDef.cell, cell.getContext())
420
419
  )}
421
- </TableCell>
420
+ </td>
422
421
  ))}
423
- </TableRow>
422
+ </tr>
424
423
  );
425
424
  })}
426
425
  </React.Fragment>
@@ -435,9 +434,9 @@ export function DataTableBody<TData extends Record<string, any>>({
435
434
 
436
435
  // Regular row (non-grouped or when grouping is disabled)
437
436
  return (
438
- <TableRow key={row.id}>
437
+ <tr key={row.id}>
439
438
  {row.getVisibleCells().map((cell) => (
440
- <TableCell key={cell.id}>
439
+ <td key={cell.id}>
441
440
  {isEditing && cell.column.id !== 'actions' ? (
442
441
  renderEditField(cell.column, editingData[cell.column.id], (value) => {
443
442
  if (typeof value === 'object' && value !== null) {
@@ -451,12 +450,12 @@ export function DataTableBody<TData extends Record<string, any>>({
451
450
  ) : (
452
451
  flexRender(cell.column.columnDef.cell, cell.getContext())
453
452
  )}
454
- </TableCell>
453
+ </td>
455
454
  ))}
456
- </TableRow>
455
+ </tr>
457
456
  );
458
457
  })}
459
- </TableBody>
458
+ </tbody>
460
459
  </>
461
460
  );
462
461
  }