@ackplus/react-tanstack-data-table 1.0.35 → 1.1.3
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/LICENSE +21 -0
- package/{src → dist}/index.d.ts +21 -4
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +63 -0
- package/{src → dist}/lib/components/droupdown/menu-dropdown.d.ts +2 -1
- package/dist/lib/components/droupdown/menu-dropdown.d.ts.map +1 -0
- package/{src → dist}/lib/components/droupdown/menu-dropdown.js +38 -7
- package/{src → dist}/lib/components/filters/filter-value-input.d.ts +3 -1
- package/dist/lib/components/filters/filter-value-input.d.ts.map +1 -0
- package/dist/lib/components/filters/filter-value-input.js +83 -0
- package/{src → dist}/lib/components/filters/index.d.ts +1 -0
- package/dist/lib/components/filters/index.d.ts.map +1 -0
- package/dist/lib/components/filters/index.js +142 -0
- package/{src → dist}/lib/components/headers/draggable-header.d.ts +2 -2
- package/dist/lib/components/headers/draggable-header.d.ts.map +1 -0
- package/{src → dist}/lib/components/headers/draggable-header.js +81 -17
- package/dist/lib/components/headers/index.d.ts +6 -0
- package/dist/lib/components/headers/index.d.ts.map +1 -0
- package/dist/lib/components/headers/index.js +21 -0
- package/{src → dist}/lib/components/headers/table-header.d.ts +15 -1
- package/dist/lib/components/headers/table-header.d.ts.map +1 -0
- package/{src → dist}/lib/components/headers/table-header.js +50 -17
- package/{src → dist}/lib/components/index.d.ts +6 -1
- package/dist/lib/components/index.d.ts.map +1 -0
- package/dist/lib/components/index.js +32 -0
- package/{src → dist}/lib/components/pagination/data-table-pagination.d.ts +2 -1
- package/dist/lib/components/pagination/data-table-pagination.d.ts.map +1 -0
- package/{src → dist}/lib/components/pagination/data-table-pagination.js +20 -6
- package/dist/lib/components/pagination/index.d.ts +5 -0
- package/dist/lib/components/pagination/index.d.ts.map +1 -0
- package/dist/lib/components/pagination/index.js +20 -0
- package/{src → dist}/lib/components/rows/data-table-row.d.ts +15 -2
- package/dist/lib/components/rows/data-table-row.d.ts.map +1 -0
- package/{src → dist}/lib/components/rows/data-table-row.js +58 -25
- package/{src → dist}/lib/components/rows/empty-data-row.d.ts +3 -3
- package/dist/lib/components/rows/empty-data-row.d.ts.map +1 -0
- package/{src → dist}/lib/components/rows/empty-data-row.js +12 -4
- package/dist/lib/components/rows/index.d.ts +7 -0
- package/dist/lib/components/rows/index.d.ts.map +1 -0
- package/dist/lib/components/rows/index.js +22 -0
- package/{src → dist}/lib/components/rows/loading-rows.d.ts +3 -1
- package/dist/lib/components/rows/loading-rows.d.ts.map +1 -0
- package/{src → dist}/lib/components/rows/loading-rows.js +27 -19
- package/{src → dist}/lib/components/toolbar/bulk-actions-toolbar.d.ts +4 -3
- package/dist/lib/components/toolbar/bulk-actions-toolbar.d.ts.map +1 -0
- package/dist/lib/components/toolbar/bulk-actions-toolbar.js +49 -0
- package/{src → dist}/lib/components/toolbar/column-filter-control.d.ts +3 -1
- package/dist/lib/components/toolbar/column-filter-control.d.ts.map +1 -0
- package/{src → dist}/lib/components/toolbar/column-filter-control.js +73 -4
- package/{src → dist}/lib/components/toolbar/column-pinning-control.d.ts +2 -1
- package/dist/lib/components/toolbar/column-pinning-control.d.ts.map +1 -0
- package/{src → dist}/lib/components/toolbar/column-pinning-control.js +70 -6
- package/{src → dist}/lib/components/toolbar/column-reset-control.d.ts +3 -1
- package/dist/lib/components/toolbar/column-reset-control.d.ts.map +1 -0
- package/{src → dist}/lib/components/toolbar/column-reset-control.js +9 -2
- package/{src → dist}/lib/components/toolbar/column-visibility-control.d.ts +2 -1
- package/dist/lib/components/toolbar/column-visibility-control.d.ts.map +1 -0
- package/dist/lib/components/toolbar/column-visibility-control.js +77 -0
- package/{src → dist}/lib/components/toolbar/data-table-toolbar.d.ts +3 -2
- package/dist/lib/components/toolbar/data-table-toolbar.d.ts.map +1 -0
- package/{src → dist}/lib/components/toolbar/data-table-toolbar.js +17 -4
- package/{src → dist}/lib/components/toolbar/index.d.ts +4 -0
- package/dist/lib/components/toolbar/index.d.ts.map +1 -0
- package/{src → dist}/lib/components/toolbar/index.js +6 -0
- package/dist/lib/components/toolbar/table-export-control.d.ts +12 -0
- package/dist/lib/components/toolbar/table-export-control.d.ts.map +1 -0
- package/dist/lib/components/toolbar/table-export-control.js +67 -0
- package/{src → dist}/lib/components/toolbar/table-search-control.d.ts +3 -1
- package/dist/lib/components/toolbar/table-search-control.d.ts.map +1 -0
- package/{src → dist}/lib/components/toolbar/table-search-control.js +45 -2
- package/{src → dist}/lib/components/toolbar/table-size-control.d.ts +3 -1
- package/dist/lib/components/toolbar/table-size-control.d.ts.map +1 -0
- package/{src → dist}/lib/components/toolbar/table-size-control.js +20 -8
- package/{src → dist}/lib/contexts/data-table-context.d.ts +6 -2
- package/dist/lib/contexts/data-table-context.d.ts.map +1 -0
- package/{src → dist}/lib/contexts/data-table-context.js +34 -1
- package/dist/lib/data-table.d.ts +5 -0
- package/dist/lib/data-table.d.ts.map +1 -0
- package/{src/lib/components/table → dist/lib}/data-table.js +427 -143
- package/dist/lib/features/column-filter.feature.d.ts +55 -0
- package/dist/lib/features/column-filter.feature.d.ts.map +1 -0
- package/{src → dist}/lib/features/column-filter.feature.js +116 -18
- package/dist/lib/features/index.d.ts +9 -0
- package/dist/lib/features/index.d.ts.map +1 -0
- package/{src → dist}/lib/features/index.js +7 -0
- package/{src → dist}/lib/features/selection.feature.d.ts +8 -1
- package/dist/lib/features/selection.feature.d.ts.map +1 -0
- package/{src → dist}/lib/features/selection.feature.js +76 -15
- package/dist/lib/icons/add-icon.d.ts +4 -0
- package/dist/lib/icons/add-icon.d.ts.map +1 -0
- package/dist/lib/icons/add-icon.js +12 -0
- package/dist/lib/icons/csv-icon.d.ts +4 -0
- package/dist/lib/icons/csv-icon.d.ts.map +1 -0
- package/dist/lib/icons/csv-icon.js +12 -0
- package/dist/lib/icons/delete-icon.d.ts +4 -0
- package/dist/lib/icons/delete-icon.d.ts.map +1 -0
- package/dist/lib/icons/delete-icon.js +12 -0
- package/dist/lib/icons/excel-icon.d.ts +4 -0
- package/dist/lib/icons/excel-icon.d.ts.map +1 -0
- package/dist/lib/icons/excel-icon.js +12 -0
- package/dist/lib/icons/index.d.ts +8 -0
- package/dist/lib/icons/index.d.ts.map +1 -0
- package/dist/lib/icons/unpin-icon.d.ts +4 -0
- package/dist/lib/icons/unpin-icon.d.ts.map +1 -0
- package/dist/lib/icons/unpin-icon.js +12 -0
- package/{src → dist}/lib/icons/view-comfortable-icon.d.ts +3 -1
- package/dist/lib/icons/view-comfortable-icon.d.ts.map +1 -0
- package/dist/lib/icons/view-comfortable-icon.js +12 -0
- package/dist/lib/icons/view-compact-icon.d.ts +4 -0
- package/dist/lib/icons/view-compact-icon.d.ts.map +1 -0
- package/dist/lib/icons/view-compact-icon.js +12 -0
- package/{src → dist}/lib/types/column.types.d.ts +10 -1
- package/dist/lib/types/column.types.d.ts.map +1 -0
- package/{src → dist}/lib/types/data-table-api.d.ts +2 -1
- package/dist/lib/types/data-table-api.d.ts.map +1 -0
- package/{src/lib/components/table → dist/lib/types}/data-table.types.d.ts +10 -11
- package/dist/lib/types/data-table.types.d.ts.map +1 -0
- package/{src → dist}/lib/types/export.types.d.ts +38 -0
- package/dist/lib/types/export.types.d.ts.map +1 -0
- package/dist/lib/types/export.types.js +6 -0
- package/{src → dist}/lib/types/index.d.ts +6 -0
- package/dist/lib/types/index.d.ts.map +1 -0
- package/dist/lib/types/index.js +32 -0
- package/{src → dist}/lib/types/slots.types.d.ts +50 -3
- package/dist/lib/types/slots.types.d.ts.map +1 -0
- package/{src → dist}/lib/types/table.types.d.ts +14 -0
- package/dist/lib/types/table.types.d.ts.map +1 -0
- package/{src → dist}/lib/utils/column-helpers.d.ts +10 -0
- package/dist/lib/utils/column-helpers.d.ts.map +1 -0
- package/{src → dist}/lib/utils/column-helpers.js +20 -4
- package/{src → dist}/lib/utils/debounced-fetch.utils.d.ts +3 -5
- package/dist/lib/utils/debounced-fetch.utils.d.ts.map +1 -0
- package/{src → dist}/lib/utils/debounced-fetch.utils.js +12 -6
- package/{src → dist}/lib/utils/export-utils.d.ts +13 -0
- package/dist/lib/utils/export-utils.d.ts.map +1 -0
- package/dist/lib/utils/export-utils.js +252 -0
- package/{src → dist}/lib/utils/index.d.ts +4 -0
- package/dist/lib/utils/index.d.ts.map +1 -0
- package/dist/lib/utils/index.js +35 -0
- package/{src → dist}/lib/utils/logger.d.ts +43 -0
- package/dist/lib/utils/logger.d.ts.map +1 -0
- package/{src → dist}/lib/utils/logger.js +22 -2
- package/{src → dist}/lib/utils/slot-helpers.d.ts +39 -1
- package/dist/lib/utils/slot-helpers.d.ts.map +1 -0
- package/{src → dist}/lib/utils/slot-helpers.js +55 -6
- package/{src → dist}/lib/utils/special-columns.utils.d.ts +10 -0
- package/dist/lib/utils/special-columns.utils.d.ts.map +1 -0
- package/{src → dist}/lib/utils/special-columns.utils.js +41 -5
- package/{src → dist}/lib/utils/styling-helpers.d.ts +20 -0
- package/dist/lib/utils/styling-helpers.d.ts.map +1 -0
- package/dist/lib/utils/styling-helpers.js +108 -0
- package/{src → dist}/lib/utils/table-helpers.d.ts +25 -0
- package/dist/lib/utils/table-helpers.d.ts.map +1 -0
- package/{src → dist}/lib/utils/table-helpers.js +24 -0
- package/package.json +36 -11
- package/src/index.ts +71 -0
- package/src/lib/components/droupdown/menu-dropdown.tsx +97 -0
- package/src/lib/components/filters/filter-value-input.tsx +225 -0
- package/src/lib/components/filters/{index.js → index.ts} +3 -6
- package/src/lib/components/headers/draggable-header.tsx +326 -0
- package/src/lib/components/headers/{index.d.ts → index.ts} +4 -0
- package/src/lib/components/headers/table-header.tsx +173 -0
- package/src/lib/components/index.ts +21 -0
- package/src/lib/components/pagination/data-table-pagination.tsx +99 -0
- package/src/lib/components/pagination/index.ts +5 -0
- package/src/lib/components/rows/data-table-row.tsx +208 -0
- package/src/lib/components/rows/empty-data-row.tsx +69 -0
- package/src/lib/components/rows/{index.d.ts → index.ts} +4 -0
- package/src/lib/components/rows/loading-rows.tsx +160 -0
- package/src/lib/components/toolbar/bulk-actions-toolbar.tsx +125 -0
- package/src/lib/components/toolbar/column-filter-control.tsx +374 -0
- package/src/lib/components/toolbar/column-pinning-control.tsx +275 -0
- package/src/lib/components/toolbar/column-reset-control.tsx +74 -0
- package/src/lib/components/toolbar/column-visibility-control.tsx +105 -0
- package/src/lib/components/toolbar/data-table-toolbar.tsx +229 -0
- package/src/lib/components/toolbar/index.ts +17 -0
- package/src/lib/components/toolbar/table-export-control.tsx +179 -0
- package/src/lib/components/toolbar/table-search-control.tsx +155 -0
- package/src/lib/components/toolbar/table-size-control.tsx +102 -0
- package/src/lib/contexts/data-table-context.tsx +112 -0
- package/src/lib/data-table.tsx +1911 -0
- package/src/lib/features/README.md +161 -0
- package/src/lib/features/column-filter.feature.ts +456 -0
- package/src/lib/features/index.ts +23 -0
- package/src/lib/features/selection.feature.ts +318 -0
- package/src/lib/icons/add-icon.tsx +23 -0
- package/src/lib/icons/csv-icon.tsx +15 -0
- package/src/lib/icons/delete-icon.tsx +30 -0
- package/src/lib/icons/excel-icon.tsx +15 -0
- package/src/lib/icons/unpin-icon.tsx +18 -0
- package/src/lib/icons/view-comfortable-icon.tsx +45 -0
- package/src/lib/icons/view-compact-icon.tsx +55 -0
- package/src/lib/types/column.types.ts +44 -0
- package/src/lib/types/data-table-api.ts +169 -0
- package/src/lib/types/data-table.types.ts +136 -0
- package/src/lib/types/export.types.ts +154 -0
- package/src/lib/types/index.ts +24 -0
- package/src/lib/types/slots.types.ts +332 -0
- package/src/lib/types/table.types.ts +90 -0
- package/src/lib/utils/column-helpers.ts +72 -0
- package/src/lib/utils/debounced-fetch.utils.ts +54 -0
- package/src/lib/utils/export-utils.ts +285 -0
- package/src/lib/utils/index.ts +27 -0
- package/src/lib/utils/logger.ts +203 -0
- package/src/lib/utils/slot-helpers.tsx +194 -0
- package/src/lib/utils/special-columns.utils.ts +94 -0
- package/src/lib/utils/styling-helpers.ts +126 -0
- package/src/lib/utils/table-helpers.ts +106 -0
- package/src/index.js +0 -27
- package/src/lib/components/filters/filter-value-input.js +0 -41
- package/src/lib/components/headers/index.js +0 -5
- package/src/lib/components/index.js +0 -10
- package/src/lib/components/pagination/index.d.ts +0 -1
- package/src/lib/components/pagination/index.js +0 -4
- package/src/lib/components/rows/index.js +0 -6
- package/src/lib/components/table/data-table.d.ts +0 -4
- package/src/lib/components/table/index.d.ts +0 -2
- package/src/lib/components/table/index.js +0 -5
- package/src/lib/components/toolbar/bulk-actions-toolbar.js +0 -30
- package/src/lib/components/toolbar/column-visibility-control.js +0 -31
- package/src/lib/components/toolbar/table-export-control.d.ts +0 -31
- package/src/lib/components/toolbar/table-export-control.js +0 -56
- package/src/lib/examples/advanced-features-example.d.ts +0 -1
- package/src/lib/examples/advanced-features-example.js +0 -269
- package/src/lib/examples/bulk-actions-test.d.ts +0 -1
- package/src/lib/examples/bulk-actions-test.js +0 -44
- package/src/lib/examples/custom-column-filter-example.d.ts +0 -1
- package/src/lib/examples/custom-column-filter-example.js +0 -60
- package/src/lib/examples/index.d.ts +0 -8
- package/src/lib/examples/index.js +0 -19
- package/src/lib/examples/selection-test-example.d.ts +0 -1
- package/src/lib/examples/selection-test-example.js +0 -101
- package/src/lib/examples/server-side-fetching-example.d.ts +0 -1
- package/src/lib/examples/server-side-fetching-example.js +0 -245
- package/src/lib/examples/server-side-test.d.ts +0 -1
- package/src/lib/examples/server-side-test.js +0 -9
- package/src/lib/examples/simple-local-example.d.ts +0 -1
- package/src/lib/examples/simple-local-example.js +0 -95
- package/src/lib/examples/simple-slots-example.d.ts +0 -1
- package/src/lib/examples/simple-slots-example.js +0 -115
- package/src/lib/features/column-filter.feature.d.ts +0 -45
- package/src/lib/features/index.d.ts +0 -2
- package/src/lib/hooks/index.d.ts +0 -1
- package/src/lib/hooks/index.js +0 -4
- package/src/lib/hooks/use-data-table-api.d.ts +0 -46
- package/src/lib/hooks/use-data-table-api.js +0 -690
- package/src/lib/icons/add-icon.d.ts +0 -2
- package/src/lib/icons/add-icon.js +0 -8
- package/src/lib/icons/csv-icon.d.ts +0 -2
- package/src/lib/icons/csv-icon.js +0 -8
- package/src/lib/icons/delete-icon.d.ts +0 -2
- package/src/lib/icons/delete-icon.js +0 -8
- package/src/lib/icons/excel-icon.d.ts +0 -2
- package/src/lib/icons/excel-icon.js +0 -8
- package/src/lib/icons/unpin-icon.d.ts +0 -2
- package/src/lib/icons/unpin-icon.js +0 -8
- package/src/lib/icons/view-comfortable-icon.js +0 -8
- package/src/lib/icons/view-compact-icon.d.ts +0 -2
- package/src/lib/icons/view-compact-icon.js +0 -8
- package/src/lib/types/export.types.js +0 -2
- package/src/lib/types/index.js +0 -8
- package/src/lib/utils/export-utils.js +0 -175
- package/src/lib/utils/index.js +0 -11
- package/src/lib/utils/styling-helpers.js +0 -70
- package/tsconfig.tsbuildinfo +0 -1
- /package/{src → dist}/lib/icons/index.js +0 -0
- /package/{src → dist}/lib/types/column.types.js +0 -0
- /package/{src → dist}/lib/types/data-table-api.js +0 -0
- /package/{src/lib/components/table → dist/lib/types}/data-table.types.js +0 -0
- /package/{src → dist}/lib/types/slots.types.js +0 -0
- /package/{src → dist}/lib/types/table.types.js +0 -0
- /package/src/lib/icons/{index.d.ts → index.ts} +0 -0
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* TableHeader Component
|
|
3
|
+
*
|
|
4
|
+
* Unified header component that combines:
|
|
5
|
+
* - Sortable functionality
|
|
6
|
+
* - Draggable column reordering
|
|
7
|
+
* - Column resizing
|
|
8
|
+
* - Pinning support
|
|
9
|
+
*/
|
|
10
|
+
import React, { ReactElement } from 'react';
|
|
11
|
+
import { TableHead, TableRow, TableCell, Box, useTheme, TableHeadProps, TableRowProps, TableCellProps, SxProps } from '@mui/material';
|
|
12
|
+
import { Header } from '@tanstack/react-table';
|
|
13
|
+
|
|
14
|
+
import { DraggableHeader } from './draggable-header';
|
|
15
|
+
import { useDataTableContext } from '../../contexts/data-table-context';
|
|
16
|
+
import { getPinnedColumnStyle, getColumnAlignment } from '../../utils';
|
|
17
|
+
import { getSlotComponent, mergeSlotProps, extractSlotProps } from '../../utils/slot-helpers';
|
|
18
|
+
|
|
19
|
+
export interface TableHeaderProps extends TableHeadProps {
|
|
20
|
+
draggable?: boolean;
|
|
21
|
+
enableColumnResizing?: boolean;
|
|
22
|
+
enableStickyHeader?: boolean;
|
|
23
|
+
fitToScreen?: boolean;
|
|
24
|
+
onColumnReorder?: (draggedColumnId: string, targetColumnId: string) => void;
|
|
25
|
+
// Enhanced customization props
|
|
26
|
+
headerRowProps?: TableRowProps;
|
|
27
|
+
headerCellProps?: TableCellProps;
|
|
28
|
+
containerSx?: SxProps;
|
|
29
|
+
resizeHandleSx?: SxProps;
|
|
30
|
+
slots?: Record<string, any>;
|
|
31
|
+
slotProps?: Record<string, any>;
|
|
32
|
+
[key: string]: any;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Renders table headers with sorting, dragging, and resizing capabilities
|
|
37
|
+
*/
|
|
38
|
+
export function TableHeader<T>(props: TableHeaderProps): ReactElement {
|
|
39
|
+
const {
|
|
40
|
+
draggable = false,
|
|
41
|
+
enableColumnResizing = false,
|
|
42
|
+
enableStickyHeader = false,
|
|
43
|
+
fitToScreen = true,
|
|
44
|
+
onColumnReorder,
|
|
45
|
+
headerRowProps,
|
|
46
|
+
headerCellProps,
|
|
47
|
+
containerSx,
|
|
48
|
+
resizeHandleSx,
|
|
49
|
+
slots,
|
|
50
|
+
slotProps,
|
|
51
|
+
...otherProps
|
|
52
|
+
} = props;
|
|
53
|
+
|
|
54
|
+
const theme = useTheme();
|
|
55
|
+
const { table } = useDataTableContext();
|
|
56
|
+
|
|
57
|
+
// Extract slot-specific props with enhanced merging
|
|
58
|
+
const headerCellSlotProps = extractSlotProps(slotProps, 'headerCell');
|
|
59
|
+
const headerRowSlotProps = extractSlotProps(slotProps, 'headerRow');
|
|
60
|
+
const headerSlotProps = extractSlotProps(slotProps, 'header');
|
|
61
|
+
|
|
62
|
+
const HeaderCellSlot = getSlotComponent(slots, 'headerCell', TableCell);
|
|
63
|
+
const HeaderRowSlot = getSlotComponent(slots, 'headerRow', TableRow);
|
|
64
|
+
const HeaderSlot = getSlotComponent(slots, 'header', TableHead);
|
|
65
|
+
|
|
66
|
+
// Merge all props for maximum flexibility
|
|
67
|
+
const mergedHeaderProps = mergeSlotProps(
|
|
68
|
+
{
|
|
69
|
+
sx: containerSx,
|
|
70
|
+
},
|
|
71
|
+
headerSlotProps,
|
|
72
|
+
otherProps
|
|
73
|
+
);
|
|
74
|
+
|
|
75
|
+
const mergedHeaderRowProps = mergeSlotProps(
|
|
76
|
+
{},
|
|
77
|
+
headerRowSlotProps,
|
|
78
|
+
headerRowProps || {}
|
|
79
|
+
);
|
|
80
|
+
|
|
81
|
+
const renderHeaderCell = (header: Header<T, unknown>) => {
|
|
82
|
+
const isPinned = header.column.getIsPinned();
|
|
83
|
+
const pinnedPosition = isPinned ? header.column.getStart('left') : undefined;
|
|
84
|
+
const pinnedRightPosition = isPinned === 'right' ? header.column.getAfter('right') : undefined;
|
|
85
|
+
const alignment = getColumnAlignment(header.column.columnDef);
|
|
86
|
+
const enableSorting = header.column.getCanSort();
|
|
87
|
+
const wrapText = header.column.columnDef.wrapText ?? false;
|
|
88
|
+
const canResize = enableColumnResizing && header.column.getCanResize();
|
|
89
|
+
|
|
90
|
+
const mergedHeaderCellProps = mergeSlotProps(
|
|
91
|
+
{
|
|
92
|
+
align: alignment,
|
|
93
|
+
sx: {
|
|
94
|
+
...getPinnedColumnStyle({
|
|
95
|
+
width: (fitToScreen && !enableColumnResizing) ? 'auto' : header.getSize(),
|
|
96
|
+
isPinned,
|
|
97
|
+
pinnedPosition,
|
|
98
|
+
isLastLeftPinnedColumn: isPinned === 'left' && header.column.getIsLastColumn('left'),
|
|
99
|
+
isFirstRightPinnedColumn: isPinned === 'right' && header.column.getIsFirstColumn('right'),
|
|
100
|
+
pinnedRightPosition,
|
|
101
|
+
zIndex: isPinned ? 10 : 1,
|
|
102
|
+
disableStickyHeader: enableStickyHeader,
|
|
103
|
+
wrapText,
|
|
104
|
+
}),
|
|
105
|
+
},
|
|
106
|
+
},
|
|
107
|
+
headerCellSlotProps,
|
|
108
|
+
headerCellProps || {}
|
|
109
|
+
);
|
|
110
|
+
|
|
111
|
+
const mergedResizeHandleProps = mergeSlotProps(
|
|
112
|
+
{
|
|
113
|
+
onMouseDown: header.getResizeHandler(),
|
|
114
|
+
onTouchStart: header.getResizeHandler(),
|
|
115
|
+
sx: {
|
|
116
|
+
position: 'absolute',
|
|
117
|
+
right: 0,
|
|
118
|
+
top: '25%',
|
|
119
|
+
height: '50%',
|
|
120
|
+
width: '3px',
|
|
121
|
+
cursor: 'col-resize',
|
|
122
|
+
userSelect: 'none',
|
|
123
|
+
touchAction: 'none',
|
|
124
|
+
borderRadius: '4px',
|
|
125
|
+
backgroundColor: header.column.getIsResizing() ? 'primary.main' : theme.palette.grey[300],
|
|
126
|
+
'&:hover': {
|
|
127
|
+
backgroundColor: theme.palette.primary.main,
|
|
128
|
+
},
|
|
129
|
+
...resizeHandleSx,
|
|
130
|
+
},
|
|
131
|
+
}
|
|
132
|
+
);
|
|
133
|
+
|
|
134
|
+
return (
|
|
135
|
+
<HeaderCellSlot
|
|
136
|
+
key={header.id}
|
|
137
|
+
{...mergedHeaderCellProps}
|
|
138
|
+
>
|
|
139
|
+
<DraggableHeader
|
|
140
|
+
header={header}
|
|
141
|
+
enableSorting={enableSorting}
|
|
142
|
+
draggable={!!(draggable && !isPinned)}
|
|
143
|
+
onColumnReorder={onColumnReorder}
|
|
144
|
+
slots={slots}
|
|
145
|
+
slotProps={slotProps}
|
|
146
|
+
alignment={alignment}
|
|
147
|
+
/>
|
|
148
|
+
|
|
149
|
+
{/* Column resizer */}
|
|
150
|
+
{canResize ? (
|
|
151
|
+
<Box
|
|
152
|
+
{...mergedResizeHandleProps}
|
|
153
|
+
/>
|
|
154
|
+
) : null}
|
|
155
|
+
</HeaderCellSlot>
|
|
156
|
+
);
|
|
157
|
+
};
|
|
158
|
+
|
|
159
|
+
return (
|
|
160
|
+
<HeaderSlot
|
|
161
|
+
{...mergedHeaderProps}
|
|
162
|
+
>
|
|
163
|
+
{table.getHeaderGroups().map(headerGroup => (
|
|
164
|
+
<HeaderRowSlot
|
|
165
|
+
key={headerGroup.id}
|
|
166
|
+
{...mergedHeaderRowProps}
|
|
167
|
+
>
|
|
168
|
+
{headerGroup.headers.map(renderHeaderCell)}
|
|
169
|
+
</HeaderRowSlot>
|
|
170
|
+
))}
|
|
171
|
+
</HeaderSlot>
|
|
172
|
+
);
|
|
173
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* DataTable Components
|
|
3
|
+
*
|
|
4
|
+
* Organized component exports for the MUI TanStack DataTable
|
|
5
|
+
*/
|
|
6
|
+
// Header components
|
|
7
|
+
export * from './headers';
|
|
8
|
+
|
|
9
|
+
// Row components
|
|
10
|
+
export * from './rows';
|
|
11
|
+
|
|
12
|
+
// Toolbar components
|
|
13
|
+
export * from './toolbar';
|
|
14
|
+
|
|
15
|
+
// Filter components
|
|
16
|
+
export * from './filters';
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
// Pagination components
|
|
20
|
+
export * from './pagination';
|
|
21
|
+
export * from './droupdown/menu-dropdown';
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
// data-table-pagination.tsx
|
|
2
|
+
import { TablePagination, Box, TablePaginationProps, SxProps } from '@mui/material';
|
|
3
|
+
import { memo, ReactNode } from 'react';
|
|
4
|
+
|
|
5
|
+
import { useDataTableContext } from '../../contexts/data-table-context';
|
|
6
|
+
import { mergeSlotProps } from '../../utils/slot-helpers';
|
|
7
|
+
|
|
8
|
+
export interface DataTablePaginationProps extends Omit<TablePaginationProps, 'count' | 'rowsPerPage' | 'page' | 'onPageChange' | 'onRowsPerPageChange'> {
|
|
9
|
+
totalRow: number;
|
|
10
|
+
footerFilter?: ReactNode | null;
|
|
11
|
+
pagination: {
|
|
12
|
+
pageIndex: number;
|
|
13
|
+
pageSize: number;
|
|
14
|
+
};
|
|
15
|
+
// Enhanced customization props
|
|
16
|
+
containerSx?: SxProps;
|
|
17
|
+
paginationProps?: TablePaginationProps;
|
|
18
|
+
footerSx?: SxProps;
|
|
19
|
+
slots?: Record<string, any>;
|
|
20
|
+
slotProps?: Record<string, any>;
|
|
21
|
+
[key: string]: any;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export const DataTablePagination = memo((props: DataTablePaginationProps) => {
|
|
25
|
+
const {
|
|
26
|
+
footerFilter = null,
|
|
27
|
+
pagination,
|
|
28
|
+
totalRow,
|
|
29
|
+
containerSx,
|
|
30
|
+
paginationProps,
|
|
31
|
+
footerSx,
|
|
32
|
+
...otherProps
|
|
33
|
+
} = props;
|
|
34
|
+
|
|
35
|
+
const { table, tableSize } = useDataTableContext();
|
|
36
|
+
|
|
37
|
+
// Extract slot-specific props with enhanced merging
|
|
38
|
+
// const paginationSlotProps = extractSlotProps(slotProps, 'pagination');
|
|
39
|
+
|
|
40
|
+
// Merge all props for maximum flexibility
|
|
41
|
+
const mergedContainerProps = mergeSlotProps(
|
|
42
|
+
{
|
|
43
|
+
sx: {
|
|
44
|
+
display: 'flex',
|
|
45
|
+
alignItems: 'center',
|
|
46
|
+
gap: 1,
|
|
47
|
+
justifyContent: 'space-between',
|
|
48
|
+
px: 2,
|
|
49
|
+
...containerSx,
|
|
50
|
+
},
|
|
51
|
+
}
|
|
52
|
+
);
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
const mergedPaginationProps: any = mergeSlotProps(
|
|
57
|
+
{
|
|
58
|
+
component: 'div',
|
|
59
|
+
size: tableSize === 'small' ? 'small' : 'medium',
|
|
60
|
+
count: totalRow,
|
|
61
|
+
rowsPerPage: pagination?.pageSize,
|
|
62
|
+
page: pagination?.pageIndex,
|
|
63
|
+
onPageChange: (_, page: number) => {
|
|
64
|
+
// Use TanStack Table's native pagination methods
|
|
65
|
+
table.setPageIndex(page);
|
|
66
|
+
},
|
|
67
|
+
onRowsPerPageChange: (e: React.ChangeEvent<HTMLInputElement>) => {
|
|
68
|
+
const newPageSize = Number(e.target.value);
|
|
69
|
+
// Use TanStack Table's native pagination methods
|
|
70
|
+
table.setPageIndex(0);
|
|
71
|
+
table.setPageSize(newPageSize);
|
|
72
|
+
},
|
|
73
|
+
showFirstButton: true,
|
|
74
|
+
showLastButton: true,
|
|
75
|
+
labelRowsPerPage: 'Rows per page:',
|
|
76
|
+
labelDisplayedRows: ({ from, to, count }: { from: number; to: number; count: number }) =>
|
|
77
|
+
`${from}–${to} of ${count !== -1 ? count : `more than ${to}`}`,
|
|
78
|
+
},
|
|
79
|
+
{ ...paginationProps, ...otherProps }
|
|
80
|
+
);
|
|
81
|
+
|
|
82
|
+
return (
|
|
83
|
+
<Box
|
|
84
|
+
{...mergedContainerProps}
|
|
85
|
+
>
|
|
86
|
+
{footerFilter && (
|
|
87
|
+
<Box sx={footerSx}>
|
|
88
|
+
{footerFilter as any}
|
|
89
|
+
</Box>
|
|
90
|
+
)}
|
|
91
|
+
|
|
92
|
+
<TablePagination
|
|
93
|
+
{...mergedPaginationProps}
|
|
94
|
+
/>
|
|
95
|
+
</Box>
|
|
96
|
+
);
|
|
97
|
+
});
|
|
98
|
+
|
|
99
|
+
DataTablePagination.displayName = 'DataTablePagination';
|
|
@@ -0,0 +1,208 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* DataTableRow Component
|
|
3
|
+
*
|
|
4
|
+
* Renders individual table rows with support for:
|
|
5
|
+
* - Column pinning
|
|
6
|
+
* - Row expansion
|
|
7
|
+
* - Hover effects
|
|
8
|
+
* - Striped styling
|
|
9
|
+
*/
|
|
10
|
+
import { TableRow, TableCell, Collapse, TableRowProps, TableCellProps, SxProps, tableRowClasses } from '@mui/material';
|
|
11
|
+
import { flexRender, Row } from '@tanstack/react-table';
|
|
12
|
+
import { ReactNode, ReactElement } from 'react';
|
|
13
|
+
|
|
14
|
+
import { getPinnedColumnStyle, getColumnAlignment } from '../../utils';
|
|
15
|
+
import { getSlotComponent, mergeSlotProps, extractSlotProps } from '../../utils/slot-helpers';
|
|
16
|
+
import { useDataTableContext } from '../../contexts/data-table-context';
|
|
17
|
+
|
|
18
|
+
export interface DataTableRowProps<T> extends TableRowProps {
|
|
19
|
+
row: Row<T>;
|
|
20
|
+
enableHover?: boolean;
|
|
21
|
+
enableStripes?: boolean;
|
|
22
|
+
isOdd?: boolean;
|
|
23
|
+
renderSubComponent?: (row: Row<T>) => ReactNode;
|
|
24
|
+
disableStickyHeader?: boolean;
|
|
25
|
+
// Row click props
|
|
26
|
+
onRowClick?: (event: React.MouseEvent<HTMLTableRowElement>, row: Row<T>) => void;
|
|
27
|
+
selectOnRowClick?: boolean; // If true, row click will toggle selection (default: false)
|
|
28
|
+
// Enhanced customization props
|
|
29
|
+
cellProps?: TableCellProps;
|
|
30
|
+
expandedRowProps?: TableRowProps;
|
|
31
|
+
expandedCellProps?: TableCellProps;
|
|
32
|
+
containerSx?: SxProps;
|
|
33
|
+
expandedContainerSx?: SxProps;
|
|
34
|
+
// Cell slot management
|
|
35
|
+
slots?: Record<string, any>;
|
|
36
|
+
slotProps?: Record<string, any>;
|
|
37
|
+
[key: string]: any;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Individual table row component with cell rendering and expansion support
|
|
42
|
+
*/
|
|
43
|
+
export function DataTableRow<T>(props: DataTableRowProps<T>): ReactElement {
|
|
44
|
+
const {
|
|
45
|
+
row,
|
|
46
|
+
enableHover = true,
|
|
47
|
+
enableStripes = false,
|
|
48
|
+
isOdd = false,
|
|
49
|
+
renderSubComponent,
|
|
50
|
+
disableStickyHeader = false,
|
|
51
|
+
onRowClick,
|
|
52
|
+
selectOnRowClick = false,
|
|
53
|
+
cellProps,
|
|
54
|
+
expandedRowProps,
|
|
55
|
+
expandedCellProps,
|
|
56
|
+
containerSx,
|
|
57
|
+
expandedContainerSx,
|
|
58
|
+
slots,
|
|
59
|
+
slotProps,
|
|
60
|
+
...otherProps
|
|
61
|
+
} = props;
|
|
62
|
+
const { table } = useDataTableContext();
|
|
63
|
+
|
|
64
|
+
// Extract slot-specific props with enhanced merging
|
|
65
|
+
const cellSlotProps = extractSlotProps(slotProps, 'cell');
|
|
66
|
+
const expandedRowSlotProps = extractSlotProps(slotProps, 'expandedRow');
|
|
67
|
+
const rowSlotProps = extractSlotProps(slotProps, 'row');
|
|
68
|
+
|
|
69
|
+
const CellSlot = getSlotComponent(slots, 'cell', TableCell);
|
|
70
|
+
const ExpandedRowSlot = getSlotComponent(slots, 'expandedRow', TableRow);
|
|
71
|
+
const TableRowSlot = getSlotComponent(slots, 'row', TableRow);
|
|
72
|
+
|
|
73
|
+
// Handle row click
|
|
74
|
+
const handleRowClick = (event: React.MouseEvent<HTMLTableRowElement>) => {
|
|
75
|
+
// Check if click target is a checkbox, button, or interactive element
|
|
76
|
+
const target = event.target as HTMLElement;
|
|
77
|
+
const isCheckboxClick = target.closest('input[type="checkbox"]') !== null;
|
|
78
|
+
const isButtonClick = target.closest('button') !== null;
|
|
79
|
+
const isLinkClick = target.closest('a') !== null;
|
|
80
|
+
|
|
81
|
+
// If selectOnRowClick is enabled and it's not a checkbox/interactive element click, toggle selection
|
|
82
|
+
if (selectOnRowClick && !isCheckboxClick && !isButtonClick && !isLinkClick && table?.toggleRowSelected) {
|
|
83
|
+
table.toggleRowSelected(row.id);
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
// Always call onRowClick if provided
|
|
87
|
+
if (onRowClick) {
|
|
88
|
+
onRowClick(event, row);
|
|
89
|
+
}
|
|
90
|
+
};
|
|
91
|
+
|
|
92
|
+
// Merge all props for maximum flexibility
|
|
93
|
+
const mergedRowProps = mergeSlotProps(
|
|
94
|
+
{
|
|
95
|
+
hover: enableHover,
|
|
96
|
+
selected: !!table?.getIsRowSelected?.(row.id),
|
|
97
|
+
onClick: (onRowClick || selectOnRowClick) ? handleRowClick : undefined,
|
|
98
|
+
sx: (theme) => ({
|
|
99
|
+
// set the row background as a variable
|
|
100
|
+
'--row-bg': enableStripes && isOdd
|
|
101
|
+
? theme.palette.action.hover
|
|
102
|
+
: theme.palette.background.paper,
|
|
103
|
+
backgroundColor: 'var(--row-bg)',
|
|
104
|
+
// keep the variable in sync for hover/selected
|
|
105
|
+
...(enableHover && {
|
|
106
|
+
'&:hover': { '--row-bg': theme.palette.action.hover },
|
|
107
|
+
}),
|
|
108
|
+
[`&.${tableRowClasses.selected}`]: {
|
|
109
|
+
'--row-bg': theme.palette.action.selected,
|
|
110
|
+
backgroundColor: 'var(--row-bg)',
|
|
111
|
+
},
|
|
112
|
+
// Add cursor pointer if row is clickable
|
|
113
|
+
...((onRowClick || selectOnRowClick) && {
|
|
114
|
+
cursor: 'pointer',
|
|
115
|
+
}),
|
|
116
|
+
...containerSx,
|
|
117
|
+
}),
|
|
118
|
+
},
|
|
119
|
+
rowSlotProps,
|
|
120
|
+
otherProps
|
|
121
|
+
);
|
|
122
|
+
const mergedExpandedRowProps = mergeSlotProps(
|
|
123
|
+
{
|
|
124
|
+
sx: expandedContainerSx,
|
|
125
|
+
},
|
|
126
|
+
expandedRowSlotProps,
|
|
127
|
+
expandedRowProps || {}
|
|
128
|
+
);
|
|
129
|
+
|
|
130
|
+
return (
|
|
131
|
+
<>
|
|
132
|
+
<TableRowSlot
|
|
133
|
+
{...mergedRowProps}
|
|
134
|
+
>
|
|
135
|
+
{row.getVisibleCells().map(cell => {
|
|
136
|
+
const isPinned = cell.column.getIsPinned();
|
|
137
|
+
const pinnedPosition = isPinned ? cell.column.getStart('left') : undefined;
|
|
138
|
+
const pinnedRightPosition = isPinned === 'right' ? cell.column.getAfter('right') : undefined;
|
|
139
|
+
const alignment = getColumnAlignment(cell.column.columnDef);
|
|
140
|
+
|
|
141
|
+
// Get minSize and maxSize from column definition
|
|
142
|
+
const minSize = cell.column.columnDef?.minSize;
|
|
143
|
+
const maxSize = cell.column.columnDef.maxSize;
|
|
144
|
+
const wrapText = cell.column.columnDef.wrapText ?? false;
|
|
145
|
+
|
|
146
|
+
const mergedCellProps = mergeSlotProps(
|
|
147
|
+
{
|
|
148
|
+
align: alignment,
|
|
149
|
+
sx: {
|
|
150
|
+
...getPinnedColumnStyle({
|
|
151
|
+
width: cell.column.getSize() || 'auto',
|
|
152
|
+
minWidth: minSize !== undefined ? minSize : undefined,
|
|
153
|
+
maxWidth: maxSize !== undefined ? maxSize : undefined,
|
|
154
|
+
isPinned,
|
|
155
|
+
pinnedPosition,
|
|
156
|
+
pinnedRightPosition,
|
|
157
|
+
zIndex: isPinned ? 9 : 1,
|
|
158
|
+
disableStickyHeader,
|
|
159
|
+
isLastLeftPinnedColumn: isPinned === 'left' && cell.column.getIsLastColumn('left'),
|
|
160
|
+
isFirstRightPinnedColumn: isPinned === 'right' && cell.column.getIsFirstColumn('right'),
|
|
161
|
+
wrapText,
|
|
162
|
+
}),
|
|
163
|
+
},
|
|
164
|
+
},
|
|
165
|
+
cellSlotProps,
|
|
166
|
+
cellProps || {}
|
|
167
|
+
);
|
|
168
|
+
|
|
169
|
+
return (
|
|
170
|
+
<CellSlot
|
|
171
|
+
key={cell.id}
|
|
172
|
+
{...mergedCellProps}
|
|
173
|
+
>
|
|
174
|
+
{flexRender(cell.column.columnDef.cell, cell.getContext())}
|
|
175
|
+
</CellSlot>
|
|
176
|
+
);
|
|
177
|
+
})}
|
|
178
|
+
</TableRowSlot>
|
|
179
|
+
|
|
180
|
+
{row.getIsExpanded() && renderSubComponent ? (
|
|
181
|
+
<ExpandedRowSlot
|
|
182
|
+
{...mergedExpandedRowProps}
|
|
183
|
+
>
|
|
184
|
+
<CellSlot
|
|
185
|
+
colSpan={row.getVisibleCells().length}
|
|
186
|
+
sx={{
|
|
187
|
+
py: 0,
|
|
188
|
+
...expandedCellProps?.sx,
|
|
189
|
+
}}
|
|
190
|
+
{...mergeSlotProps(
|
|
191
|
+
{},
|
|
192
|
+
cellSlotProps,
|
|
193
|
+
expandedCellProps || {}
|
|
194
|
+
)}
|
|
195
|
+
>
|
|
196
|
+
<Collapse
|
|
197
|
+
in={row.getIsExpanded()}
|
|
198
|
+
timeout="auto"
|
|
199
|
+
unmountOnExit
|
|
200
|
+
>
|
|
201
|
+
{renderSubComponent(row) as any}
|
|
202
|
+
</Collapse>
|
|
203
|
+
</CellSlot>
|
|
204
|
+
</ExpandedRowSlot>
|
|
205
|
+
) : null}
|
|
206
|
+
</>
|
|
207
|
+
);
|
|
208
|
+
}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import { TableCell, TableRow, TableRowProps, TableCellProps, SxProps } from '@mui/material';
|
|
2
|
+
import React, { ReactElement, ReactNode } from 'react';
|
|
3
|
+
import { getSlotComponent, mergeSlotProps, extractSlotProps } from '../../utils/slot-helpers';
|
|
4
|
+
|
|
5
|
+
export interface EmptyDataRowProps {
|
|
6
|
+
colSpan: number;
|
|
7
|
+
message: string | ReactNode;
|
|
8
|
+
// Enhanced customization props
|
|
9
|
+
rowProps?: TableRowProps;
|
|
10
|
+
cellProps?: TableCellProps;
|
|
11
|
+
containerSx?: SxProps;
|
|
12
|
+
messageSx?: SxProps;
|
|
13
|
+
slots?: Record<string, any>;
|
|
14
|
+
slotProps?: Record<string, any>;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export function EmptyDataRow(props: EmptyDataRowProps): ReactElement {
|
|
18
|
+
const {
|
|
19
|
+
colSpan,
|
|
20
|
+
message,
|
|
21
|
+
rowProps,
|
|
22
|
+
cellProps,
|
|
23
|
+
containerSx,
|
|
24
|
+
messageSx,
|
|
25
|
+
slots,
|
|
26
|
+
slotProps,
|
|
27
|
+
} = props;
|
|
28
|
+
|
|
29
|
+
// Extract slot-specific props with enhanced merging
|
|
30
|
+
const emptyRowSlotProps = extractSlotProps(slotProps, 'emptyRow');
|
|
31
|
+
const cellSlotProps = extractSlotProps(slotProps, 'cell');
|
|
32
|
+
|
|
33
|
+
const EmptyRowSlot = getSlotComponent(slots, 'emptyRow', TableRow);
|
|
34
|
+
const EmptyCellSlot = getSlotComponent(slots, 'cell', TableCell);
|
|
35
|
+
|
|
36
|
+
// Merge all props for maximum flexibility
|
|
37
|
+
const mergedRowProps = mergeSlotProps(
|
|
38
|
+
{
|
|
39
|
+
sx: containerSx,
|
|
40
|
+
},
|
|
41
|
+
emptyRowSlotProps,
|
|
42
|
+
rowProps || {}
|
|
43
|
+
);
|
|
44
|
+
|
|
45
|
+
const mergedCellProps = mergeSlotProps(
|
|
46
|
+
{
|
|
47
|
+
colSpan,
|
|
48
|
+
align: 'center',
|
|
49
|
+
sx: {
|
|
50
|
+
py: 4,
|
|
51
|
+
...messageSx,
|
|
52
|
+
},
|
|
53
|
+
},
|
|
54
|
+
cellSlotProps,
|
|
55
|
+
cellProps || {}
|
|
56
|
+
);
|
|
57
|
+
|
|
58
|
+
return (
|
|
59
|
+
<EmptyRowSlot
|
|
60
|
+
{...mergedRowProps}
|
|
61
|
+
>
|
|
62
|
+
<EmptyCellSlot
|
|
63
|
+
{...mergedCellProps}
|
|
64
|
+
>
|
|
65
|
+
{message}
|
|
66
|
+
</EmptyCellSlot>
|
|
67
|
+
</EmptyRowSlot>
|
|
68
|
+
);
|
|
69
|
+
}
|