@ackplus/react-tanstack-data-table 1.1.20 → 1.1.21

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (61) hide show
  1. package/dist/lib/hooks/use-data-table-engine.d.ts.map +1 -1
  2. package/dist/lib/hooks/use-data-table-engine.js +4 -0
  3. package/package.json +3 -4
  4. package/src/index.ts +0 -75
  5. package/src/lib/components/data-table-view.tsx +0 -386
  6. package/src/lib/components/droupdown/menu-dropdown.tsx +0 -103
  7. package/src/lib/components/filters/filter-value-input.tsx +0 -225
  8. package/src/lib/components/filters/index.ts +0 -126
  9. package/src/lib/components/headers/draggable-header.tsx +0 -326
  10. package/src/lib/components/headers/index.ts +0 -6
  11. package/src/lib/components/headers/table-header.tsx +0 -175
  12. package/src/lib/components/index.ts +0 -21
  13. package/src/lib/components/pagination/data-table-pagination.tsx +0 -111
  14. package/src/lib/components/pagination/index.ts +0 -5
  15. package/src/lib/components/rows/data-table-row.tsx +0 -218
  16. package/src/lib/components/rows/empty-data-row.tsx +0 -69
  17. package/src/lib/components/rows/index.ts +0 -7
  18. package/src/lib/components/rows/loading-rows.tsx +0 -164
  19. package/src/lib/components/toolbar/bulk-actions-toolbar.tsx +0 -125
  20. package/src/lib/components/toolbar/column-filter-control.tsx +0 -432
  21. package/src/lib/components/toolbar/column-pinning-control.tsx +0 -275
  22. package/src/lib/components/toolbar/column-reset-control.tsx +0 -74
  23. package/src/lib/components/toolbar/column-visibility-control.tsx +0 -105
  24. package/src/lib/components/toolbar/data-table-toolbar.tsx +0 -257
  25. package/src/lib/components/toolbar/index.ts +0 -17
  26. package/src/lib/components/toolbar/table-export-control.tsx +0 -233
  27. package/src/lib/components/toolbar/table-refresh-control.tsx +0 -62
  28. package/src/lib/components/toolbar/table-search-control.tsx +0 -155
  29. package/src/lib/components/toolbar/table-size-control.tsx +0 -102
  30. package/src/lib/contexts/data-table-context.tsx +0 -126
  31. package/src/lib/data-table.tsx +0 -29
  32. package/src/lib/features/README.md +0 -161
  33. package/src/lib/features/column-filter.feature.ts +0 -493
  34. package/src/lib/features/index.ts +0 -23
  35. package/src/lib/features/selection.feature.ts +0 -322
  36. package/src/lib/hooks/index.ts +0 -2
  37. package/src/lib/hooks/use-data-table-engine.ts +0 -1552
  38. package/src/lib/icons/add-icon.tsx +0 -23
  39. package/src/lib/icons/csv-icon.tsx +0 -15
  40. package/src/lib/icons/delete-icon.tsx +0 -30
  41. package/src/lib/icons/excel-icon.tsx +0 -15
  42. package/src/lib/icons/index.ts +0 -7
  43. package/src/lib/icons/unpin-icon.tsx +0 -18
  44. package/src/lib/icons/view-comfortable-icon.tsx +0 -45
  45. package/src/lib/icons/view-compact-icon.tsx +0 -55
  46. package/src/lib/types/column.types.ts +0 -63
  47. package/src/lib/types/data-table-api.ts +0 -191
  48. package/src/lib/types/data-table.types.ts +0 -193
  49. package/src/lib/types/export.types.ts +0 -223
  50. package/src/lib/types/index.ts +0 -24
  51. package/src/lib/types/slots.types.ts +0 -342
  52. package/src/lib/types/table.types.ts +0 -88
  53. package/src/lib/utils/column-helpers.ts +0 -72
  54. package/src/lib/utils/debounced-fetch.utils.ts +0 -131
  55. package/src/lib/utils/export-utils.ts +0 -712
  56. package/src/lib/utils/index.ts +0 -27
  57. package/src/lib/utils/logger.ts +0 -203
  58. package/src/lib/utils/slot-helpers.tsx +0 -194
  59. package/src/lib/utils/special-columns.utils.ts +0 -101
  60. package/src/lib/utils/styling-helpers.ts +0 -126
  61. package/src/lib/utils/table-helpers.ts +0 -106
@@ -1,257 +0,0 @@
1
- import {
2
- Stack,
3
- Toolbar,
4
- Typography,
5
- Box,
6
- ToolbarProps,
7
- SxProps,
8
- } from '@mui/material';
9
- import React, { ReactNode, ReactElement } from 'react';
10
-
11
- import { ColumnFilterControl } from './column-filter-control';
12
- import { ColumnPinningControl } from './column-pinning-control';
13
- import { ColumnResetControl } from './column-reset-control';
14
- import { ColumnVisibilityControl } from './column-visibility-control';
15
- import { TableExportControl } from './table-export-control';
16
- import { TableSearchControl } from './table-search-control';
17
- import { TableSizeControl } from './table-size-control';
18
- import { useDataTableContext } from '../../contexts/data-table-context';
19
- import { TableRefreshControl } from './table-refresh-control';
20
- import { getSlotComponent, mergeSlotProps, extractSlotProps } from '../../utils/slot-helpers';
21
-
22
- export interface DataTableToolbarProps extends ToolbarProps {
23
- extraFilter?: ReactNode;
24
- enableGlobalFilter?: boolean;
25
- title?: string;
26
- subtitle?: string;
27
- enableColumnVisibility?: boolean;
28
- enableExport?: boolean;
29
- enableReset?: boolean;
30
- enableColumnFilter?: boolean;
31
- enableTableSizeControl?: boolean;
32
- enableColumnPinning?: boolean;
33
- // Enhanced styling props
34
- titleSx?: SxProps;
35
- subtitleSx?: SxProps;
36
- containerSx?: SxProps;
37
- leftSectionSx?: SxProps;
38
- rightSectionSx?: SxProps;
39
- // Allow full customization of any prop
40
- [key: string]: any;
41
- }
42
-
43
- export function DataTableToolbar(props: DataTableToolbarProps = {}): ReactElement {
44
- const {
45
- extraFilter = null,
46
- enableGlobalFilter = true,
47
- title,
48
- subtitle,
49
- enableColumnVisibility = true,
50
- enableExport = true,
51
- enableReset = true,
52
- enableRefresh = false,
53
- enableColumnFilter = true,
54
- enableTableSizeControl = true,
55
- enableColumnPinning = true,
56
- titleSx,
57
- subtitleSx,
58
- containerSx,
59
- leftSectionSx,
60
- rightSectionSx,
61
- ...otherProps
62
- } = props;
63
-
64
- const { table, slots, slotProps = {} } = useDataTableContext();
65
-
66
- // Extract slot-specific props with enhanced merging
67
- const toolbarSlotProps = extractSlotProps(slotProps, 'toolbar');
68
- const searchInputSlotProps = extractSlotProps(slotProps, 'searchInput');
69
- const tableSizeControlSlotProps = extractSlotProps(slotProps, 'tableSizeControl');
70
- const columnCustomFilterControlSlotProps = extractSlotProps(slotProps, 'columnCustomFilterControl');
71
- const columnPinningControlSlotProps = extractSlotProps(slotProps, 'columnPinningControl');
72
- const columnVisibilityControlSlotProps = extractSlotProps(slotProps, 'columnVisibilityControl');
73
- const resetButtonSlotProps = extractSlotProps(slotProps, 'resetButton');
74
- const exportButtonSlotProps = extractSlotProps(slotProps, 'exportButton');
75
- const refreshButtonSlotProps = extractSlotProps(slotProps, 'refreshButton');
76
-
77
- const ToolbarSlot = getSlotComponent(slots, 'toolbar', Toolbar);
78
- const TableSearchControlSlot = getSlotComponent(slots, 'searchInput', TableSearchControl);
79
- const TableSizeControlSlot = getSlotComponent(slots, 'tableSizeControl', TableSizeControl);
80
- const ColumnCustomFilterControlSlot = getSlotComponent(slots, 'columnCustomFilterControl', ColumnFilterControl);
81
- const ColumnPinningControlSlot = getSlotComponent(slots, 'columnPinningControl', ColumnPinningControl);
82
- const ColumnVisibilityControlSlot = getSlotComponent(slots, 'columnVisibilityControl', ColumnVisibilityControl);
83
- const ColumnResetControlSlot = getSlotComponent(slots, 'resetButton', ColumnResetControl);
84
- const TableExportControlSlot = getSlotComponent(slots, 'exportButton', TableExportControl);
85
- const TableRefreshControlSlot = getSlotComponent(slots, 'refreshButton', TableRefreshControl);
86
-
87
- // Merge all props for maximum flexibility
88
- const mergedToolbarProps = mergeSlotProps(
89
- {
90
- // Default toolbar props
91
- table,
92
- ...otherProps,
93
- },
94
- toolbarSlotProps
95
- );
96
-
97
- // Omit child-slot props so they are not spread onto the Toolbar DOM element (React warning)
98
- const TOOLBAR_CHILD_SLOT_KEYS = [
99
- 'refreshButtonProps',
100
- 'searchInputProps',
101
- 'tableSizeControlProps',
102
- 'columnFilterProps',
103
- 'columnPinningProps',
104
- 'columnVisibilityProps',
105
- 'resetButtonProps',
106
- 'exportButtonProps',
107
- ] as const;
108
- const toolbarDomProps = { ...mergedToolbarProps };
109
- TOOLBAR_CHILD_SLOT_KEYS.forEach((key) => delete toolbarDomProps[key]);
110
-
111
- return (
112
- <ToolbarSlot
113
- {...toolbarDomProps}
114
- >
115
- <Box
116
- sx={{
117
- width: '100%',
118
- ...containerSx,
119
- }}
120
- >
121
- {(title || subtitle) ? (
122
- <Box sx={{ mb: 2 }}>
123
- {title ? (
124
- <Typography
125
- variant="h6"
126
- component="div"
127
- sx={titleSx}
128
- >
129
- {title}
130
- </Typography>
131
- ) : null}
132
- {subtitle ? (
133
- <Typography
134
- variant="body2"
135
- color="text.secondary"
136
- sx={subtitleSx}
137
- >
138
- {subtitle}
139
- </Typography>
140
- ) : null}
141
- </Box>
142
- ) : null}
143
-
144
- <Stack
145
- direction="row"
146
- spacing={2}
147
- justifyContent="space-between"
148
- alignItems="center"
149
- >
150
- {/* Left Section - Search, Filters, Actions, and Status */}
151
- <Stack
152
- direction="row"
153
- spacing={0.5}
154
- alignItems="center"
155
- sx={{
156
- flex: 1,
157
- ...leftSectionSx,
158
- }}
159
- >
160
- {/* Table Actions and Filters */}
161
- {enableTableSizeControl ? (
162
- <TableSizeControlSlot
163
- {...mergeSlotProps(
164
- {},
165
- tableSizeControlSlotProps,
166
- props.tableSizeControlProps || {}
167
- )}
168
- />
169
- ) : null}
170
-
171
- {enableColumnFilter ? (
172
- <ColumnCustomFilterControlSlot
173
- {...mergeSlotProps(
174
- {},
175
- columnCustomFilterControlSlotProps,
176
- props.columnFilterProps || {}
177
- )}
178
- />
179
- ) : null}
180
-
181
- {enableColumnPinning ? (
182
- <ColumnPinningControlSlot
183
- {...mergeSlotProps(
184
- {},
185
- columnPinningControlSlotProps,
186
- props.columnPinningProps || {}
187
- )}
188
- />
189
- ) : null}
190
-
191
- {enableColumnVisibility ? (
192
- <ColumnVisibilityControlSlot
193
- {...mergeSlotProps(
194
- {},
195
- columnVisibilityControlSlotProps,
196
- props.columnVisibilityProps || {}
197
- )}
198
- />
199
- ) : null}
200
-
201
- {enableReset ? (
202
- <ColumnResetControlSlot
203
- {...mergeSlotProps(
204
- {},
205
- resetButtonSlotProps,
206
- props.resetButtonProps || {}
207
- )}
208
- />
209
- ) : null}
210
-
211
- {enableExport ? (
212
- <TableExportControlSlot
213
- {...mergeSlotProps(
214
- {},
215
- exportButtonSlotProps,
216
- props.exportButtonProps || {}
217
- )}
218
- />
219
- ) : null}
220
-
221
- {/* Search */}
222
- {enableGlobalFilter ? (
223
- <TableSearchControlSlot
224
- {...mergeSlotProps(
225
- {},
226
- searchInputSlotProps,
227
- props.searchInputProps || {}
228
- )}
229
- />
230
- ) : null}
231
-
232
- {enableRefresh ? (
233
- <TableRefreshControlSlot
234
- {...mergeSlotProps(
235
- {},
236
- refreshButtonSlotProps,
237
- props.refreshButtonProps || {}
238
- )}
239
- />
240
- ) : null}
241
- </Stack>
242
-
243
- {/* Right Section - Extra Filter and More Menu */}
244
- <Stack
245
- direction="row"
246
- spacing={1}
247
- alignItems="center"
248
- sx={rightSectionSx}
249
- >
250
- {/* Extra Filter */}
251
- {extraFilter as any}
252
- </Stack>
253
- </Stack>
254
- </Box>
255
- </ToolbarSlot>
256
- );
257
- }
@@ -1,17 +0,0 @@
1
- /**
2
- * Toolbar components for DataTable
3
- */
4
-
5
- // Main toolbar component
6
- export { DataTableToolbar } from './data-table-toolbar';
7
-
8
- // Individual toolbar building blocks - export for custom toolbars
9
- export { ColumnVisibilityControl } from './column-visibility-control';
10
- export { ColumnPinningControl } from './column-pinning-control';
11
- export { ColumnResetControl } from './column-reset-control';
12
- export { TableExportControl } from './table-export-control';
13
- export { TableSizeControl } from './table-size-control';
14
- export { ColumnFilterControl } from './column-filter-control';
15
- // Bulk actions
16
- export { BulkActionsToolbar } from './bulk-actions-toolbar';
17
- export type { BulkActionsToolbarProps } from './bulk-actions-toolbar';
@@ -1,233 +0,0 @@
1
- import { CloudDownloadOutlined } from '@mui/icons-material';
2
- import React from 'react';
3
- import {
4
- IconButton,
5
- Tooltip,
6
- MenuItem,
7
- ListItemIcon,
8
- ListItemText,
9
- Typography,
10
- Box,
11
- IconButtonProps,
12
- SxProps,
13
- Divider,
14
- LinearProgress,
15
- } from '@mui/material';
16
-
17
- import { MenuDropdown } from '../droupdown/menu-dropdown';
18
- import { useDataTableContext } from '../../contexts/data-table-context';
19
- import { ExcelIcon, CsvIcon } from '../../icons';
20
- import { getSlotComponent, mergeSlotProps, extractSlotProps } from '../../utils/slot-helpers';
21
-
22
- interface TableExportControlProps {
23
- // Optional props to override context defaults
24
- exportFilename?: string;
25
- // onServerExport?: (filters?: Partial<TableFilters>, selection?: SelectionState) => Promise<{ data: any[]; total: number }>;
26
- // onExportProgress?: (progress: { processedRows?: number; totalRows?: number; percentage?: number }) => void;
27
- // onExportComplete?: (result: { success: boolean; filename: string; totalRows: number }) => void;
28
- // onExportError?: (error: { message: string; code: string }) => void;
29
- // Enhanced customization props
30
- iconButtonProps?: IconButtonProps;
31
- tooltipProps?: any;
32
- menuSx?: SxProps;
33
- menuItemProps?: any;
34
- [key: string]: any;
35
- }
36
-
37
- export function TableExportControl(props: TableExportControlProps = {}) {
38
- const {
39
- exportFilename: propsExportFilename,
40
- iconButtonProps,
41
- tooltipProps,
42
- menuSx,
43
- menuItemProps,
44
- } = props;
45
-
46
- const {
47
- apiRef,
48
- slots,
49
- slotProps,
50
- isExporting,
51
- exportPhase,
52
- exportProgress,
53
- onCancelExport,
54
- // Export callbacks from context (DataTable props)
55
- exportFilename: contextExportFilename,
56
- } = useDataTableContext();
57
-
58
- // Use props if provided, otherwise fall back to context values
59
- const exportFilename = propsExportFilename || contextExportFilename || 'export';
60
-
61
- // Extract slot-specific props with enhanced merging
62
- const exportIconSlotProps = extractSlotProps(slotProps, 'exportIcon');
63
- const csvIconSlotProps = extractSlotProps(slotProps, 'csvIcon');
64
- const excelIconSlotProps = extractSlotProps(slotProps, 'excelIcon');
65
-
66
- const ExportIconSlot = getSlotComponent(slots, 'exportIcon', CloudDownloadOutlined);
67
- const CsvIconSlot = getSlotComponent(slots, 'csvIcon', CsvIcon);
68
- const ExcelIconSlot = getSlotComponent(slots, 'excelIcon', ExcelIcon);
69
-
70
- const handleExport = async (format: 'csv' | 'excel') => {
71
- if (!apiRef?.current) return;
72
-
73
- try {
74
- if (format === 'csv') {
75
- await apiRef.current.export.exportCSV({
76
- filename: exportFilename,
77
- });
78
- } else {
79
- await apiRef.current.export.exportExcel({
80
- filename: exportFilename,
81
- });
82
- }
83
- } catch (error) {
84
- console.error('Export failed:', error);
85
- }
86
- };
87
-
88
- const handleCancelExport = () => {
89
- if (onCancelExport) {
90
- onCancelExport();
91
- return;
92
- }
93
- apiRef?.current?.export.cancelExport();
94
- };
95
-
96
- // Merge all props for maximum flexibility
97
- const mergedIconButtonProps = mergeSlotProps(
98
- {
99
- size: 'small',
100
- sx: { flexShrink: 0 },
101
- },
102
- exportIconSlotProps,
103
- iconButtonProps || {}
104
- );
105
-
106
- const mergedMenuItemProps = mergeSlotProps(
107
- {
108
- sx: { minWidth: 150 },
109
- },
110
- menuItemProps || {}
111
- );
112
-
113
- const progressPercentage = typeof exportProgress?.percentage === 'number'
114
- ? Math.max(0, Math.min(100, exportProgress.percentage))
115
- : undefined;
116
-
117
- const getPhaseLabel = () => {
118
- switch (exportPhase) {
119
- case 'fetching':
120
- return 'Fetching rows from server...';
121
- case 'processing':
122
- return 'Preparing export file...';
123
- case 'downloading':
124
- return 'Downloading file...';
125
- case 'starting':
126
- return 'Starting export...';
127
- default:
128
- return 'Export in progress...';
129
- }
130
- };
131
-
132
- return (
133
- <MenuDropdown
134
- anchor={(
135
- <Tooltip
136
- title={isExporting ? 'Export in progress...' : 'Export data'}
137
- {...tooltipProps}
138
- >
139
- <IconButton
140
- {...mergedIconButtonProps}
141
- >
142
- <ExportIconSlot {...exportIconSlotProps} />
143
- </IconButton>
144
- </Tooltip>
145
- )}
146
- >
147
- {({ handleClose }: { handleClose: () => void }) => (
148
- <Box
149
- sx={{
150
- minWidth: 200,
151
- ...menuSx,
152
- }}
153
- >
154
- <Typography
155
- variant="subtitle2"
156
- sx={{ p: 2, pb: 1 }}
157
- >
158
- Export Format
159
- </Typography>
160
-
161
- <MenuItem
162
- onClick={() => {
163
- handleExport('csv');
164
- }}
165
- disabled={isExporting}
166
- {...mergedMenuItemProps}
167
- >
168
- <ListItemIcon>
169
- <CsvIconSlot {...csvIconSlotProps} />
170
- </ListItemIcon>
171
- <ListItemText
172
- primary="CSV"
173
- secondary="Comma-separated values"
174
- />
175
- </MenuItem>
176
-
177
- <MenuItem
178
- onClick={() => {
179
- handleExport('excel');
180
- }}
181
- disabled={isExporting}
182
- {...mergedMenuItemProps}
183
- >
184
- <ListItemIcon>
185
- <ExcelIconSlot {...excelIconSlotProps} />
186
- </ListItemIcon>
187
- <ListItemText
188
- primary="Excel"
189
- secondary="Microsoft Excel format"
190
- />
191
- </MenuItem>
192
-
193
- {isExporting && (
194
- <>
195
- <Box sx={{ px: 2, pb: 1 }}>
196
- <Typography variant="caption" color="text.secondary" sx={{ display: 'block', mb: 0.75 }}>
197
- {getPhaseLabel()}
198
- </Typography>
199
- <LinearProgress
200
- variant={progressPercentage !== undefined ? 'determinate' : 'indeterminate'}
201
- value={progressPercentage !== undefined ? progressPercentage : 0}
202
- />
203
- {(exportProgress?.processedRows !== undefined || exportProgress?.totalRows !== undefined) && (
204
- <Typography variant="caption" color="text.secondary" sx={{ display: 'block', mt: 0.75 }}>
205
- {`${exportProgress?.processedRows ?? 0}${exportProgress?.totalRows !== undefined ? ` / ${exportProgress.totalRows}` : ''}${progressPercentage !== undefined ? ` (${progressPercentage}%)` : ''}`}
206
- </Typography>
207
- )}
208
- </Box>
209
- <Divider sx={{ my: 1 }} />
210
- <MenuItem
211
- onClick={() => {
212
- handleCancelExport();
213
- handleClose();
214
- }}
215
- {...mergedMenuItemProps}
216
- >
217
- <ListItemText
218
- primary="Cancel Export"
219
- secondary="Stop current export job"
220
- slotProps={{
221
- primary: {
222
- color: 'error.main',
223
- },
224
- }}
225
- />
226
- </MenuItem>
227
- </>
228
- )}
229
- </Box>
230
- )}
231
- </MenuDropdown>
232
- );
233
- }
@@ -1,62 +0,0 @@
1
- import React, { ReactElement, useCallback } from 'react';
2
- import { Refresh } from '@mui/icons-material';
3
- import { IconButton, Tooltip, IconButtonProps, CircularProgress } from '@mui/material';
4
-
5
- import { useDataTableContext } from '../../contexts/data-table-context';
6
- import { extractSlotProps, getSlotComponent, mergeSlotProps } from '../../utils/slot-helpers';
7
-
8
- export interface TableRefreshControlProps {
9
- iconButtonProps?: IconButtonProps;
10
- tooltipProps?: any;
11
-
12
- /** optional override */
13
- onRefresh?: () => void | Promise<void>;
14
-
15
- /** disable + show spinner if true */
16
- loading?: boolean;
17
-
18
- /** use spinner instead of icon while loading */
19
- showSpinnerWhileLoading?: boolean;
20
-
21
- [key: string]: any;
22
- }
23
-
24
- export function TableRefreshControl(props: TableRefreshControlProps = {}): ReactElement {
25
- const { apiRef, slots, slotProps } = useDataTableContext();
26
-
27
- const refreshIconSlotProps = extractSlotProps(slotProps, 'refreshIcon');
28
- const RefreshIconSlot = getSlotComponent(slots, 'refreshIcon', Refresh);
29
-
30
- const handleRefresh = useCallback(() => {
31
- if (props.onRefresh) return props.onRefresh();
32
- // Default: use internal api
33
- apiRef?.current?.data?.reload?.();
34
- }, [props, apiRef]);
35
-
36
- const mergedIconButtonProps = mergeSlotProps(
37
- {
38
- size: 'small',
39
- onClick: handleRefresh,
40
- disabled: !!props.loading,
41
- sx: { flexShrink: 0 },
42
- },
43
- refreshIconSlotProps,
44
- props.iconButtonProps || {}
45
- );
46
-
47
- // Wrap in span so when IconButton is disabled (loading), the tooltip still
48
- // receives pointer events and closes on mouse leave (disabled elements don't fire them).
49
- return (
50
- <Tooltip title="Refresh data" {...props.tooltipProps}>
51
- <span style={{ display: 'inline-flex' }}>
52
- <IconButton {...mergedIconButtonProps}>
53
- {props.loading && props.showSpinnerWhileLoading ? (
54
- <CircularProgress size={16} />
55
- ) : (
56
- <RefreshIconSlot {...refreshIconSlotProps} />
57
- )}
58
- </IconButton>
59
- </span>
60
- </Tooltip>
61
- );
62
- }