@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
@@ -1,180 +0,0 @@
1
- import React from 'react';
2
- import { DataTable } from '../DataTable';
3
- import type { DataTableFeatureConfig } from '../types';
4
-
5
- // Sample data with varying content lengths
6
- const sampleData = [
7
- {
8
- id: '1',
9
- eventName: 'AJ2025',
10
- eventDate: '06/01/2025',
11
- dishType: 'Dinner',
12
- dishName: 'Pulled pork on jacket potatoes & slaw'
13
- },
14
- {
15
- id: '2',
16
- eventName: 'AJ2025',
17
- eventDate: '06/01/2025',
18
- dishType: 'Dinner',
19
- dishName: 'Pork ragu pasta with salad & garlic bread'
20
- },
21
- {
22
- id: '3',
23
- eventName: 'AJ2025',
24
- eventDate: '06/01/2025',
25
- dishType: 'Dinner',
26
- dishName: 'Pulled pork soft tacos with salad'
27
- },
28
- {
29
- id: '4',
30
- eventName: 'AJ2025',
31
- eventDate: '06/01/2025',
32
- dishType: 'Dinner',
33
- dishName: 'Beef burritos with salad'
34
- },
35
- {
36
- id: '5',
37
- eventName: 'AJ2025',
38
- eventDate: '06/01/2025',
39
- dishType: 'Dinner',
40
- dishName: 'Pasta Bolognese, garlic bread & garden salad'
41
- },
42
- {
43
- id: '6',
44
- eventName: 'AJ2025',
45
- eventDate: '06/01/2025',
46
- dishType: 'Dinner',
47
- dishName: 'Jacket potatoes with Bolognese & slaw'
48
- },
49
- {
50
- id: '7',
51
- eventName: 'AJ2025',
52
- eventDate: '06/01/2025',
53
- dishType: 'Dinner',
54
- dishName: 'Butter chicken with rice & veggies'
55
- },
56
- {
57
- id: '8',
58
- eventName: 'AJ2025',
59
- eventDate: '06/01/2025',
60
- dishType: 'Dinner',
61
- dishName: 'Honey soy chicken with fried rice'
62
- },
63
- {
64
- id: '9',
65
- eventName: 'AJ2025',
66
- eventDate: '06/01/2025',
67
- dishType: 'Dinner',
68
- dishName: 'Sweet & sour chicken with veggies & noodles'
69
- },
70
- {
71
- id: '10',
72
- eventName: 'AJ2025',
73
- eventDate: '06/01/2025',
74
- dishType: 'Dinner',
75
- dishName: 'Loaded wedges with corned beef & slaw'
76
- }
77
- ];
78
-
79
- const columns = [
80
- {
81
- id: 'eventName',
82
- accessorKey: 'eventName',
83
- header: 'Event Name',
84
- enableSorting: true,
85
- },
86
- {
87
- id: 'eventDate',
88
- accessorKey: 'eventDate',
89
- header: 'Event Date',
90
- enableSorting: true,
91
- },
92
- {
93
- id: 'dishType',
94
- accessorKey: 'dishType',
95
- header: 'Dish Type',
96
- enableSorting: true,
97
- },
98
- {
99
- id: 'dishName',
100
- accessorKey: 'dishName',
101
- header: 'Dish Name',
102
- enableSorting: true,
103
- },
104
- ];
105
-
106
- // Feature configuration with auto-sizing enabled
107
- const featuresWithAutoSizing: DataTableFeatureConfig = {
108
- search: true,
109
- pagination: true,
110
- sorting: true,
111
- filtering: false,
112
- import: false,
113
- export: false,
114
- selection: false,
115
- creation: false,
116
- editing: false,
117
- deletion: false,
118
- deleteSelected: false,
119
- grouping: false,
120
- columnVisibility: false,
121
- columnReordering: false,
122
- hierarchical: false,
123
- autoColumnSizing: true, // Enable automatic column sizing
124
- };
125
-
126
- // Feature configuration without auto-sizing (fixed equal widths)
127
- const featuresWithoutAutoSizing: DataTableFeatureConfig = {
128
- search: true,
129
- pagination: true,
130
- sorting: true,
131
- filtering: false,
132
- import: false,
133
- export: false,
134
- selection: false,
135
- creation: false,
136
- editing: false,
137
- deletion: false,
138
- deleteSelected: false,
139
- grouping: false,
140
- columnVisibility: false,
141
- columnReordering: false,
142
- hierarchical: false,
143
- autoColumnSizing: false, // Disable automatic column sizing
144
- };
145
-
146
- export function AutoSizingExample() {
147
- return (
148
- <div className="space-y-8">
149
- <div>
150
- <h2 className="text-2xl font-bold mb-4">DataTable with Auto-Sizing Columns</h2>
151
- <p className="text-gray-600 mb-4">
152
- Notice how the "Dish Name" column is wider to accommodate the longer text content,
153
- while shorter columns like "Event Name" and "Dish Type" take up less space.
154
- </p>
155
- <DataTable
156
- data={sampleData}
157
- columns={columns}
158
- features={featuresWithAutoSizing}
159
- title="Auto-Sizing Table"
160
- />
161
- </div>
162
-
163
- <div>
164
- <h2 className="text-2xl font-bold mb-4">DataTable with Fixed Equal Widths</h2>
165
- <p className="text-gray-600 mb-4">
166
- This table uses fixed equal widths, causing text wrapping in the "Dish Name" column
167
- while other columns have empty space.
168
- </p>
169
- <DataTable
170
- data={sampleData}
171
- columns={columns}
172
- features={featuresWithoutAutoSizing}
173
- title="Fixed Width Table"
174
- />
175
- </div>
176
- </div>
177
- );
178
- }
179
-
180
- export default AutoSizingExample;
@@ -1,235 +0,0 @@
1
- import React from 'react';
2
- import { DataTable } from '../DataTable';
3
- import type { DataTableFeatureConfig } from '../types';
4
-
5
- // Sample data with varying content lengths to demonstrate auto-sizing
6
- const sampleData = [
7
- {
8
- id: '1',
9
- eventName: 'AJ2025',
10
- eventDate: '06/01/2025',
11
- dishType: 'Dinner',
12
- dishName: 'Pulled pork on jacket potatoes & slaw'
13
- },
14
- {
15
- id: '2',
16
- eventName: 'AJ2025',
17
- eventDate: '06/01/2025',
18
- dishType: 'Dinner',
19
- dishName: 'Pork ragu pasta with salad & garlic bread'
20
- },
21
- {
22
- id: '3',
23
- eventName: 'AJ2025',
24
- eventDate: '06/01/2025',
25
- dishType: 'Dinner',
26
- dishName: 'Pulled pork soft tacos with salad'
27
- },
28
- {
29
- id: '4',
30
- eventName: 'AJ2025',
31
- eventDate: '06/01/2025',
32
- dishType: 'Dinner',
33
- dishName: 'Beef burritos with salad'
34
- },
35
- {
36
- id: '5',
37
- eventName: 'AJ2025',
38
- eventDate: '06/01/2025',
39
- dishType: 'Dinner',
40
- dishName: 'Pasta Bolognese, garlic bread & garden salad'
41
- },
42
- {
43
- id: '6',
44
- eventName: 'AJ2025',
45
- eventDate: '06/01/2025',
46
- dishType: 'Dinner',
47
- dishName: 'Jacket potatoes with Bolognese & slaw'
48
- },
49
- {
50
- id: '7',
51
- eventName: 'AJ2025',
52
- eventDate: '06/01/2025',
53
- dishType: 'Dinner',
54
- dishName: 'Butter chicken with rice & veggies'
55
- },
56
- {
57
- id: '8',
58
- eventName: 'AJ2025',
59
- eventDate: '06/01/2025',
60
- dishType: 'Dinner',
61
- dishName: 'Honey soy chicken with fried rice'
62
- },
63
- {
64
- id: '9',
65
- eventName: 'AJ2025',
66
- eventDate: '06/01/2025',
67
- dishType: 'Dinner',
68
- dishName: 'Sweet & sour chicken with veggies & noodles'
69
- },
70
- {
71
- id: '10',
72
- eventName: 'AJ2025',
73
- eventDate: '06/01/2025',
74
- dishType: 'Dinner',
75
- dishName: 'Loaded wedges with corned beef & slaw'
76
- }
77
- ];
78
-
79
- const columns = [
80
- {
81
- id: 'eventName',
82
- accessorKey: 'eventName',
83
- header: 'Event Name',
84
- enableSorting: true,
85
- },
86
- {
87
- id: 'eventDate',
88
- accessorKey: 'eventDate',
89
- header: 'Event Date',
90
- enableSorting: true,
91
- },
92
- {
93
- id: 'dishType',
94
- accessorKey: 'dishType',
95
- header: 'Dish Type',
96
- enableSorting: true,
97
- },
98
- {
99
- id: 'dishName',
100
- accessorKey: 'dishName',
101
- header: 'Dish Name',
102
- enableSorting: true,
103
- },
104
- ];
105
-
106
- // Feature configuration with auto-sizing enabled
107
- const featuresWithAutoSizing: DataTableFeatureConfig = {
108
- search: true,
109
- pagination: true,
110
- sorting: true,
111
- filtering: false,
112
- import: false,
113
- export: false,
114
- selection: false,
115
- creation: false,
116
- editing: false,
117
- deletion: false,
118
- deleteSelected: false,
119
- grouping: false,
120
- columnVisibility: false,
121
- columnReordering: false,
122
- hierarchical: false,
123
- autoColumnSizing: true, // Enable automatic column sizing
124
- };
125
-
126
- // Feature configuration without auto-sizing (fixed equal widths)
127
- const featuresWithoutAutoSizing: DataTableFeatureConfig = {
128
- search: true,
129
- pagination: true,
130
- sorting: true,
131
- filtering: false,
132
- import: false,
133
- export: false,
134
- selection: false,
135
- creation: false,
136
- editing: false,
137
- deletion: false,
138
- deleteSelected: false,
139
- grouping: false,
140
- columnVisibility: false,
141
- columnReordering: false,
142
- hierarchical: false,
143
- autoColumnSizing: false, // Disable automatic column sizing
144
- };
145
-
146
- export function ColumnSizingComparison() {
147
- return (
148
- <div className="space-y-12">
149
- <div className="text-center">
150
- <h1 className="text-3xl font-bold mb-4">DataTable Column Sizing Comparison</h1>
151
- <p className="text-lg text-gray-600 max-w-4xl mx-auto">
152
- Compare how DataTable handles column widths with and without automatic sizing.
153
- Notice how the "Dish Name" column adjusts to content length in the auto-sizing version.
154
- </p>
155
- </div>
156
-
157
- <div className="space-y-8">
158
- <div>
159
- <div className="flex items-center gap-3 mb-4">
160
- <h2 className="text-2xl font-bold">✅ With Auto-Sizing (Recommended)</h2>
161
- <span className="px-3 py-1 bg-green-100 text-green-800 text-sm font-medium rounded-full">
162
- autoColumnSizing: true
163
- </span>
164
- </div>
165
- <p className="text-gray-600 mb-4">
166
- Columns automatically adjust their width based on content. The "Dish Name" column
167
- gets more space for longer text, while shorter columns like "Event Name" and "Dish Type"
168
- take up less space. This prevents text wrapping and improves readability.
169
- </p>
170
- <DataTable
171
- data={sampleData}
172
- columns={columns}
173
- features={featuresWithAutoSizing}
174
- title="Auto-Sizing Table"
175
- description="Columns automatically adjust to content width"
176
- />
177
- </div>
178
-
179
- <div>
180
- <div className="flex items-center gap-3 mb-4">
181
- <h2 className="text-2xl font-bold">❌ Without Auto-Sizing (Fixed Widths)</h2>
182
- <span className="px-3 py-1 bg-red-100 text-red-800 text-sm font-medium rounded-full">
183
- autoColumnSizing: false
184
- </span>
185
- </div>
186
- <p className="text-gray-600 mb-4">
187
- All columns have equal width regardless of content length. This causes the "Dish Name"
188
- column to wrap text unnecessarily while other columns have wasted space. This is the
189
- default behavior you were experiencing.
190
- </p>
191
- <DataTable
192
- data={sampleData}
193
- columns={columns}
194
- features={featuresWithoutAutoSizing}
195
- title="Fixed Width Table"
196
- description="All columns have equal width"
197
- />
198
- </div>
199
- </div>
200
-
201
- <div className="bg-blue-50 border border-blue-200 rounded-lg p-6">
202
- <h3 className="text-lg font-semibold text-blue-900 mb-3">💡 How to Enable Auto-Sizing</h3>
203
- <p className="text-blue-800 mb-4">
204
- To enable automatic column sizing in your DataTable, simply add <code className="bg-blue-100 px-2 py-1 rounded text-sm">autoColumnSizing: true</code> to your features configuration:
205
- </p>
206
- <pre className="bg-blue-100 p-4 rounded-lg text-sm overflow-x-auto">
207
- {`<DataTable
208
- data={yourData}
209
- columns={yourColumns}
210
- features={{
211
- search: true,
212
- pagination: true,
213
- sorting: true,
214
- autoColumnSizing: true, // 👈 Add this line
215
- // ... other features
216
- }}
217
- />`}
218
- </pre>
219
- </div>
220
-
221
- <div className="bg-gray-50 border border-gray-200 rounded-lg p-6">
222
- <h3 className="text-lg font-semibold text-gray-900 mb-3">🔧 How Auto-Sizing Works</h3>
223
- <ul className="text-gray-700 space-y-2">
224
- <li>• <strong>Content Analysis:</strong> Analyzes both header text and data content to determine optimal widths</li>
225
- <li>• <strong>Smart Calculation:</strong> Uses character count estimation (8px per character + padding)</li>
226
- <li>• <strong>Constraints:</strong> Respects min-width (80px) and max-width (400px) limits</li>
227
- <li>• <strong>Performance:</strong> Only samples first 100 rows for large datasets</li>
228
- <li>• <strong>Table Layout:</strong> Switches from <code>tableLayout: 'fixed'</code> to <code>tableLayout: 'auto'</code></li>
229
- </ul>
230
- </div>
231
- </div>
232
- );
233
- }
234
-
235
- export default ColumnSizingComparison;
@@ -1,237 +0,0 @@
1
- /**
2
- * @file Column Sizing Utilities Tests
3
- * @package @jmruthers/pace-core
4
- * @module Components/DataTable/utils/__tests__
5
- * @since 0.4.33
6
- *
7
- * Tests for column sizing utility functions.
8
- */
9
-
10
- import { describe, it, expect } from 'vitest';
11
- import {
12
- calculateContentWidth,
13
- calculateColumnWidths,
14
- getColumnSizingConfig
15
- } from '../columnSizing';
16
-
17
- describe('Column Sizing Utilities', () => {
18
- describe('calculateContentWidth', () => {
19
- it('calculates width for normal content', () => {
20
- const width = calculateContentWidth('Hello World', 80, 400, 32);
21
- expect(width).toBeGreaterThan(80);
22
- expect(width).toBeLessThan(400);
23
- });
24
-
25
- it('returns minWidth for empty content', () => {
26
- const width = calculateContentWidth('', 80, 400, 32);
27
- expect(width).toBe(80);
28
- });
29
-
30
- it('returns minWidth for null content', () => {
31
- const width = calculateContentWidth(null as any, 80, 400, 32);
32
- expect(width).toBe(80);
33
- });
34
-
35
- it('returns minWidth for undefined content', () => {
36
- const width = calculateContentWidth(undefined as any, 80, 400, 32);
37
- expect(width).toBe(80);
38
- });
39
-
40
- it('respects maxWidth constraint', () => {
41
- const longText = 'A'.repeat(1000);
42
- const width = calculateContentWidth(longText, 80, 400, 32);
43
- expect(width).toBe(400);
44
- });
45
-
46
- it('respects minWidth constraint', () => {
47
- const width = calculateContentWidth('A', 200, 400, 32);
48
- expect(width).toBe(200);
49
- });
50
-
51
- it('uses default parameters correctly', () => {
52
- const width = calculateContentWidth('Test');
53
- expect(width).toBeGreaterThanOrEqual(80);
54
- expect(width).toBeLessThan(400);
55
- });
56
-
57
- it('includes padding in calculation', () => {
58
- const width1 = calculateContentWidth('Test', 80, 400, 0);
59
- const width2 = calculateContentWidth('Test', 80, 400, 50);
60
- expect(width2).toBeGreaterThan(width1);
61
- });
62
- });
63
-
64
- describe('calculateColumnWidths', () => {
65
- const testData = [
66
- { id: '1', name: 'John', email: 'john@example.com', description: 'A short description' },
67
- { id: '2', name: 'Jane', email: 'jane@example.com', description: 'A very long description that should make this column wider' },
68
- { id: '3', name: 'Bob', email: 'bob@example.com', description: 'Medium length description' }
69
- ];
70
-
71
- const testColumns = [
72
- { id: 'name', accessorKey: 'name', header: 'Name' },
73
- { id: 'email', accessorKey: 'email', header: 'Email' },
74
- { id: 'description', accessorKey: 'description', header: 'Description' }
75
- ];
76
-
77
- it('calculates widths for all columns', () => {
78
- const widths = calculateColumnWidths(testData, testColumns);
79
-
80
- expect(widths).toHaveProperty('name');
81
- expect(widths).toHaveProperty('email');
82
- expect(widths).toHaveProperty('description');
83
-
84
- expect(widths.name).toBeGreaterThan(0);
85
- expect(widths.email).toBeGreaterThan(0);
86
- expect(widths.description).toBeGreaterThan(0);
87
- });
88
-
89
- it('makes wider columns for longer content', () => {
90
- const widths = calculateColumnWidths(testData, testColumns);
91
-
92
- // Description column should be wider than name column
93
- expect(widths.description).toBeGreaterThan(widths.name);
94
- });
95
-
96
- it('respects min and max width constraints', () => {
97
- const widths = calculateColumnWidths(testData, testColumns, {
98
- minWidth: 100,
99
- maxWidth: 200
100
- });
101
-
102
- Object.values(widths).forEach(width => {
103
- expect(width).toBeGreaterThanOrEqual(100);
104
- expect(width).toBeLessThanOrEqual(200);
105
- });
106
- });
107
-
108
- it('handles empty data array', () => {
109
- const widths = calculateColumnWidths([], testColumns);
110
-
111
- expect(widths).toHaveProperty('name');
112
- expect(widths).toHaveProperty('email');
113
- expect(widths).toHaveProperty('description');
114
-
115
- // Should still calculate widths based on headers
116
- Object.values(widths).forEach(width => {
117
- expect(width).toBeGreaterThan(0);
118
- });
119
- });
120
-
121
- it('handles columns without id or accessorKey', () => {
122
- const invalidColumns = [
123
- { header: 'Valid Column', accessorKey: 'valid' },
124
- { header: 'Invalid Column' }, // No id or accessorKey
125
- { id: 'another', header: 'Another Valid' }
126
- ];
127
-
128
- const widths = calculateColumnWidths(testData, invalidColumns);
129
-
130
- expect(widths).toHaveProperty('valid');
131
- expect(widths).toHaveProperty('another');
132
- expect(widths).not.toHaveProperty('undefined');
133
- });
134
-
135
- it('handles data with null/undefined values', () => {
136
- const dataWithNulls = [
137
- { id: '1', name: 'John', email: null, description: undefined },
138
- { id: '2', name: null, email: 'jane@example.com', description: 'Valid description' }
139
- ];
140
-
141
- const widths = calculateColumnWidths(dataWithNulls, testColumns);
142
-
143
- expect(widths).toHaveProperty('name');
144
- expect(widths).toHaveProperty('email');
145
- expect(widths).toHaveProperty('description');
146
-
147
- Object.values(widths).forEach(width => {
148
- expect(width).toBeGreaterThan(0);
149
- });
150
- });
151
-
152
- it('uses sample size limit for large datasets', () => {
153
- const largeData = Array.from({ length: 10000 }, (_, i) => ({
154
- id: i.toString(),
155
- name: `User ${i}`,
156
- email: `user${i}@example.com`,
157
- description: `Description for user ${i}`
158
- }));
159
-
160
- const widths = calculateColumnWidths(largeData, testColumns, {
161
- sampleSize: 100
162
- });
163
-
164
- expect(widths).toHaveProperty('name');
165
- expect(widths).toHaveProperty('email');
166
- expect(widths).toHaveProperty('description');
167
- });
168
-
169
- it('handles columns with accessorFn', () => {
170
- const columnsWithFn = [
171
- { id: 'name', accessorKey: 'name', header: 'Name' },
172
- {
173
- id: 'fullName',
174
- accessorFn: (row: any) => `${row.firstName} ${row.lastName}`,
175
- header: 'Full Name'
176
- }
177
- ];
178
-
179
- const dataWithFn = [
180
- { id: '1', name: 'John', firstName: 'John', lastName: 'Doe' },
181
- { id: '2', name: 'Jane', firstName: 'Jane', lastName: 'Smith' }
182
- ];
183
-
184
- const widths = calculateColumnWidths(dataWithFn, columnsWithFn);
185
-
186
- expect(widths).toHaveProperty('name');
187
- expect(widths).toHaveProperty('fullName');
188
- });
189
- });
190
-
191
- describe('getColumnSizingConfig', () => {
192
- it('returns basic config when auto-sizing disabled', () => {
193
- const config = getColumnSizingConfig(false);
194
-
195
- expect(config).toEqual({
196
- columnResizeMode: 'onChange'
197
- });
198
- });
199
-
200
- it('returns enhanced config when auto-sizing enabled', () => {
201
- const config = getColumnSizingConfig(true);
202
-
203
- expect(config).toEqual({
204
- columnResizeMode: 'onChange',
205
- enableColumnResizing: true,
206
- columnResizeDirection: 'ltr'
207
- });
208
- });
209
-
210
- it('includes initial column sizes when provided', () => {
211
- const columnWidths = { name: 150, email: 200, description: 300 };
212
- const config = getColumnSizingConfig(true, columnWidths);
213
-
214
- expect(config).toEqual({
215
- columnResizeMode: 'onChange',
216
- enableColumnResizing: true,
217
- columnResizeDirection: 'ltr',
218
- initialState: {
219
- columnSizing: columnWidths
220
- }
221
- });
222
- });
223
-
224
- it('handles empty column widths object', () => {
225
- const config = getColumnSizingConfig(true, {});
226
-
227
- expect(config).toEqual({
228
- columnResizeMode: 'onChange',
229
- enableColumnResizing: true,
230
- columnResizeDirection: 'ltr',
231
- initialState: {
232
- columnSizing: {}
233
- }
234
- });
235
- });
236
- });
237
- });