@shohojdhara/atomix 0.3.7 → 0.3.8
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/atomix.css +77 -0
- package/dist/atomix.css.map +1 -1
- package/dist/atomix.min.css +77 -0
- package/dist/atomix.min.css.map +1 -1
- package/dist/charts.js.map +1 -1
- package/dist/core.d.ts +2 -2
- package/dist/core.js.map +1 -1
- package/dist/forms.js.map +1 -1
- package/dist/heavy.js.map +1 -1
- package/dist/index.d.ts +578 -515
- package/dist/index.esm.js +3157 -2626
- package/dist/index.esm.js.map +1 -1
- package/dist/index.js +10496 -9973
- package/dist/index.js.map +1 -1
- package/dist/index.min.js +1 -1
- package/dist/index.min.js.map +1 -1
- package/dist/theme.d.ts +237 -420
- package/dist/theme.js +1629 -1701
- package/dist/theme.js.map +1 -1
- package/package.json +1 -1
- package/src/components/DataTable/DataTable.stories.tsx +238 -0
- package/src/components/DataTable/DataTable.test.tsx +450 -0
- package/src/components/DataTable/DataTable.tsx +384 -61
- package/src/components/DatePicker/DatePicker.tsx +29 -38
- package/src/components/Upload/Upload.tsx +539 -40
- package/src/lib/composables/useDataTable.ts +355 -15
- package/src/lib/composables/useDatePicker.ts +19 -0
- package/src/lib/constants/components.ts +10 -0
- package/src/lib/theme/adapters/cssVariableMapper.ts +29 -14
- package/src/lib/theme/adapters/index.ts +1 -4
- package/src/lib/theme/config/configLoader.ts +53 -35
- package/src/lib/theme/core/composeTheme.ts +22 -30
- package/src/lib/theme/core/createTheme.ts +49 -26
- package/src/lib/theme/core/index.ts +0 -1
- package/src/lib/theme/generators/generateCSSNested.ts +4 -3
- package/src/lib/theme/generators/generateCSSVariables.ts +24 -16
- package/src/lib/theme/index.ts +10 -17
- package/src/lib/theme/runtime/ThemeApplicator.ts +6 -109
- package/src/lib/theme/runtime/ThemeErrorBoundary.tsx +3 -3
- package/src/lib/theme/runtime/ThemeProvider.tsx +186 -44
- package/src/lib/theme/runtime/useTheme.ts +1 -1
- package/src/lib/theme/runtime/useThemeTokens.ts +7 -16
- package/src/lib/theme/test/testTheme.ts +2 -1
- package/src/lib/theme/types.ts +14 -14
- package/src/lib/theme/utils/componentTheming.ts +35 -27
- package/src/lib/theme/utils/domUtils.ts +57 -15
- package/src/lib/theme/utils/injectCSS.ts +0 -1
- package/src/lib/theme/utils/themeHelpers.ts +1 -39
- package/src/lib/theme/utils/themeUtils.ts +1 -170
- package/src/lib/types/components.ts +145 -0
- package/src/lib/utils/dataTableExport.ts +143 -0
- package/src/styles/06-components/_components.data-table.scss +95 -0
- package/src/lib/hooks/useThemeTokens.ts +0 -105
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { useState, useEffect, useCallback, useMemo } from 'react';
|
|
2
|
-
import { DataTableColumn, SortConfig } from '../types/components';
|
|
1
|
+
import { useState, useEffect, useCallback, useMemo, useRef } from 'react';
|
|
2
|
+
import { DataTableColumn, SortConfig, SelectionMode } from '../types/components';
|
|
3
3
|
|
|
4
4
|
export interface UseDataTableProps {
|
|
5
5
|
/**
|
|
@@ -36,6 +36,46 @@ export interface UseDataTableProps {
|
|
|
36
36
|
* Initial sort configuration
|
|
37
37
|
*/
|
|
38
38
|
initialSortConfig?: SortConfig;
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Row selection mode
|
|
42
|
+
*/
|
|
43
|
+
selectionMode?: SelectionMode;
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Selected row IDs (controlled)
|
|
47
|
+
*/
|
|
48
|
+
selectedRowIds?: (string | number)[];
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* Callback when selection changes
|
|
52
|
+
*/
|
|
53
|
+
onSelectionChange?: (selectedRows: any[], selectedIds: (string | number)[]) => void;
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* Key to use as unique identifier for rows
|
|
57
|
+
*/
|
|
58
|
+
rowKey?: string | ((row: any) => string | number);
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* Column-specific filters
|
|
62
|
+
*/
|
|
63
|
+
columnFilters?: boolean;
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* Whether columns can be reordered
|
|
67
|
+
*/
|
|
68
|
+
reorderable?: boolean;
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* Callback when column order changes
|
|
72
|
+
*/
|
|
73
|
+
onColumnReorder?: (columnKeys: string[]) => void;
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* Callback when column visibility changes
|
|
77
|
+
*/
|
|
78
|
+
onColumnVisibilityChange?: (visibleColumns: string[]) => void;
|
|
39
79
|
}
|
|
40
80
|
|
|
41
81
|
export interface UseDataTableReturn {
|
|
@@ -73,6 +113,84 @@ export interface UseDataTableReturn {
|
|
|
73
113
|
* Handle search input
|
|
74
114
|
*/
|
|
75
115
|
handleSearch: (query: string) => void;
|
|
116
|
+
|
|
117
|
+
/**
|
|
118
|
+
* Selected row IDs
|
|
119
|
+
*/
|
|
120
|
+
selectedRowIds: (string | number)[];
|
|
121
|
+
|
|
122
|
+
/**
|
|
123
|
+
* Selected rows data
|
|
124
|
+
*/
|
|
125
|
+
selectedRows: any[];
|
|
126
|
+
|
|
127
|
+
/**
|
|
128
|
+
* Handle row selection
|
|
129
|
+
*/
|
|
130
|
+
handleRowSelect: (rowId: string | number, selected: boolean) => void;
|
|
131
|
+
|
|
132
|
+
/**
|
|
133
|
+
* Handle select all
|
|
134
|
+
*/
|
|
135
|
+
handleSelectAll: (selected: boolean) => void;
|
|
136
|
+
|
|
137
|
+
/**
|
|
138
|
+
* Whether all rows are selected
|
|
139
|
+
*/
|
|
140
|
+
isAllSelected: boolean;
|
|
141
|
+
|
|
142
|
+
/**
|
|
143
|
+
* Whether some rows are selected
|
|
144
|
+
*/
|
|
145
|
+
isIndeterminate: boolean;
|
|
146
|
+
|
|
147
|
+
/**
|
|
148
|
+
* Column order
|
|
149
|
+
*/
|
|
150
|
+
columnOrder: string[];
|
|
151
|
+
|
|
152
|
+
/**
|
|
153
|
+
* Visible columns
|
|
154
|
+
*/
|
|
155
|
+
visibleColumns: DataTableColumn[];
|
|
156
|
+
|
|
157
|
+
/**
|
|
158
|
+
* Column visibility map
|
|
159
|
+
*/
|
|
160
|
+
columnVisibility: Record<string, boolean>;
|
|
161
|
+
|
|
162
|
+
/**
|
|
163
|
+
* Handle column visibility toggle
|
|
164
|
+
*/
|
|
165
|
+
handleColumnVisibilityToggle: (columnKey: string) => void;
|
|
166
|
+
|
|
167
|
+
/**
|
|
168
|
+
* Column-specific filter values
|
|
169
|
+
*/
|
|
170
|
+
columnFilterValues: Record<string, string>;
|
|
171
|
+
|
|
172
|
+
/**
|
|
173
|
+
* Handle column filter change
|
|
174
|
+
*/
|
|
175
|
+
handleColumnFilterChange: (columnKey: string, value: string) => void;
|
|
176
|
+
|
|
177
|
+
/**
|
|
178
|
+
* Clear all column filters
|
|
179
|
+
*/
|
|
180
|
+
clearColumnFilters: () => void;
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
/**
|
|
184
|
+
* Get unique row ID
|
|
185
|
+
*/
|
|
186
|
+
function getRowId(row: any, rowKey?: string | ((row: any) => string | number)): string | number {
|
|
187
|
+
if (typeof rowKey === 'function') {
|
|
188
|
+
return rowKey(row);
|
|
189
|
+
}
|
|
190
|
+
if (typeof rowKey === 'string') {
|
|
191
|
+
return row[rowKey];
|
|
192
|
+
}
|
|
193
|
+
return row.id ?? row.key ?? JSON.stringify(row);
|
|
76
194
|
}
|
|
77
195
|
|
|
78
196
|
/**
|
|
@@ -86,6 +204,14 @@ export function useDataTable({
|
|
|
86
204
|
pageSize = 10,
|
|
87
205
|
onSort,
|
|
88
206
|
initialSortConfig,
|
|
207
|
+
selectionMode = 'none',
|
|
208
|
+
selectedRowIds: controlledSelectedRowIds,
|
|
209
|
+
onSelectionChange,
|
|
210
|
+
rowKey,
|
|
211
|
+
columnFilters = false,
|
|
212
|
+
reorderable = false,
|
|
213
|
+
onColumnReorder,
|
|
214
|
+
onColumnVisibilityChange,
|
|
89
215
|
}: UseDataTableProps): UseDataTableReturn {
|
|
90
216
|
// Sort state
|
|
91
217
|
const [sortConfig, setSortConfig] = useState<SortConfig | null>(initialSortConfig || null);
|
|
@@ -96,6 +222,61 @@ export function useDataTable({
|
|
|
96
222
|
// Search state
|
|
97
223
|
const [searchQuery, setSearchQuery] = useState<string>('');
|
|
98
224
|
|
|
225
|
+
// Selection state
|
|
226
|
+
const [internalSelectedRowIds, setInternalSelectedRowIds] = useState<(string | number)[]>([]);
|
|
227
|
+
const selectedRowIds = controlledSelectedRowIds ?? internalSelectedRowIds;
|
|
228
|
+
|
|
229
|
+
// Column order state
|
|
230
|
+
const [columnOrder, setColumnOrder] = useState<string[]>(() => columns.map(col => col.key));
|
|
231
|
+
|
|
232
|
+
// Column visibility state
|
|
233
|
+
const [columnVisibility, setColumnVisibility] = useState<Record<string, boolean>>(() => {
|
|
234
|
+
const visibility: Record<string, boolean> = {};
|
|
235
|
+
columns.forEach(col => {
|
|
236
|
+
visibility[col.key] = col.visible !== false;
|
|
237
|
+
});
|
|
238
|
+
return visibility;
|
|
239
|
+
});
|
|
240
|
+
|
|
241
|
+
// Column-specific filter values
|
|
242
|
+
const [columnFilterValues, setColumnFilterValues] = useState<Record<string, string>>({});
|
|
243
|
+
|
|
244
|
+
// Update column order when columns prop changes
|
|
245
|
+
useEffect(() => {
|
|
246
|
+
const newOrder = columns.map(col => col.key);
|
|
247
|
+
const currentOrderSet = new Set(columnOrder);
|
|
248
|
+
const newOrderSet = new Set(newOrder);
|
|
249
|
+
|
|
250
|
+
// Only update if there are actual differences
|
|
251
|
+
if (
|
|
252
|
+
newOrder.length !== columnOrder.length ||
|
|
253
|
+
!newOrder.every(key => currentOrderSet.has(key)) ||
|
|
254
|
+
!columnOrder.every(key => newOrderSet.has(key))
|
|
255
|
+
) {
|
|
256
|
+
setColumnOrder(newOrder);
|
|
257
|
+
}
|
|
258
|
+
}, [columns]);
|
|
259
|
+
|
|
260
|
+
// Update column visibility when columns prop changes
|
|
261
|
+
useEffect(() => {
|
|
262
|
+
setColumnVisibility(prev => {
|
|
263
|
+
const updated: Record<string, boolean> = { ...prev };
|
|
264
|
+
columns.forEach(col => {
|
|
265
|
+
if (!(col.key in updated)) {
|
|
266
|
+
updated[col.key] = col.visible !== false;
|
|
267
|
+
}
|
|
268
|
+
});
|
|
269
|
+
return updated;
|
|
270
|
+
});
|
|
271
|
+
}, [columns]);
|
|
272
|
+
|
|
273
|
+
// Visible columns based on order and visibility
|
|
274
|
+
const visibleColumns = useMemo(() => {
|
|
275
|
+
return columnOrder
|
|
276
|
+
.map(key => columns.find(col => col.key === key))
|
|
277
|
+
.filter((col): col is DataTableColumn => col !== undefined && columnVisibility[col.key] !== false);
|
|
278
|
+
}, [columns, columnOrder, columnVisibility]);
|
|
279
|
+
|
|
99
280
|
// Handle sorting
|
|
100
281
|
const handleSort = useCallback(
|
|
101
282
|
(key: string) => {
|
|
@@ -120,10 +301,10 @@ export function useDataTable({
|
|
|
120
301
|
// Handle page change
|
|
121
302
|
const handlePageChange = useCallback(
|
|
122
303
|
(page: number) => {
|
|
123
|
-
if (page < 1
|
|
304
|
+
if (page < 1) return;
|
|
124
305
|
setCurrentPage(page);
|
|
125
306
|
},
|
|
126
|
-
[
|
|
307
|
+
[]
|
|
127
308
|
);
|
|
128
309
|
|
|
129
310
|
// Handle search
|
|
@@ -132,20 +313,62 @@ export function useDataTable({
|
|
|
132
313
|
setCurrentPage(1); // Reset to first page when searching
|
|
133
314
|
}, []);
|
|
134
315
|
|
|
135
|
-
//
|
|
316
|
+
// Handle column filter change
|
|
317
|
+
const handleColumnFilterChange = useCallback((columnKey: string, value: string) => {
|
|
318
|
+
setColumnFilterValues(prev => ({
|
|
319
|
+
...prev,
|
|
320
|
+
[columnKey]: value,
|
|
321
|
+
}));
|
|
322
|
+
setCurrentPage(1); // Reset to first page when filtering
|
|
323
|
+
}, []);
|
|
324
|
+
|
|
325
|
+
// Clear all column filters
|
|
326
|
+
const clearColumnFilters = useCallback(() => {
|
|
327
|
+
setColumnFilterValues({});
|
|
328
|
+
setCurrentPage(1);
|
|
329
|
+
}, []);
|
|
330
|
+
|
|
331
|
+
// Filter data based on search query and column filters
|
|
136
332
|
const filteredData = useMemo(() => {
|
|
137
|
-
|
|
333
|
+
let result = data;
|
|
334
|
+
|
|
335
|
+
// Apply global search
|
|
336
|
+
if (searchQuery) {
|
|
337
|
+
const lowercaseQuery = searchQuery.toLowerCase();
|
|
338
|
+
result = result.filter(row => {
|
|
339
|
+
return visibleColumns.some(column => {
|
|
340
|
+
const value = row[column.key];
|
|
341
|
+
if (value == null) return false;
|
|
342
|
+
return String(value).toLowerCase().includes(lowercaseQuery);
|
|
343
|
+
});
|
|
344
|
+
});
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
// Apply column-specific filters
|
|
348
|
+
if (columnFilters) {
|
|
349
|
+
result = result.filter(row => {
|
|
350
|
+
return Object.entries(columnFilterValues).every(([columnKey, filterValue]) => {
|
|
351
|
+
if (!filterValue) return true;
|
|
138
352
|
|
|
139
|
-
|
|
353
|
+
const column = columns.find(col => col.key === columnKey);
|
|
354
|
+
if (!column || !column.filterable) return true;
|
|
140
355
|
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
356
|
+
const cellValue = row[columnKey];
|
|
357
|
+
if (cellValue == null) return false;
|
|
358
|
+
|
|
359
|
+
// Use custom filter function if provided
|
|
360
|
+
if (column.filterFunction) {
|
|
361
|
+
return column.filterFunction(cellValue, filterValue);
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
// Default text filter
|
|
365
|
+
return String(cellValue).toLowerCase().includes(filterValue.toLowerCase());
|
|
366
|
+
});
|
|
146
367
|
});
|
|
147
|
-
}
|
|
148
|
-
|
|
368
|
+
}
|
|
369
|
+
|
|
370
|
+
return result;
|
|
371
|
+
}, [data, visibleColumns, searchQuery, columnFilterValues, columnFilters, columns]);
|
|
149
372
|
|
|
150
373
|
// Sort data
|
|
151
374
|
const sortedData = useMemo(() => {
|
|
@@ -182,6 +405,110 @@ export function useDataTable({
|
|
|
182
405
|
return Math.max(1, Math.ceil(sortedData.length / pageSize));
|
|
183
406
|
}, [sortedData.length, paginated, pageSize]);
|
|
184
407
|
|
|
408
|
+
// Selected rows data
|
|
409
|
+
const selectedRows = useMemo(() => {
|
|
410
|
+
if (selectionMode === 'none' || selectedRowIds.length === 0) return [];
|
|
411
|
+
return sortedData.filter(row => selectedRowIds.includes(getRowId(row, rowKey)));
|
|
412
|
+
}, [sortedData, selectedRowIds, selectionMode, rowKey]);
|
|
413
|
+
|
|
414
|
+
// Handle row selection
|
|
415
|
+
const handleRowSelect = useCallback(
|
|
416
|
+
(rowId: string | number, selected: boolean) => {
|
|
417
|
+
if (selectionMode === 'none') return;
|
|
418
|
+
|
|
419
|
+
let newSelectedIds: (string | number)[];
|
|
420
|
+
|
|
421
|
+
if (selectionMode === 'single') {
|
|
422
|
+
newSelectedIds = selected ? [rowId] : [];
|
|
423
|
+
} else {
|
|
424
|
+
// multiple
|
|
425
|
+
if (selected) {
|
|
426
|
+
newSelectedIds = [...selectedRowIds, rowId];
|
|
427
|
+
} else {
|
|
428
|
+
newSelectedIds = selectedRowIds.filter(id => id !== rowId);
|
|
429
|
+
}
|
|
430
|
+
}
|
|
431
|
+
|
|
432
|
+
if (!controlledSelectedRowIds) {
|
|
433
|
+
setInternalSelectedRowIds(newSelectedIds);
|
|
434
|
+
}
|
|
435
|
+
|
|
436
|
+
if (onSelectionChange) {
|
|
437
|
+
const selectedRowsData = sortedData.filter(row => newSelectedIds.includes(getRowId(row, rowKey)));
|
|
438
|
+
onSelectionChange(selectedRowsData, newSelectedIds);
|
|
439
|
+
}
|
|
440
|
+
},
|
|
441
|
+
[selectionMode, selectedRowIds, controlledSelectedRowIds, onSelectionChange, sortedData, rowKey]
|
|
442
|
+
);
|
|
443
|
+
|
|
444
|
+
// Handle select all
|
|
445
|
+
const handleSelectAll = useCallback(
|
|
446
|
+
(selected: boolean) => {
|
|
447
|
+
if (selectionMode !== 'multiple') return;
|
|
448
|
+
|
|
449
|
+
const newSelectedIds = selected
|
|
450
|
+
? paginatedData.map(row => getRowId(row, rowKey))
|
|
451
|
+
: [];
|
|
452
|
+
|
|
453
|
+
if (!controlledSelectedRowIds) {
|
|
454
|
+
setInternalSelectedRowIds(newSelectedIds);
|
|
455
|
+
}
|
|
456
|
+
|
|
457
|
+
if (onSelectionChange) {
|
|
458
|
+
const selectedRowsData = sortedData.filter(row => newSelectedIds.includes(getRowId(row, rowKey)));
|
|
459
|
+
onSelectionChange(selectedRowsData, newSelectedIds);
|
|
460
|
+
}
|
|
461
|
+
},
|
|
462
|
+
[selectionMode, paginatedData, sortedData, controlledSelectedRowIds, onSelectionChange, rowKey]
|
|
463
|
+
);
|
|
464
|
+
|
|
465
|
+
// Check if all rows are selected
|
|
466
|
+
const isAllSelected = useMemo(() => {
|
|
467
|
+
if (selectionMode !== 'multiple' || paginatedData.length === 0) return false;
|
|
468
|
+
return paginatedData.every(row => selectedRowIds.includes(getRowId(row, rowKey)));
|
|
469
|
+
}, [selectionMode, paginatedData, selectedRowIds, rowKey]);
|
|
470
|
+
|
|
471
|
+
// Check if some rows are selected (indeterminate)
|
|
472
|
+
const isIndeterminate = useMemo(() => {
|
|
473
|
+
if (selectionMode !== 'multiple' || paginatedData.length === 0) return false;
|
|
474
|
+
const selectedCount = paginatedData.filter(row => selectedRowIds.includes(getRowId(row, rowKey))).length;
|
|
475
|
+
return selectedCount > 0 && selectedCount < paginatedData.length;
|
|
476
|
+
}, [selectionMode, paginatedData, selectedRowIds, rowKey]);
|
|
477
|
+
|
|
478
|
+
// Handle column visibility toggle
|
|
479
|
+
const handleColumnVisibilityToggle = useCallback(
|
|
480
|
+
(columnKey: string) => {
|
|
481
|
+
setColumnVisibility(prev => {
|
|
482
|
+
const updated = { ...prev, [columnKey]: !prev[columnKey] };
|
|
483
|
+
if (onColumnVisibilityChange) {
|
|
484
|
+
const visibleKeys = Object.entries(updated)
|
|
485
|
+
.filter(([, visible]) => visible)
|
|
486
|
+
.map(([key]) => key);
|
|
487
|
+
onColumnVisibilityChange(visibleKeys);
|
|
488
|
+
}
|
|
489
|
+
return updated;
|
|
490
|
+
});
|
|
491
|
+
},
|
|
492
|
+
[onColumnVisibilityChange]
|
|
493
|
+
);
|
|
494
|
+
|
|
495
|
+
// Handle column reorder
|
|
496
|
+
const handleColumnReorder = useCallback(
|
|
497
|
+
(fromIndex: number, toIndex: number) => {
|
|
498
|
+
const newOrder = [...columnOrder];
|
|
499
|
+
const [removed] = newOrder.splice(fromIndex, 1);
|
|
500
|
+
if (removed) {
|
|
501
|
+
newOrder.splice(toIndex, 0, removed);
|
|
502
|
+
setColumnOrder(newOrder);
|
|
503
|
+
|
|
504
|
+
if (onColumnReorder) {
|
|
505
|
+
onColumnReorder(newOrder);
|
|
506
|
+
}
|
|
507
|
+
}
|
|
508
|
+
},
|
|
509
|
+
[columnOrder, onColumnReorder]
|
|
510
|
+
);
|
|
511
|
+
|
|
185
512
|
// Reset to first page when data changes
|
|
186
513
|
useEffect(() => {
|
|
187
514
|
setCurrentPage(1);
|
|
@@ -189,7 +516,7 @@ export function useDataTable({
|
|
|
189
516
|
|
|
190
517
|
// Reset current page if it's out of bounds
|
|
191
518
|
useEffect(() => {
|
|
192
|
-
if (currentPage > totalPages) {
|
|
519
|
+
if (currentPage > totalPages && totalPages > 0) {
|
|
193
520
|
setCurrentPage(Math.max(1, totalPages));
|
|
194
521
|
}
|
|
195
522
|
}, [currentPage, totalPages]);
|
|
@@ -202,6 +529,19 @@ export function useDataTable({
|
|
|
202
529
|
handleSort,
|
|
203
530
|
handlePageChange,
|
|
204
531
|
handleSearch,
|
|
532
|
+
selectedRowIds,
|
|
533
|
+
selectedRows,
|
|
534
|
+
handleRowSelect,
|
|
535
|
+
handleSelectAll,
|
|
536
|
+
isAllSelected,
|
|
537
|
+
isIndeterminate,
|
|
538
|
+
columnOrder,
|
|
539
|
+
visibleColumns,
|
|
540
|
+
columnVisibility,
|
|
541
|
+
handleColumnVisibilityToggle,
|
|
542
|
+
columnFilterValues,
|
|
543
|
+
handleColumnFilterChange,
|
|
544
|
+
clearColumnFilters,
|
|
205
545
|
};
|
|
206
546
|
}
|
|
207
547
|
|
|
@@ -248,6 +248,22 @@ export function useDatePicker({
|
|
|
248
248
|
[currentMonth]
|
|
249
249
|
);
|
|
250
250
|
|
|
251
|
+
// Decade navigation handlers
|
|
252
|
+
const handlePrevDecade = useCallback(() => {
|
|
253
|
+
// Move back 12 years (since generateYears shows 12 years)
|
|
254
|
+
setViewDate(new Date(currentYear - 12, currentMonth, 1));
|
|
255
|
+
}, [currentYear, currentMonth]);
|
|
256
|
+
|
|
257
|
+
const handleNextDecade = useCallback(() => {
|
|
258
|
+
// Move forward 12 years (since generateYears shows 12 years)
|
|
259
|
+
setViewDate(new Date(currentYear + 12, currentMonth, 1));
|
|
260
|
+
}, [currentYear, currentMonth]);
|
|
261
|
+
|
|
262
|
+
// Switch from year view back to day view
|
|
263
|
+
const switchToDayView = useCallback(() => {
|
|
264
|
+
setViewMode('days');
|
|
265
|
+
}, []);
|
|
266
|
+
|
|
251
267
|
// Handle today button click
|
|
252
268
|
const handleTodayClick = useCallback(() => {
|
|
253
269
|
const todayDate = new Date();
|
|
@@ -546,8 +562,11 @@ export function useDatePicker({
|
|
|
546
562
|
// View mode handlers
|
|
547
563
|
switchToMonthView,
|
|
548
564
|
switchToYearView,
|
|
565
|
+
switchToDayView,
|
|
549
566
|
selectMonth,
|
|
550
567
|
selectYear,
|
|
568
|
+
handlePrevDecade,
|
|
569
|
+
handleNextDecade,
|
|
551
570
|
|
|
552
571
|
// Data generators
|
|
553
572
|
generateDays,
|
|
@@ -633,21 +633,31 @@ export const DATA_TABLE_CLASSES = {
|
|
|
633
633
|
header: 'c-data-table__header',
|
|
634
634
|
headerCell: 'c-data-table__header-cell',
|
|
635
635
|
headerContent: 'c-data-table__header-content',
|
|
636
|
+
headerActions: 'c-data-table__header-actions',
|
|
636
637
|
sortable: 'c-data-table__header-cell--sortable',
|
|
637
638
|
sortIcon: 'c-data-table__sort-icon',
|
|
638
639
|
row: 'c-data-table__row',
|
|
640
|
+
rowSelected: 'c-data-table__row--selected',
|
|
639
641
|
cell: 'c-data-table__cell',
|
|
642
|
+
selectionCell: 'c-data-table__cell--selection',
|
|
640
643
|
loadingCell: 'c-data-table__loading-cell',
|
|
641
644
|
loadingIndicator: 'c-data-table__loading-indicator',
|
|
642
645
|
emptyCell: 'c-data-table__empty-cell',
|
|
643
646
|
toolbar: 'c-data-table-toolbar',
|
|
647
|
+
toolbarLeft: 'c-data-table-toolbar__left',
|
|
648
|
+
toolbarRight: 'c-data-table-toolbar__right',
|
|
644
649
|
search: 'c-data-table-search',
|
|
645
650
|
searchInput: 'c-data-table-search__input',
|
|
651
|
+
columnFilter: 'c-data-table__column-filter',
|
|
646
652
|
pagination: 'c-data-table__pagination-container',
|
|
647
653
|
striped: 'c-data-table--striped',
|
|
648
654
|
bordered: 'c-data-table--bordered',
|
|
649
655
|
dense: 'c-data-table--dense',
|
|
650
656
|
loading: 'c-data-table--loading',
|
|
657
|
+
stickyHeader: 'c-data-table--sticky-header',
|
|
658
|
+
dragging: 'c-data-table__header-cell--dragging',
|
|
659
|
+
dragOver: 'c-data-table__header-cell--drag-over',
|
|
660
|
+
resizeHandle: 'c-data-table__resize-handle',
|
|
651
661
|
open: 'is-open',
|
|
652
662
|
};
|
|
653
663
|
|
|
@@ -164,16 +164,21 @@ export function mapSCSSTokensToCSSVars(
|
|
|
164
164
|
/**
|
|
165
165
|
* Apply CSS variables to an element
|
|
166
166
|
*
|
|
167
|
-
* @param element - Target element (defaults to document.documentElement)
|
|
168
167
|
* @param vars - CSS variables to apply
|
|
168
|
+
* @param element - Target element (defaults to document.documentElement)
|
|
169
169
|
*/
|
|
170
170
|
export function applyCSSVariables(
|
|
171
|
-
|
|
172
|
-
|
|
171
|
+
vars: Record<string, string | number>,
|
|
172
|
+
element?: HTMLElement
|
|
173
173
|
): void {
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
174
|
+
if (typeof window === 'undefined') {
|
|
175
|
+
return; // SSR safety
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
const target = element || document.documentElement;
|
|
179
|
+
Object.entries(vars).forEach(([key, value]) => {
|
|
180
|
+
target.style.setProperty(key, String(value));
|
|
181
|
+
});
|
|
177
182
|
}
|
|
178
183
|
|
|
179
184
|
/**
|
|
@@ -183,12 +188,17 @@ export function applyCSSVariables(
|
|
|
183
188
|
* @param element - Target element (defaults to document.documentElement)
|
|
184
189
|
*/
|
|
185
190
|
export function removeCSSVariables(
|
|
186
|
-
|
|
187
|
-
|
|
191
|
+
varNames: string[],
|
|
192
|
+
element?: HTMLElement
|
|
188
193
|
): void {
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
194
|
+
if (typeof window === 'undefined') {
|
|
195
|
+
return; // SSR safety
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
const target = element || document.documentElement;
|
|
199
|
+
varNames.forEach((varName) => {
|
|
200
|
+
target.style.removeProperty(varName);
|
|
201
|
+
});
|
|
192
202
|
}
|
|
193
203
|
|
|
194
204
|
/**
|
|
@@ -199,10 +209,15 @@ export function removeCSSVariables(
|
|
|
199
209
|
* @returns Variable value or null if not found
|
|
200
210
|
*/
|
|
201
211
|
export function getCSSVariable(
|
|
202
|
-
|
|
203
|
-
|
|
212
|
+
varName: string,
|
|
213
|
+
element?: HTMLElement
|
|
204
214
|
): string | null {
|
|
205
|
-
|
|
215
|
+
if (typeof window === 'undefined') {
|
|
216
|
+
return null; // SSR safety
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
const target = element || document.documentElement;
|
|
220
|
+
return getComputedStyle(target).getPropertyValue(varName).trim() || null;
|
|
206
221
|
}
|
|
207
222
|
|
|
208
223
|
/**
|
|
@@ -1,14 +1,11 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Theme Adapters
|
|
3
3
|
*
|
|
4
|
-
* Adapters for
|
|
4
|
+
* Adapters for working with DesignTokens and CSS variables
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
7
|
export {
|
|
8
|
-
themeToDesignTokens,
|
|
9
8
|
designTokensToCSSVars,
|
|
10
|
-
createDesignTokensFromTheme,
|
|
11
|
-
designTokensToTheme,
|
|
12
9
|
} from './themeAdapter';
|
|
13
10
|
|
|
14
11
|
export {
|