@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.
- package/dist/{DataTable-BHlzyKZP.d.ts → DataTable-C1AEm9Cx.d.ts} +1 -1
- package/dist/{DataTable-GEY5U7OI.js → DataTable-EEUDXPE5.js} +2 -8
- package/dist/{api-T6CBS7IO.js → api-ETQ6YJ3C.js} +2 -3
- package/dist/{chunk-DY5E3AT7.js → chunk-BEZRLNK3.js} +13 -3
- package/dist/chunk-BEZRLNK3.js.map +1 -0
- package/dist/{chunk-ANE4PDC2.js → chunk-C5G2A4PO.js} +159 -6
- package/dist/chunk-C5G2A4PO.js.map +1 -0
- package/dist/{chunk-WYB6MBZA.js → chunk-EWKPTNPO.js} +579 -973
- package/dist/chunk-EWKPTNPO.js.map +1 -0
- package/dist/{chunk-TMRLB2LA.js → chunk-HEMJ4SUJ.js} +2 -2
- package/dist/{chunk-O4T53L7X.js → chunk-HNDFPXUU.js} +5 -5
- package/dist/{chunk-UY7AM4QG.js → chunk-RRUYHORU.js} +161 -74
- package/dist/chunk-RRUYHORU.js.map +1 -0
- package/dist/{chunk-PFRRIDYA.js → chunk-TIVL4UQ7.js} +2 -2
- package/dist/{chunk-2MKP6IYD.js → chunk-VYG4AXYW.js} +2 -2
- package/dist/components.d.ts +2 -2
- package/dist/components.js +15 -16
- package/dist/components.js.map +1 -1
- package/dist/hooks.d.ts +1 -1
- package/dist/hooks.js +4 -4
- package/dist/index.d.ts +2 -2
- package/dist/index.js +16 -17
- package/dist/index.js.map +1 -1
- package/dist/providers.js +2 -2
- package/dist/rbac/index.js +25 -20
- package/dist/rbac/index.js.map +1 -1
- package/dist/styles/core.css +83 -62
- package/dist/{types-CInEi-ng.d.ts → types-DiRQsGJs.d.ts} +0 -2
- package/dist/utils.d.ts +2 -2
- package/dist/utils.js +1 -1
- package/docs/api/classes/ErrorBoundary.md +1 -1
- package/docs/api/classes/PublicErrorBoundary.md +1 -1
- package/docs/api/interfaces/AggregateConfig.md +1 -1
- package/docs/api/interfaces/ButtonProps.md +1 -1
- package/docs/api/interfaces/CardProps.md +1 -1
- package/docs/api/interfaces/ColorPalette.md +1 -1
- package/docs/api/interfaces/ColorShade.md +1 -1
- package/docs/api/interfaces/DataTableAction.md +1 -1
- package/docs/api/interfaces/DataTableColumn.md +1 -1
- package/docs/api/interfaces/DataTableProps.md +33 -33
- package/docs/api/interfaces/DataTableToolbarButton.md +1 -1
- package/docs/api/interfaces/EmptyStateConfig.md +1 -1
- package/docs/api/interfaces/EventContextType.md +1 -1
- package/docs/api/interfaces/EventLogoProps.md +1 -1
- package/docs/api/interfaces/EventProviderProps.md +1 -1
- package/docs/api/interfaces/FileSizeLimits.md +1 -1
- package/docs/api/interfaces/FileUploadProps.md +1 -1
- package/docs/api/interfaces/FooterProps.md +1 -1
- package/docs/api/interfaces/InactivityWarningModalProps.md +1 -1
- package/docs/api/interfaces/InputProps.md +1 -1
- package/docs/api/interfaces/LabelProps.md +1 -1
- package/docs/api/interfaces/LoginFormProps.md +1 -1
- package/docs/api/interfaces/NavigationItem.md +1 -1
- package/docs/api/interfaces/NavigationMenuProps.md +1 -1
- package/docs/api/interfaces/Organisation.md +1 -1
- package/docs/api/interfaces/OrganisationContextType.md +1 -1
- package/docs/api/interfaces/OrganisationMembership.md +1 -1
- package/docs/api/interfaces/OrganisationProviderProps.md +1 -1
- package/docs/api/interfaces/OrganisationSecurityError.md +1 -1
- package/docs/api/interfaces/PaceAppLayoutProps.md +1 -1
- package/docs/api/interfaces/PaceLoginPageProps.md +1 -1
- package/docs/api/interfaces/PaletteData.md +1 -1
- package/docs/api/interfaces/PublicErrorBoundaryProps.md +1 -1
- package/docs/api/interfaces/PublicErrorBoundaryState.md +1 -1
- package/docs/api/interfaces/PublicLoadingSpinnerProps.md +1 -1
- package/docs/api/interfaces/PublicPageFooterProps.md +1 -1
- package/docs/api/interfaces/PublicPageHeaderProps.md +1 -1
- package/docs/api/interfaces/PublicPageLayoutProps.md +1 -1
- package/docs/api/interfaces/StorageConfig.md +1 -1
- package/docs/api/interfaces/StorageFileInfo.md +1 -1
- package/docs/api/interfaces/StorageFileMetadata.md +1 -1
- package/docs/api/interfaces/StorageListOptions.md +1 -1
- package/docs/api/interfaces/StorageListResult.md +1 -1
- package/docs/api/interfaces/StorageUploadOptions.md +1 -1
- package/docs/api/interfaces/StorageUploadResult.md +1 -1
- package/docs/api/interfaces/StorageUrlOptions.md +1 -1
- package/docs/api/interfaces/StyleImport.md +1 -1
- package/docs/api/interfaces/ToastActionElement.md +1 -1
- package/docs/api/interfaces/ToastProps.md +1 -1
- package/docs/api/interfaces/UnifiedAuthContextType.md +1 -1
- package/docs/api/interfaces/UnifiedAuthProviderProps.md +1 -1
- package/docs/api/interfaces/UseInactivityTrackerOptions.md +1 -1
- package/docs/api/interfaces/UseInactivityTrackerReturn.md +1 -1
- package/docs/api/interfaces/UsePublicEventLogoOptions.md +1 -1
- package/docs/api/interfaces/UsePublicEventLogoReturn.md +1 -1
- package/docs/api/interfaces/UsePublicEventOptions.md +1 -1
- package/docs/api/interfaces/UsePublicEventReturn.md +1 -1
- package/docs/api/interfaces/UsePublicRouteParamsReturn.md +1 -1
- package/docs/api/interfaces/UserEventAccess.md +1 -1
- package/docs/api/interfaces/UserMenuProps.md +1 -1
- package/docs/api/interfaces/UserProfile.md +1 -1
- package/docs/api/modules.md +10 -10
- package/docs/architecture/README.md +1 -1
- package/package.json +1 -1
- package/src/__tests__/shared/testUtils.optimized.tsx +65 -7
- package/src/components/DataTable/DataTable.tsx +1 -3
- package/src/components/DataTable/__tests__/DataTable.errorHandling.test.tsx +0 -8
- package/src/components/DataTable/__tests__/DataTable.hierarchical.test.tsx +17 -12
- package/src/components/DataTable/__tests__/DataTable.infinite-loop.test.tsx +0 -1
- package/src/components/DataTable/__tests__/DataTable.integration.test.tsx +4 -12
- package/src/components/DataTable/__tests__/DataTable.performance.test.tsx +0 -8
- package/src/components/DataTable/__tests__/DataTable.permissions.test.tsx +21 -11
- package/src/components/DataTable/__tests__/DataTable.sorting.test.tsx +321 -0
- package/src/components/DataTable/__tests__/DataTable.userWorkflows.test.tsx +21 -11
- package/src/components/DataTable/__tests__/DataTable.workflowValidation.test.tsx +94 -0
- package/src/components/DataTable/__tests__/DataTable.workflows.test.tsx +25 -15
- package/src/components/DataTable/__tests__/README.md +11 -2
- package/src/components/DataTable/__tests__/performance-regression.test.tsx +0 -11
- package/src/components/DataTable/__tests__/test-utils/sharedTestUtils.tsx +0 -1
- package/src/components/DataTable/components/ColumnVisibilityDropdown.tsx +2 -2
- package/src/components/DataTable/components/DataTableBody.tsx +34 -35
- package/src/components/DataTable/components/DataTableCore.tsx +205 -133
- package/src/components/DataTable/components/DataTableToolbar.tsx +9 -10
- package/src/components/DataTable/components/DraggableColumnHeader.tsx +3 -7
- package/src/components/DataTable/components/EditableRow.tsx +6 -7
- package/src/components/DataTable/components/FilterRow.tsx +0 -1
- package/src/components/DataTable/components/GroupingDropdown.tsx +2 -2
- package/src/components/DataTable/components/UnifiedTableBody.tsx +83 -281
- package/src/components/DataTable/components/VirtualizedDataTable.tsx +9 -89
- package/src/components/DataTable/components/__tests__/DataTable.accessibility.test.tsx +111 -5
- package/src/components/DataTable/components/__tests__/DataTable.integration.test.tsx +82 -13
- package/src/components/DataTable/components/__tests__/DataTable.performance.test.tsx +0 -1
- package/src/components/DataTable/components/__tests__/DataTable.real.test.tsx +2 -2
- package/src/components/DataTable/components/__tests__/DataTable.security.test.tsx +0 -1
- package/src/components/DataTable/components/__tests__/DataTable.unit.test.tsx +2 -2
- package/src/components/DataTable/components/__tests__/FilteringToggle.unit.test.tsx +3 -0
- package/src/components/DataTable/components/index.ts +0 -1
- package/src/components/DataTable/core/DataTableContext.tsx +0 -1
- package/src/components/DataTable/index.ts +0 -2
- package/src/components/DataTable/types.ts +0 -2
- package/src/components/Input/Input.tsx +2 -2
- package/src/components/Input/__tests__/Input.unit.test.tsx +4 -4
- package/src/components/PaceAppLayout/__tests__/PaceAppLayout.integration.test.tsx +6 -2
- package/src/components/RBAC/PagePermissionGuard.tsx +13 -0
- package/src/components/RBAC/__tests__/PagePermissionGuard.unit.test.tsx +10 -1
- package/src/components/Select/Select.tsx +7 -1
- package/src/components/__tests__/EdgeCaseTesting.enhanced.test.tsx +2 -1
- package/src/hooks/__tests__/useRBAC.unit.test.ts +32 -24
- package/src/providers/RBACProvider.tsx +14 -2
- package/src/providers/__tests__/UnifiedAuthProvider.unit.test.tsx +11 -3
- package/src/rbac/__tests__/cache-invalidation.test.ts +2 -2
- package/src/rbac/__tests__/cache.test.ts +3 -3
- package/src/rbac/hooks.ts +15 -7
- package/src/styles/core.css +83 -62
- package/src/utils/__tests__/lazyLoad.unit.test.tsx +13 -18
- package/src/utils/storage/__tests__/helpers.unit.test.ts +9 -7
- package/dist/cache-I72HKDOA.js +0 -12
- package/dist/cache-I72HKDOA.js.map +0 -1
- package/dist/chunk-ANE4PDC2.js.map +0 -1
- package/dist/chunk-DY5E3AT7.js.map +0 -1
- package/dist/chunk-MRRFJ6SA.js +0 -161
- package/dist/chunk-MRRFJ6SA.js.map +0 -1
- package/dist/chunk-UY7AM4QG.js.map +0 -1
- package/dist/chunk-WYB6MBZA.js.map +0 -1
- package/src/components/DataTable/__tests__/DataTable.autoSizing.test.tsx +0 -526
- package/src/components/DataTable/components/DataTableHeader.tsx +0 -31
- package/src/components/DataTable/components/__tests__/DataTableHeader.unit.test.tsx +0 -143
- package/src/components/DataTable/examples/AutoSizingExample.tsx +0 -180
- package/src/components/DataTable/examples/ColumnSizingComparison.tsx +0 -235
- package/src/components/DataTable/utils/__tests__/columnSizing.test.ts +0 -237
- package/src/components/DataTable/utils/columnSizing.ts +0 -125
- /package/dist/{DataTable-GEY5U7OI.js.map → DataTable-EEUDXPE5.js.map} +0 -0
- /package/dist/{api-T6CBS7IO.js.map → api-ETQ6YJ3C.js.map} +0 -0
- /package/dist/{chunk-TMRLB2LA.js.map → chunk-HEMJ4SUJ.js.map} +0 -0
- /package/dist/{chunk-O4T53L7X.js.map → chunk-HNDFPXUU.js.map} +0 -0
- /package/dist/{chunk-PFRRIDYA.js.map → chunk-TIVL4UQ7.js.map} +0 -0
- /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
|
-
});
|