@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.
Files changed (272) hide show
  1. package/LICENSE +21 -0
  2. package/{src → dist}/index.d.ts +21 -4
  3. package/dist/index.d.ts.map +1 -0
  4. package/dist/index.js +63 -0
  5. package/{src → dist}/lib/components/droupdown/menu-dropdown.d.ts +2 -1
  6. package/dist/lib/components/droupdown/menu-dropdown.d.ts.map +1 -0
  7. package/{src → dist}/lib/components/droupdown/menu-dropdown.js +38 -7
  8. package/{src → dist}/lib/components/filters/filter-value-input.d.ts +3 -1
  9. package/dist/lib/components/filters/filter-value-input.d.ts.map +1 -0
  10. package/dist/lib/components/filters/filter-value-input.js +83 -0
  11. package/{src → dist}/lib/components/filters/index.d.ts +1 -0
  12. package/dist/lib/components/filters/index.d.ts.map +1 -0
  13. package/dist/lib/components/filters/index.js +142 -0
  14. package/{src → dist}/lib/components/headers/draggable-header.d.ts +2 -2
  15. package/dist/lib/components/headers/draggable-header.d.ts.map +1 -0
  16. package/{src → dist}/lib/components/headers/draggable-header.js +81 -17
  17. package/dist/lib/components/headers/index.d.ts +6 -0
  18. package/dist/lib/components/headers/index.d.ts.map +1 -0
  19. package/dist/lib/components/headers/index.js +21 -0
  20. package/{src → dist}/lib/components/headers/table-header.d.ts +15 -1
  21. package/dist/lib/components/headers/table-header.d.ts.map +1 -0
  22. package/{src → dist}/lib/components/headers/table-header.js +50 -17
  23. package/{src → dist}/lib/components/index.d.ts +6 -1
  24. package/dist/lib/components/index.d.ts.map +1 -0
  25. package/dist/lib/components/index.js +32 -0
  26. package/{src → dist}/lib/components/pagination/data-table-pagination.d.ts +2 -1
  27. package/dist/lib/components/pagination/data-table-pagination.d.ts.map +1 -0
  28. package/{src → dist}/lib/components/pagination/data-table-pagination.js +20 -6
  29. package/dist/lib/components/pagination/index.d.ts +5 -0
  30. package/dist/lib/components/pagination/index.d.ts.map +1 -0
  31. package/dist/lib/components/pagination/index.js +20 -0
  32. package/{src → dist}/lib/components/rows/data-table-row.d.ts +15 -2
  33. package/dist/lib/components/rows/data-table-row.d.ts.map +1 -0
  34. package/{src → dist}/lib/components/rows/data-table-row.js +58 -25
  35. package/{src → dist}/lib/components/rows/empty-data-row.d.ts +3 -3
  36. package/dist/lib/components/rows/empty-data-row.d.ts.map +1 -0
  37. package/{src → dist}/lib/components/rows/empty-data-row.js +12 -4
  38. package/dist/lib/components/rows/index.d.ts +7 -0
  39. package/dist/lib/components/rows/index.d.ts.map +1 -0
  40. package/dist/lib/components/rows/index.js +22 -0
  41. package/{src → dist}/lib/components/rows/loading-rows.d.ts +3 -1
  42. package/dist/lib/components/rows/loading-rows.d.ts.map +1 -0
  43. package/{src → dist}/lib/components/rows/loading-rows.js +27 -19
  44. package/{src → dist}/lib/components/toolbar/bulk-actions-toolbar.d.ts +4 -3
  45. package/dist/lib/components/toolbar/bulk-actions-toolbar.d.ts.map +1 -0
  46. package/dist/lib/components/toolbar/bulk-actions-toolbar.js +49 -0
  47. package/{src → dist}/lib/components/toolbar/column-filter-control.d.ts +3 -1
  48. package/dist/lib/components/toolbar/column-filter-control.d.ts.map +1 -0
  49. package/{src → dist}/lib/components/toolbar/column-filter-control.js +73 -4
  50. package/{src → dist}/lib/components/toolbar/column-pinning-control.d.ts +2 -1
  51. package/dist/lib/components/toolbar/column-pinning-control.d.ts.map +1 -0
  52. package/{src → dist}/lib/components/toolbar/column-pinning-control.js +70 -6
  53. package/{src → dist}/lib/components/toolbar/column-reset-control.d.ts +3 -1
  54. package/dist/lib/components/toolbar/column-reset-control.d.ts.map +1 -0
  55. package/{src → dist}/lib/components/toolbar/column-reset-control.js +9 -2
  56. package/{src → dist}/lib/components/toolbar/column-visibility-control.d.ts +2 -1
  57. package/dist/lib/components/toolbar/column-visibility-control.d.ts.map +1 -0
  58. package/dist/lib/components/toolbar/column-visibility-control.js +77 -0
  59. package/{src → dist}/lib/components/toolbar/data-table-toolbar.d.ts +3 -2
  60. package/dist/lib/components/toolbar/data-table-toolbar.d.ts.map +1 -0
  61. package/{src → dist}/lib/components/toolbar/data-table-toolbar.js +17 -4
  62. package/{src → dist}/lib/components/toolbar/index.d.ts +4 -0
  63. package/dist/lib/components/toolbar/index.d.ts.map +1 -0
  64. package/{src → dist}/lib/components/toolbar/index.js +6 -0
  65. package/dist/lib/components/toolbar/table-export-control.d.ts +12 -0
  66. package/dist/lib/components/toolbar/table-export-control.d.ts.map +1 -0
  67. package/dist/lib/components/toolbar/table-export-control.js +67 -0
  68. package/{src → dist}/lib/components/toolbar/table-search-control.d.ts +3 -1
  69. package/dist/lib/components/toolbar/table-search-control.d.ts.map +1 -0
  70. package/{src → dist}/lib/components/toolbar/table-search-control.js +45 -2
  71. package/{src → dist}/lib/components/toolbar/table-size-control.d.ts +3 -1
  72. package/dist/lib/components/toolbar/table-size-control.d.ts.map +1 -0
  73. package/{src → dist}/lib/components/toolbar/table-size-control.js +20 -8
  74. package/{src → dist}/lib/contexts/data-table-context.d.ts +6 -2
  75. package/dist/lib/contexts/data-table-context.d.ts.map +1 -0
  76. package/{src → dist}/lib/contexts/data-table-context.js +34 -1
  77. package/dist/lib/data-table.d.ts +5 -0
  78. package/dist/lib/data-table.d.ts.map +1 -0
  79. package/{src/lib/components/table → dist/lib}/data-table.js +427 -143
  80. package/dist/lib/features/column-filter.feature.d.ts +55 -0
  81. package/dist/lib/features/column-filter.feature.d.ts.map +1 -0
  82. package/{src → dist}/lib/features/column-filter.feature.js +116 -18
  83. package/dist/lib/features/index.d.ts +9 -0
  84. package/dist/lib/features/index.d.ts.map +1 -0
  85. package/{src → dist}/lib/features/index.js +7 -0
  86. package/{src → dist}/lib/features/selection.feature.d.ts +8 -1
  87. package/dist/lib/features/selection.feature.d.ts.map +1 -0
  88. package/{src → dist}/lib/features/selection.feature.js +76 -15
  89. package/dist/lib/icons/add-icon.d.ts +4 -0
  90. package/dist/lib/icons/add-icon.d.ts.map +1 -0
  91. package/dist/lib/icons/add-icon.js +12 -0
  92. package/dist/lib/icons/csv-icon.d.ts +4 -0
  93. package/dist/lib/icons/csv-icon.d.ts.map +1 -0
  94. package/dist/lib/icons/csv-icon.js +12 -0
  95. package/dist/lib/icons/delete-icon.d.ts +4 -0
  96. package/dist/lib/icons/delete-icon.d.ts.map +1 -0
  97. package/dist/lib/icons/delete-icon.js +12 -0
  98. package/dist/lib/icons/excel-icon.d.ts +4 -0
  99. package/dist/lib/icons/excel-icon.d.ts.map +1 -0
  100. package/dist/lib/icons/excel-icon.js +12 -0
  101. package/dist/lib/icons/index.d.ts +8 -0
  102. package/dist/lib/icons/index.d.ts.map +1 -0
  103. package/dist/lib/icons/unpin-icon.d.ts +4 -0
  104. package/dist/lib/icons/unpin-icon.d.ts.map +1 -0
  105. package/dist/lib/icons/unpin-icon.js +12 -0
  106. package/{src → dist}/lib/icons/view-comfortable-icon.d.ts +3 -1
  107. package/dist/lib/icons/view-comfortable-icon.d.ts.map +1 -0
  108. package/dist/lib/icons/view-comfortable-icon.js +12 -0
  109. package/dist/lib/icons/view-compact-icon.d.ts +4 -0
  110. package/dist/lib/icons/view-compact-icon.d.ts.map +1 -0
  111. package/dist/lib/icons/view-compact-icon.js +12 -0
  112. package/{src → dist}/lib/types/column.types.d.ts +10 -1
  113. package/dist/lib/types/column.types.d.ts.map +1 -0
  114. package/{src → dist}/lib/types/data-table-api.d.ts +2 -1
  115. package/dist/lib/types/data-table-api.d.ts.map +1 -0
  116. package/{src/lib/components/table → dist/lib/types}/data-table.types.d.ts +10 -11
  117. package/dist/lib/types/data-table.types.d.ts.map +1 -0
  118. package/{src → dist}/lib/types/export.types.d.ts +38 -0
  119. package/dist/lib/types/export.types.d.ts.map +1 -0
  120. package/dist/lib/types/export.types.js +6 -0
  121. package/{src → dist}/lib/types/index.d.ts +6 -0
  122. package/dist/lib/types/index.d.ts.map +1 -0
  123. package/dist/lib/types/index.js +32 -0
  124. package/{src → dist}/lib/types/slots.types.d.ts +50 -3
  125. package/dist/lib/types/slots.types.d.ts.map +1 -0
  126. package/{src → dist}/lib/types/table.types.d.ts +14 -0
  127. package/dist/lib/types/table.types.d.ts.map +1 -0
  128. package/{src → dist}/lib/utils/column-helpers.d.ts +10 -0
  129. package/dist/lib/utils/column-helpers.d.ts.map +1 -0
  130. package/{src → dist}/lib/utils/column-helpers.js +20 -4
  131. package/{src → dist}/lib/utils/debounced-fetch.utils.d.ts +3 -5
  132. package/dist/lib/utils/debounced-fetch.utils.d.ts.map +1 -0
  133. package/{src → dist}/lib/utils/debounced-fetch.utils.js +12 -6
  134. package/{src → dist}/lib/utils/export-utils.d.ts +13 -0
  135. package/dist/lib/utils/export-utils.d.ts.map +1 -0
  136. package/dist/lib/utils/export-utils.js +252 -0
  137. package/{src → dist}/lib/utils/index.d.ts +4 -0
  138. package/dist/lib/utils/index.d.ts.map +1 -0
  139. package/dist/lib/utils/index.js +35 -0
  140. package/{src → dist}/lib/utils/logger.d.ts +43 -0
  141. package/dist/lib/utils/logger.d.ts.map +1 -0
  142. package/{src → dist}/lib/utils/logger.js +22 -2
  143. package/{src → dist}/lib/utils/slot-helpers.d.ts +39 -1
  144. package/dist/lib/utils/slot-helpers.d.ts.map +1 -0
  145. package/{src → dist}/lib/utils/slot-helpers.js +55 -6
  146. package/{src → dist}/lib/utils/special-columns.utils.d.ts +10 -0
  147. package/dist/lib/utils/special-columns.utils.d.ts.map +1 -0
  148. package/{src → dist}/lib/utils/special-columns.utils.js +41 -5
  149. package/{src → dist}/lib/utils/styling-helpers.d.ts +20 -0
  150. package/dist/lib/utils/styling-helpers.d.ts.map +1 -0
  151. package/dist/lib/utils/styling-helpers.js +108 -0
  152. package/{src → dist}/lib/utils/table-helpers.d.ts +25 -0
  153. package/dist/lib/utils/table-helpers.d.ts.map +1 -0
  154. package/{src → dist}/lib/utils/table-helpers.js +24 -0
  155. package/package.json +36 -11
  156. package/src/index.ts +71 -0
  157. package/src/lib/components/droupdown/menu-dropdown.tsx +97 -0
  158. package/src/lib/components/filters/filter-value-input.tsx +225 -0
  159. package/src/lib/components/filters/{index.js → index.ts} +3 -6
  160. package/src/lib/components/headers/draggable-header.tsx +326 -0
  161. package/src/lib/components/headers/{index.d.ts → index.ts} +4 -0
  162. package/src/lib/components/headers/table-header.tsx +173 -0
  163. package/src/lib/components/index.ts +21 -0
  164. package/src/lib/components/pagination/data-table-pagination.tsx +99 -0
  165. package/src/lib/components/pagination/index.ts +5 -0
  166. package/src/lib/components/rows/data-table-row.tsx +208 -0
  167. package/src/lib/components/rows/empty-data-row.tsx +69 -0
  168. package/src/lib/components/rows/{index.d.ts → index.ts} +4 -0
  169. package/src/lib/components/rows/loading-rows.tsx +160 -0
  170. package/src/lib/components/toolbar/bulk-actions-toolbar.tsx +125 -0
  171. package/src/lib/components/toolbar/column-filter-control.tsx +374 -0
  172. package/src/lib/components/toolbar/column-pinning-control.tsx +275 -0
  173. package/src/lib/components/toolbar/column-reset-control.tsx +74 -0
  174. package/src/lib/components/toolbar/column-visibility-control.tsx +105 -0
  175. package/src/lib/components/toolbar/data-table-toolbar.tsx +229 -0
  176. package/src/lib/components/toolbar/index.ts +17 -0
  177. package/src/lib/components/toolbar/table-export-control.tsx +179 -0
  178. package/src/lib/components/toolbar/table-search-control.tsx +155 -0
  179. package/src/lib/components/toolbar/table-size-control.tsx +102 -0
  180. package/src/lib/contexts/data-table-context.tsx +112 -0
  181. package/src/lib/data-table.tsx +1911 -0
  182. package/src/lib/features/README.md +161 -0
  183. package/src/lib/features/column-filter.feature.ts +456 -0
  184. package/src/lib/features/index.ts +23 -0
  185. package/src/lib/features/selection.feature.ts +318 -0
  186. package/src/lib/icons/add-icon.tsx +23 -0
  187. package/src/lib/icons/csv-icon.tsx +15 -0
  188. package/src/lib/icons/delete-icon.tsx +30 -0
  189. package/src/lib/icons/excel-icon.tsx +15 -0
  190. package/src/lib/icons/unpin-icon.tsx +18 -0
  191. package/src/lib/icons/view-comfortable-icon.tsx +45 -0
  192. package/src/lib/icons/view-compact-icon.tsx +55 -0
  193. package/src/lib/types/column.types.ts +44 -0
  194. package/src/lib/types/data-table-api.ts +169 -0
  195. package/src/lib/types/data-table.types.ts +136 -0
  196. package/src/lib/types/export.types.ts +154 -0
  197. package/src/lib/types/index.ts +24 -0
  198. package/src/lib/types/slots.types.ts +332 -0
  199. package/src/lib/types/table.types.ts +90 -0
  200. package/src/lib/utils/column-helpers.ts +72 -0
  201. package/src/lib/utils/debounced-fetch.utils.ts +54 -0
  202. package/src/lib/utils/export-utils.ts +285 -0
  203. package/src/lib/utils/index.ts +27 -0
  204. package/src/lib/utils/logger.ts +203 -0
  205. package/src/lib/utils/slot-helpers.tsx +194 -0
  206. package/src/lib/utils/special-columns.utils.ts +94 -0
  207. package/src/lib/utils/styling-helpers.ts +126 -0
  208. package/src/lib/utils/table-helpers.ts +106 -0
  209. package/src/index.js +0 -27
  210. package/src/lib/components/filters/filter-value-input.js +0 -41
  211. package/src/lib/components/headers/index.js +0 -5
  212. package/src/lib/components/index.js +0 -10
  213. package/src/lib/components/pagination/index.d.ts +0 -1
  214. package/src/lib/components/pagination/index.js +0 -4
  215. package/src/lib/components/rows/index.js +0 -6
  216. package/src/lib/components/table/data-table.d.ts +0 -4
  217. package/src/lib/components/table/index.d.ts +0 -2
  218. package/src/lib/components/table/index.js +0 -5
  219. package/src/lib/components/toolbar/bulk-actions-toolbar.js +0 -30
  220. package/src/lib/components/toolbar/column-visibility-control.js +0 -31
  221. package/src/lib/components/toolbar/table-export-control.d.ts +0 -31
  222. package/src/lib/components/toolbar/table-export-control.js +0 -56
  223. package/src/lib/examples/advanced-features-example.d.ts +0 -1
  224. package/src/lib/examples/advanced-features-example.js +0 -269
  225. package/src/lib/examples/bulk-actions-test.d.ts +0 -1
  226. package/src/lib/examples/bulk-actions-test.js +0 -44
  227. package/src/lib/examples/custom-column-filter-example.d.ts +0 -1
  228. package/src/lib/examples/custom-column-filter-example.js +0 -60
  229. package/src/lib/examples/index.d.ts +0 -8
  230. package/src/lib/examples/index.js +0 -19
  231. package/src/lib/examples/selection-test-example.d.ts +0 -1
  232. package/src/lib/examples/selection-test-example.js +0 -101
  233. package/src/lib/examples/server-side-fetching-example.d.ts +0 -1
  234. package/src/lib/examples/server-side-fetching-example.js +0 -245
  235. package/src/lib/examples/server-side-test.d.ts +0 -1
  236. package/src/lib/examples/server-side-test.js +0 -9
  237. package/src/lib/examples/simple-local-example.d.ts +0 -1
  238. package/src/lib/examples/simple-local-example.js +0 -95
  239. package/src/lib/examples/simple-slots-example.d.ts +0 -1
  240. package/src/lib/examples/simple-slots-example.js +0 -115
  241. package/src/lib/features/column-filter.feature.d.ts +0 -45
  242. package/src/lib/features/index.d.ts +0 -2
  243. package/src/lib/hooks/index.d.ts +0 -1
  244. package/src/lib/hooks/index.js +0 -4
  245. package/src/lib/hooks/use-data-table-api.d.ts +0 -46
  246. package/src/lib/hooks/use-data-table-api.js +0 -690
  247. package/src/lib/icons/add-icon.d.ts +0 -2
  248. package/src/lib/icons/add-icon.js +0 -8
  249. package/src/lib/icons/csv-icon.d.ts +0 -2
  250. package/src/lib/icons/csv-icon.js +0 -8
  251. package/src/lib/icons/delete-icon.d.ts +0 -2
  252. package/src/lib/icons/delete-icon.js +0 -8
  253. package/src/lib/icons/excel-icon.d.ts +0 -2
  254. package/src/lib/icons/excel-icon.js +0 -8
  255. package/src/lib/icons/unpin-icon.d.ts +0 -2
  256. package/src/lib/icons/unpin-icon.js +0 -8
  257. package/src/lib/icons/view-comfortable-icon.js +0 -8
  258. package/src/lib/icons/view-compact-icon.d.ts +0 -2
  259. package/src/lib/icons/view-compact-icon.js +0 -8
  260. package/src/lib/types/export.types.js +0 -2
  261. package/src/lib/types/index.js +0 -8
  262. package/src/lib/utils/export-utils.js +0 -175
  263. package/src/lib/utils/index.js +0 -11
  264. package/src/lib/utils/styling-helpers.js +0 -70
  265. package/tsconfig.tsbuildinfo +0 -1
  266. /package/{src → dist}/lib/icons/index.js +0 -0
  267. /package/{src → dist}/lib/types/column.types.js +0 -0
  268. /package/{src → dist}/lib/types/data-table-api.js +0 -0
  269. /package/{src/lib/components/table → dist/lib/types}/data-table.types.js +0 -0
  270. /package/{src → dist}/lib/types/slots.types.js +0 -0
  271. /package/{src → dist}/lib/types/table.types.js +0 -0
  272. /package/src/lib/icons/{index.d.ts → index.ts} +0 -0
@@ -0,0 +1,275 @@
1
+ import { ArrowLeftOutlined, ArrowRightOutlined, PushPinOutlined } from '@mui/icons-material';
2
+ import {
3
+ Box,
4
+ Typography,
5
+ Divider,
6
+ IconButton,
7
+ Tooltip,
8
+ List,
9
+ ListItem,
10
+ ListItemText,
11
+ IconButtonProps,
12
+ SxProps,
13
+ } from '@mui/material';
14
+ import { ColumnPinningState, Column } from '@tanstack/react-table';
15
+ import React, { useCallback, useMemo } from 'react';
16
+
17
+ import { MenuDropdown } from '../droupdown/menu-dropdown';
18
+ import { useDataTableContext } from '../../contexts/data-table-context';
19
+ import {
20
+ UnpinIcon,
21
+ } from '../../icons';
22
+ import { getSlotComponent, mergeSlotProps, extractSlotProps } from '../../utils/slot-helpers';
23
+
24
+ export interface ColumnPinningControlProps {
25
+ // Allow full customization of any prop
26
+ title?: string;
27
+ titleSx?: SxProps;
28
+ menuSx?: SxProps;
29
+ iconButtonProps?: IconButtonProps;
30
+ tooltipProps?: any;
31
+ badgeProps?: any;
32
+ clearButtonProps?: any;
33
+ [key: string]: any;
34
+ }
35
+
36
+ export function ColumnPinningControl(props: ColumnPinningControlProps = {}) {
37
+ // Use context if no props provided (MUI DataGrid style)
38
+ const { table, slots, slotProps } = useDataTableContext();
39
+
40
+ // Extract slot-specific props with enhanced merging
41
+ const pinIconSlotProps = extractSlotProps(slotProps, 'pinIcon');
42
+ const unpinIconSlotProps = extractSlotProps(slotProps, 'unpinIcon');
43
+ const leftIconSlotProps = extractSlotProps(slotProps, 'leftIcon');
44
+ const rightIconSlotProps = extractSlotProps(slotProps, 'rightIcon');
45
+
46
+ const PinIconSlot = getSlotComponent(slots, 'pinIcon', PushPinOutlined);
47
+ const UnpinIconSlot = getSlotComponent(slots, 'unpinIcon', UnpinIcon);
48
+ const LeftIconSlot = getSlotComponent(slots, 'leftIcon', ArrowLeftOutlined);
49
+ const RightIconSlot = getSlotComponent(slots, 'rightIcon', ArrowRightOutlined);
50
+
51
+ const columnPinning = table?.getState().columnPinning || {};
52
+
53
+ const allColumns: Column<any, unknown>[] = useMemo(() => {
54
+ if (slotProps?.columnsPanel?.getPinnableColumns) {
55
+ return slotProps?.columnsPanel?.getPinnableColumns(table?.getAllLeafColumns() || []);
56
+ }
57
+ return table?.getAllLeafColumns()?.filter(column => column.getCanPin()) || [];
58
+ }, [slotProps?.columnsPanel, table]);
59
+
60
+ const handlePinColumn = (columnId: string, position: 'left' | 'right' | 'none') => {
61
+ const currentPinning = table?.getState().columnPinning || {};
62
+ const newPinning: ColumnPinningState = { ...currentPinning };
63
+
64
+ // Remove from current position
65
+ newPinning.left = (newPinning.left || []).filter(id => id !== columnId);
66
+ newPinning.right = (newPinning.right || []).filter(id => id !== columnId);
67
+
68
+ // Add to new position
69
+ if (position === 'left') {
70
+ // Left-pinned: append to end (appears leftmost to rightmost)
71
+ newPinning.left = [...(newPinning.left || []), columnId];
72
+ } else if (position === 'right') {
73
+ // Right-pinned: prepend to beginning (appears rightmost to leftmost)
74
+ // First column pinned appears rightmost, second appears to its left, etc.
75
+ newPinning.right = [columnId, ...(newPinning.right || [])];
76
+ }
77
+
78
+ table?.setColumnPinning(newPinning);
79
+ };
80
+
81
+ const getColumnPinStatus = (columnId: string): 'left' | 'right' | 'none' => {
82
+ if (columnPinning.left?.includes(columnId)) return 'left';
83
+ if (columnPinning.right?.includes(columnId)) return 'right';
84
+ return 'none';
85
+ };
86
+
87
+ const getColumnDisplayName = (column: any) => {
88
+ if (typeof column.columnDef.header === 'string') {
89
+ return column.columnDef.header;
90
+ }
91
+ return column.id;
92
+ };
93
+
94
+ const handleUnpinAll = useCallback(() => {
95
+ table?.setColumnPinning(table?.initialState?.columnPinning || {});
96
+ }, [table]);
97
+
98
+ // Count only user-pinned columns (exclude system columns like select and action)
99
+ const userPinnedLeft = (columnPinning.left?.filter((id) => allColumns.some((column: any) => column.id === id)) || []);
100
+ const userPinnedRight = (columnPinning.right?.filter((id) => allColumns.some((column: any) => column.id === id)) || []);
101
+ const totalPinned = userPinnedLeft.length + userPinnedRight.length;
102
+
103
+ // Merge all props for maximum flexibility
104
+ const mergedIconButtonProps = mergeSlotProps(
105
+ {
106
+ size: 'small',
107
+ sx: { flexShrink: 0 },
108
+ },
109
+ pinIconSlotProps,
110
+ props.iconButtonProps || {}
111
+ );
112
+
113
+ return (
114
+ <MenuDropdown
115
+ anchor={(
116
+ <Tooltip
117
+ title="Pin columns"
118
+ {...props.tooltipProps}
119
+ >
120
+ <IconButton
121
+ {...mergedIconButtonProps}
122
+ >
123
+ <PinIconSlot {...pinIconSlotProps} />
124
+ {totalPinned > 0 && (
125
+ <Box
126
+ sx={{
127
+ position: 'absolute',
128
+ top: -2,
129
+ right: -2,
130
+ backgroundColor: 'primary.main',
131
+ color: 'white',
132
+ borderRadius: '50%',
133
+ width: 16,
134
+ height: 16,
135
+ fontSize: 10,
136
+ display: 'flex',
137
+ alignItems: 'center',
138
+ justifyContent: 'center',
139
+ ...props.badgeProps?.sx,
140
+ }}
141
+ {...props.badgeProps}
142
+ >
143
+ {totalPinned}
144
+ </Box>
145
+ )}
146
+ </IconButton>
147
+ </Tooltip>
148
+ )}
149
+ >
150
+
151
+ <Box
152
+ sx={{
153
+ p: 2,
154
+ minWidth: 300,
155
+ maxWidth: 400,
156
+ ...props.menuSx,
157
+ }}
158
+ >
159
+ <Typography
160
+ variant="subtitle2"
161
+ sx={{
162
+ mb: 1,
163
+ ...props.titleSx,
164
+ }}
165
+ >
166
+ {props.title || 'Pin Columns'}
167
+ </Typography>
168
+ <Divider sx={{ mb: 2 }} />
169
+
170
+ {totalPinned > 0 && (
171
+ <Box sx={{ mb: 2 }}>
172
+ <IconButton
173
+ size="small"
174
+ onClick={handleUnpinAll}
175
+ color="warning"
176
+ {...props.clearButtonProps}
177
+ >
178
+ <UnpinIconSlot {...unpinIconSlotProps} />
179
+ </IconButton>
180
+ <Typography variant="caption" sx={{ ml: 1 }}>
181
+ Unpin all columns
182
+ </Typography>
183
+ </Box>
184
+ )}
185
+
186
+ <List
187
+ dense
188
+ sx={{ py: 0 }}
189
+ >
190
+ {allColumns.map((column: any) => {
191
+ const pinStatus = getColumnPinStatus(column.id);
192
+ const displayName = getColumnDisplayName(column);
193
+
194
+ return (
195
+ <ListItem
196
+ key={column.id}
197
+ sx={{ py: 0.25 }}
198
+ secondaryAction={(
199
+ <Box
200
+ sx={{
201
+ display: 'flex',
202
+ gap: 0.5,
203
+ }}
204
+ >
205
+ {/* Pin Left */}
206
+ <Tooltip title="Pin left">
207
+ <IconButton
208
+ size="small"
209
+ onClick={() => handlePinColumn(column.id, pinStatus === 'left' ? 'none' : 'left')}
210
+ color={pinStatus === 'left' ? 'primary' : 'default'}
211
+ >
212
+ <LeftIconSlot
213
+ fontSize="small"
214
+ {...leftIconSlotProps}
215
+ />
216
+ </IconButton>
217
+ </Tooltip>
218
+
219
+ {/* Pin Right */}
220
+ <Tooltip title="Pin right">
221
+ <IconButton
222
+ size="small"
223
+ onClick={() => handlePinColumn(column.id, pinStatus === 'right' ? 'none' : 'right')}
224
+ color={pinStatus === 'right' ? 'secondary' : 'default'}
225
+ >
226
+ <RightIconSlot
227
+ fontSize="small"
228
+ {...rightIconSlotProps}
229
+ />
230
+ </IconButton>
231
+ </Tooltip>
232
+
233
+ {/* Unpin */}
234
+ {pinStatus !== 'none' && (
235
+ <Tooltip title="Unpin">
236
+ <IconButton
237
+ size="small"
238
+ onClick={() => handlePinColumn(column.id, 'none')}
239
+ >
240
+ <UnpinIconSlot
241
+ fontSize="small"
242
+ {...unpinIconSlotProps}
243
+ />
244
+ </IconButton>
245
+ </Tooltip>
246
+ )}
247
+ </Box>
248
+ )}
249
+ >
250
+ <ListItemText
251
+ primary={displayName}
252
+ secondary={
253
+ pinStatus === 'left' ? 'Pinned left' :
254
+ pinStatus === 'right' ? 'Pinned right' :
255
+ 'Not pinned'
256
+ }
257
+ slotProps={{
258
+ primary: {
259
+ variant: 'body2',
260
+ fontWeight: pinStatus !== 'none' ? 600 : 400,
261
+ },
262
+ secondary: {
263
+ variant: 'caption',
264
+ color: pinStatus !== 'none' ? 'primary.main' : 'text.secondary',
265
+ },
266
+ }}
267
+ />
268
+ </ListItem>
269
+ );
270
+ })}
271
+ </List>
272
+ </Box>
273
+ </MenuDropdown>
274
+ );
275
+ }
@@ -0,0 +1,74 @@
1
+ import React, { ReactElement } from 'react';
2
+ import { Autorenew } from '@mui/icons-material';
3
+ import { IconButton, Tooltip, IconButtonProps } from '@mui/material';
4
+
5
+ import { useDataTableContext } from '../../contexts/data-table-context';
6
+ import { getSlotComponent, mergeSlotProps, extractSlotProps } from '../../utils/slot-helpers';
7
+
8
+ export interface ColumnResetControlProps {
9
+ // Allow full customization of any prop
10
+ iconButtonProps?: IconButtonProps;
11
+ tooltipProps?: any;
12
+ resetActions?: ('columnOrder' | 'columnPinning' | 'columnSizing' | 'columnVisibility' | 'filters' | 'sorting' | 'pagination')[];
13
+ [key: string]: any;
14
+ }
15
+
16
+ export function ColumnResetControl(props: ColumnResetControlProps = {}): ReactElement {
17
+ const { apiRef, slots, slotProps } = useDataTableContext();
18
+
19
+ // Extract slot-specific props with enhanced merging
20
+ const resetIconSlotProps = extractSlotProps(slotProps, 'resetIcon');
21
+ const ResetIconSlot = getSlotComponent(slots, 'resetIcon', Autorenew);
22
+
23
+ const handleResetLayout = () => {
24
+ const actions = props.resetActions || ['columnOrder', 'columnPinning', 'columnSizing'];
25
+ if (!apiRef?.current) return;
26
+
27
+ // Reset based on specified actions
28
+ if (actions.includes('columnOrder')) {
29
+ apiRef?.current?.columnOrdering?.resetColumnOrder();
30
+ }
31
+ if (actions.includes('columnPinning')) {
32
+ apiRef?.current?.columnPinning?.resetColumnPinning();
33
+ }
34
+ if (actions.includes('columnSizing')) {
35
+ apiRef?.current?.columnResizing?.resetColumnSizing();
36
+ }
37
+ if (actions.includes('columnVisibility')) {
38
+ apiRef?.current?.columnVisibility?.resetColumnVisibility();
39
+ }
40
+ if (actions.includes('filters')) {
41
+ apiRef?.current?.filtering?.clearAllFilters();
42
+ }
43
+ if (actions.includes('sorting')) {
44
+ apiRef?.current?.sorting?.resetSorting();
45
+ }
46
+ if (actions.includes('pagination')) {
47
+ apiRef?.current?.pagination?.resetPagination();
48
+ }
49
+ };
50
+
51
+ // Merge all props for maximum flexibility
52
+ const mergedIconButtonProps = mergeSlotProps(
53
+ {
54
+ size: 'small',
55
+ onClick: handleResetLayout,
56
+ sx: { flexShrink: 0 },
57
+ },
58
+ resetIconSlotProps,
59
+ props.iconButtonProps || {}
60
+ );
61
+
62
+ return (
63
+ <Tooltip
64
+ title="Reset layout"
65
+ {...props.tooltipProps}
66
+ >
67
+ <IconButton
68
+ {...mergedIconButtonProps}
69
+ >
70
+ <ResetIconSlot {...resetIconSlotProps} />
71
+ </IconButton>
72
+ </Tooltip>
73
+ );
74
+ }
@@ -0,0 +1,105 @@
1
+ import { ViewColumnOutlined } from '@mui/icons-material';
2
+ import { Box, Checkbox, CheckboxProps, Divider, FormControlLabel, SxProps, FormGroup, IconButton, Tooltip, Typography, FormControlLabelProps } from '@mui/material';
3
+ import React, { useMemo } from 'react';
4
+
5
+ import { MenuDropdown } from '../droupdown/menu-dropdown';
6
+ import { useDataTableContext } from '../../contexts/data-table-context';
7
+ import { getSlotComponent, mergeSlotProps, extractSlotProps } from '../../utils/slot-helpers';
8
+
9
+ export interface ColumnVisibilityControlProps {
10
+ // Allow full customization of any prop
11
+ title?: string;
12
+ titleSx?: SxProps;
13
+ menuSx?: SxProps;
14
+ checkboxProps?: CheckboxProps;
15
+ labelProps?: FormControlLabelProps;
16
+ [key: string]: any;
17
+ }
18
+
19
+ export function ColumnVisibilityControl(props: ColumnVisibilityControlProps = {}) {
20
+ // Use context if no props provided (MUI DataGrid style)
21
+ const { table, slots, slotProps } = useDataTableContext();
22
+
23
+ // Extract slot-specific props with enhanced merging
24
+ const iconSlotProps = extractSlotProps(slotProps, 'columnIcon');
25
+ const ColumnIconSlot = getSlotComponent(slots, 'columnIcon', ViewColumnOutlined);
26
+
27
+ const columns = useMemo(() => {
28
+ if (slotProps?.columnsPanel?.getTogglableColumns) {
29
+ return slotProps?.columnsPanel?.getTogglableColumns(table?.getAllLeafColumns() || []);
30
+ }
31
+ return table?.getAllLeafColumns()?.filter(column => column.getCanHide()) || [];
32
+ }, [slotProps?.columnsPanel, table]);
33
+
34
+ const handleColumnVisibilityChange = ((columnId: string, visible: boolean) => {
35
+ table?.getColumn(columnId)?.toggleVisibility(visible);
36
+ });
37
+
38
+ // Merge all props for maximum flexibility
39
+ const mergedProps = mergeSlotProps(
40
+ {
41
+ // Default props
42
+ size: 'small',
43
+ sx: { flexShrink: 0 },
44
+ },
45
+ slotProps?.columnVisibilityControl || {},
46
+ props
47
+ );
48
+
49
+ return (
50
+ <MenuDropdown
51
+ anchor={(
52
+ <Tooltip title="Column visibility">
53
+ <IconButton
54
+ {...mergedProps}
55
+ >
56
+ <ColumnIconSlot
57
+ {...iconSlotProps}
58
+ />
59
+ </IconButton>
60
+ </Tooltip>
61
+ )}
62
+ >
63
+ <Box
64
+ sx={{
65
+ p: 2,
66
+ minWidth: 200,
67
+ // Allow user to override these styles
68
+ ...mergedProps.menuSx,
69
+ }}
70
+ >
71
+ <Typography
72
+ variant="subtitle2"
73
+ sx={{
74
+ mb: 1,
75
+ // Allow user to override title styles
76
+ ...mergedProps.titleSx,
77
+ }}
78
+ >
79
+ {mergedProps.title || 'Show/Hide Columns'}
80
+ </Typography>
81
+ <Divider sx={{ mb: 1 }} />
82
+ <FormGroup>
83
+ {columns.map((column: any) => (
84
+ <FormControlLabel
85
+ key={column.id}
86
+ control={(
87
+ <Checkbox
88
+ disabled={!column.getCanHide()}
89
+ checked={column.getIsVisible()}
90
+ onChange={(e: any) => handleColumnVisibilityChange(column.id, e.target.checked)}
91
+ size="small"
92
+ // Allow user to override checkbox props
93
+ {...mergedProps.checkboxProps}
94
+ />
95
+ )}
96
+ label={typeof column.columnDef.header === 'string' ? column.columnDef.header : column.id}
97
+ // Allow user to override label props
98
+ {...mergedProps.labelProps}
99
+ />
100
+ ))}
101
+ </FormGroup>
102
+ </Box>
103
+ </MenuDropdown>
104
+ );
105
+ }
@@ -0,0 +1,229 @@
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 { getSlotComponent, mergeSlotProps, extractSlotProps } from '../../utils/slot-helpers';
20
+
21
+ export interface DataTableToolbarProps extends ToolbarProps {
22
+ extraFilter?: ReactNode;
23
+ enableGlobalFilter?: boolean;
24
+ title?: string;
25
+ subtitle?: string;
26
+ enableColumnVisibility?: boolean;
27
+ enableExport?: boolean;
28
+ enableReset?: boolean;
29
+ enableColumnFilter?: boolean;
30
+ enableTableSizeControl?: boolean;
31
+ enableColumnPinning?: boolean;
32
+ // Enhanced styling props
33
+ titleSx?: SxProps;
34
+ subtitleSx?: SxProps;
35
+ containerSx?: SxProps;
36
+ leftSectionSx?: SxProps;
37
+ rightSectionSx?: SxProps;
38
+ // Allow full customization of any prop
39
+ [key: string]: any;
40
+ }
41
+
42
+ export function DataTableToolbar(props: DataTableToolbarProps = {}): ReactElement {
43
+ const {
44
+ extraFilter = null,
45
+ enableGlobalFilter = true,
46
+ title,
47
+ subtitle,
48
+ enableColumnVisibility = true,
49
+ enableExport = true,
50
+ enableReset = true,
51
+ enableColumnFilter = true,
52
+ enableTableSizeControl = true,
53
+ enableColumnPinning = true,
54
+ titleSx,
55
+ subtitleSx,
56
+ containerSx,
57
+ leftSectionSx,
58
+ rightSectionSx,
59
+ ...otherProps
60
+ } = props;
61
+
62
+ const { table, slots, slotProps = {} } = useDataTableContext();
63
+
64
+ // Extract slot-specific props with enhanced merging
65
+ const toolbarSlotProps = extractSlotProps(slotProps, 'toolbar');
66
+ const searchInputSlotProps = extractSlotProps(slotProps, 'searchInput');
67
+ const tableSizeControlSlotProps = extractSlotProps(slotProps, 'tableSizeControl');
68
+ const columnCustomFilterControlSlotProps = extractSlotProps(slotProps, 'columnCustomFilterControl');
69
+ const columnPinningControlSlotProps = extractSlotProps(slotProps, 'columnPinningControl');
70
+ const columnVisibilityControlSlotProps = extractSlotProps(slotProps, 'columnVisibilityControl');
71
+ const resetButtonSlotProps = extractSlotProps(slotProps, 'resetButton');
72
+ const exportButtonSlotProps = extractSlotProps(slotProps, 'exportButton');
73
+
74
+ const ToolbarSlot = getSlotComponent(slots, 'toolbar', Toolbar);
75
+ const TableSearchControlSlot = getSlotComponent(slots, 'searchInput', TableSearchControl);
76
+ const TableSizeControlSlot = getSlotComponent(slots, 'tableSizeControl', TableSizeControl);
77
+ const ColumnCustomFilterControlSlot = getSlotComponent(slots, 'columnCustomFilterControl', ColumnFilterControl);
78
+ const ColumnPinningControlSlot = getSlotComponent(slots, 'columnPinningControl', ColumnPinningControl);
79
+ const ColumnVisibilityControlSlot = getSlotComponent(slots, 'columnVisibilityControl', ColumnVisibilityControl);
80
+ const ColumnResetControlSlot = getSlotComponent(slots, 'resetButton', ColumnResetControl);
81
+ const TableExportControlSlot = getSlotComponent(slots, 'exportButton', TableExportControl);
82
+
83
+ // Merge all props for maximum flexibility
84
+ const mergedToolbarProps = mergeSlotProps(
85
+ {
86
+ // Default toolbar props
87
+ table,
88
+ ...otherProps,
89
+ },
90
+ toolbarSlotProps
91
+ );
92
+
93
+ return (
94
+ <ToolbarSlot
95
+ {...mergedToolbarProps}
96
+ >
97
+ <Box
98
+ sx={{
99
+ width: '100%',
100
+ ...containerSx,
101
+ }}
102
+ >
103
+ {(title || subtitle) ? (
104
+ <Box sx={{ mb: 2 }}>
105
+ {title ? (
106
+ <Typography
107
+ variant="h6"
108
+ component="div"
109
+ sx={titleSx}
110
+ >
111
+ {title}
112
+ </Typography>
113
+ ) : null}
114
+ {subtitle ? (
115
+ <Typography
116
+ variant="body2"
117
+ color="text.secondary"
118
+ sx={subtitleSx}
119
+ >
120
+ {subtitle}
121
+ </Typography>
122
+ ) : null}
123
+ </Box>
124
+ ) : null}
125
+
126
+ <Stack
127
+ direction="row"
128
+ spacing={2}
129
+ justifyContent="space-between"
130
+ alignItems="center"
131
+ >
132
+ {/* Left Section - Search, Filters, Actions, and Status */}
133
+ <Stack
134
+ direction="row"
135
+ spacing={0.5}
136
+ alignItems="center"
137
+ sx={{
138
+ flex: 1,
139
+ ...leftSectionSx,
140
+ }}
141
+ >
142
+ {/* Table Actions and Filters */}
143
+ {enableTableSizeControl ? (
144
+ <TableSizeControlSlot
145
+ {...mergeSlotProps(
146
+ {},
147
+ tableSizeControlSlotProps,
148
+ props.tableSizeControlProps || {}
149
+ )}
150
+ />
151
+ ) : null}
152
+
153
+ {enableColumnFilter ? (
154
+ <ColumnCustomFilterControlSlot
155
+ {...mergeSlotProps(
156
+ {},
157
+ columnCustomFilterControlSlotProps,
158
+ props.columnFilterProps || {}
159
+ )}
160
+ />
161
+ ) : null}
162
+
163
+ {enableColumnPinning ? (
164
+ <ColumnPinningControlSlot
165
+ {...mergeSlotProps(
166
+ {},
167
+ columnPinningControlSlotProps,
168
+ props.columnPinningProps || {}
169
+ )}
170
+ />
171
+ ) : null}
172
+
173
+ {enableColumnVisibility ? (
174
+ <ColumnVisibilityControlSlot
175
+ {...mergeSlotProps(
176
+ {},
177
+ columnVisibilityControlSlotProps,
178
+ props.columnVisibilityProps || {}
179
+ )}
180
+ />
181
+ ) : null}
182
+
183
+ {enableReset ? (
184
+ <ColumnResetControlSlot
185
+ {...mergeSlotProps(
186
+ {},
187
+ resetButtonSlotProps,
188
+ props.resetButtonProps || {}
189
+ )}
190
+ />
191
+ ) : null}
192
+
193
+ {enableExport ? (
194
+ <TableExportControlSlot
195
+ {...mergeSlotProps(
196
+ {},
197
+ exportButtonSlotProps,
198
+ props.exportButtonProps || {}
199
+ )}
200
+ />
201
+ ) : null}
202
+
203
+ {/* Search */}
204
+ {enableGlobalFilter ? (
205
+ <TableSearchControlSlot
206
+ {...mergeSlotProps(
207
+ {},
208
+ searchInputSlotProps,
209
+ props.searchInputProps || {}
210
+ )}
211
+ />
212
+ ) : null}
213
+ </Stack>
214
+
215
+ {/* Right Section - Extra Filter and More Menu */}
216
+ <Stack
217
+ direction="row"
218
+ spacing={1}
219
+ alignItems="center"
220
+ sx={rightSectionSx}
221
+ >
222
+ {/* Extra Filter */}
223
+ {extraFilter as any}
224
+ </Stack>
225
+ </Stack>
226
+ </Box>
227
+ </ToolbarSlot>
228
+ );
229
+ }