@ackplus/react-tanstack-data-table 1.0.34 → 1.1.1

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 +71 -7
  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 -3
  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 +449 -151
  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 -10
  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 +5 -0
  122. package/dist/lib/types/index.d.ts.map +1 -0
  123. package/dist/lib/types/index.js +30 -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 +139 -0
  196. package/src/lib/types/export.types.ts +154 -0
  197. package/src/lib/types/index.ts +22 -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,97 @@
1
+ import { Button, Menu, MenuProps, Popover } from '@mui/material';
2
+ import React, {
3
+ cloneElement,
4
+ ReactElement,
5
+ ReactNode,
6
+ useCallback,
7
+ useMemo,
8
+ useState,
9
+ } from 'react';
10
+
11
+
12
+ type ChildrenEvent = {
13
+ handleClose: () => void;
14
+ open: boolean;
15
+ };
16
+
17
+ type AnchorEvent = {
18
+ isOpen: boolean;
19
+ };
20
+
21
+ export interface MenuDropdownProps
22
+ extends Omit<MenuProps, 'children' | 'open'> {
23
+ children?: ((event: ChildrenEvent) => ReactNode) | ReactNode | any;
24
+ anchor?: ((event: AnchorEvent) => ReactElement<any>) | ReactElement<any>;
25
+ label?: ReactNode;
26
+ component?: typeof Popover | typeof Menu;
27
+ }
28
+
29
+ export function MenuDropdown({
30
+ children,
31
+ anchor,
32
+ label,
33
+ component,
34
+ ...props
35
+ }: MenuDropdownProps): ReactElement {
36
+ const [anchorEl, setAnchorEl] = useState<null | HTMLElement>(null);
37
+ const isOpen = useMemo(() => Boolean(anchorEl), [anchorEl]);
38
+ const handleClick = useCallback(
39
+ (event: React.MouseEvent<HTMLButtonElement>) => {
40
+ event.preventDefault();
41
+ event.stopPropagation();
42
+ setAnchorEl(event.currentTarget);
43
+ },
44
+ [],
45
+ );
46
+ const handleClose = useCallback((event:any) => {
47
+ event?.preventDefault();
48
+ event?.stopPropagation();
49
+ setAnchorEl(null);
50
+ }, []);
51
+ const anchorNode = useMemo(() => {
52
+ if (anchor) {
53
+ let node = anchor;
54
+ if (typeof anchor === 'function') {
55
+ node = anchor({ isOpen: isOpen });
56
+ }
57
+ return cloneElement(node as ReactElement<any>, {
58
+ onClick: handleClick,
59
+ });
60
+ }
61
+ return <Button onClick={handleClick}>{label as any}</Button>;
62
+ }, [
63
+ anchor,
64
+ handleClick,
65
+ isOpen,
66
+ label,
67
+ ]);
68
+
69
+ const DropDownComponent = (component || Popover) as React.ComponentType<any>;
70
+
71
+ return (
72
+ <>
73
+ {anchorNode}
74
+ <DropDownComponent
75
+ anchorEl={anchorEl}
76
+ open={isOpen}
77
+ onClose={handleClose}
78
+ anchorOrigin={{
79
+ vertical: 'bottom',
80
+ horizontal: 'left',
81
+ }}
82
+ transformOrigin={{
83
+ vertical: 'top',
84
+ horizontal: 'left',
85
+ }}
86
+ {...props}
87
+ >
88
+ {typeof children === 'function' ?
89
+ children({
90
+ handleClose,
91
+ open: isOpen,
92
+ }) :
93
+ children}
94
+ </DropDownComponent>
95
+ </>
96
+ );
97
+ }
@@ -0,0 +1,225 @@
1
+ import React, { ReactElement } from 'react';
2
+ import { FormControl, InputLabel, Select, MenuItem, TextField, Checkbox, ListItemText, Box, FormControlProps, TextFieldProps, SelectProps, SxProps } from '@mui/material';
3
+ import { DatePicker } from '@mui/x-date-pickers/DatePicker';
4
+ import { Column } from '@tanstack/react-table';
5
+ import moment from 'moment';
6
+
7
+ import { getColumnOptions, getColumnType, getCustomFilterComponent } from '../../utils/column-helpers';
8
+ import { AdapterMoment } from '@mui/x-date-pickers/AdapterMoment';
9
+ import { LocalizationProvider } from '@mui/x-date-pickers';
10
+ import { ColumnFilterRule } from '../../features';
11
+
12
+ interface FilterValueInputProps<T> {
13
+ filter: ColumnFilterRule;
14
+ column: Column<T, any>;
15
+ onValueChange: (value: any) => void;
16
+ // Enhanced customization props
17
+ formControlProps?: FormControlProps;
18
+ textFieldProps?: TextFieldProps;
19
+ selectProps?: SelectProps;
20
+ datePickerProps?: any;
21
+ containerSx?: SxProps;
22
+ [key: string]: any;
23
+ }
24
+
25
+ export function FilterValueInput<T>(props: FilterValueInputProps<T>): ReactElement {
26
+ const {
27
+ filter,
28
+ column,
29
+ onValueChange,
30
+ formControlProps,
31
+ textFieldProps,
32
+ selectProps,
33
+ datePickerProps,
34
+ containerSx,
35
+ ...otherProps
36
+ } = props;
37
+
38
+ const columnType = getColumnType(column);
39
+ const customComponent = getCustomFilterComponent(column);
40
+ const options = getColumnOptions(column);
41
+ const operator = filter.operator;
42
+
43
+ // If custom component is provided, use it
44
+ if (customComponent) {
45
+ const CustomComponent = customComponent;
46
+ return (
47
+ <Box sx={containerSx}>
48
+ <CustomComponent
49
+ value={filter.value}
50
+ onChange={onValueChange}
51
+ filter={filter}
52
+ column={column}
53
+ {...otherProps}
54
+ />
55
+ </Box>
56
+ );
57
+ }
58
+
59
+ // Boolean type - Yes/No select
60
+ if (columnType === 'boolean') {
61
+ return (
62
+ <FormControl
63
+ size="small"
64
+ sx={{
65
+ flex: 1,
66
+ minWidth: 120,
67
+ ...containerSx,
68
+ }}
69
+ {...formControlProps}
70
+ >
71
+ <InputLabel>Value</InputLabel>
72
+ <Select
73
+ value={filter.value || 'any'}
74
+ label="Value"
75
+ onChange={(e) => onValueChange(e.target.value)}
76
+ {...selectProps}
77
+ >
78
+ <MenuItem
79
+ key={'any'}
80
+ value={'any'}
81
+ >
82
+ Any
83
+ </MenuItem>
84
+ <MenuItem
85
+ key={'true'}
86
+ value={'true'}
87
+ >
88
+ True
89
+ </MenuItem>
90
+ <MenuItem
91
+ key={'false'}
92
+ value={'false'}
93
+ >
94
+ False
95
+ </MenuItem>
96
+ </Select>
97
+ </FormControl>
98
+ );
99
+ }
100
+
101
+ // Select type with options
102
+ if (options && options.length > 0) {
103
+ // Multi-select for 'in' operator
104
+ if (operator === 'in') {
105
+ const currentValue = Array.isArray(filter.value) ? filter.value : [];
106
+
107
+ return (
108
+ <FormControl
109
+ size="small"
110
+ sx={{
111
+ flex: 1,
112
+ minWidth: 120,
113
+ ...containerSx,
114
+ }}
115
+ {...formControlProps}
116
+ >
117
+ <InputLabel>Values</InputLabel>
118
+ <Select
119
+ multiple
120
+ value={currentValue}
121
+ label="Values"
122
+ onChange={(e) => onValueChange(e.target.value)}
123
+ renderValue={(selected) => (selected as string[]).join(', ')}
124
+ {...selectProps}
125
+ >
126
+ {options.map(option => (
127
+ <MenuItem key={String(option.value)} value={option.value}>
128
+ <Checkbox checked={currentValue.includes(option.value)} />
129
+ <ListItemText primary={option.label} />
130
+ </MenuItem>
131
+ ))}
132
+ </Select>
133
+ </FormControl>
134
+ );
135
+ }
136
+ // Single select for other operators
137
+ return (
138
+ <FormControl
139
+ size="small"
140
+ sx={{
141
+ flex: 1,
142
+ minWidth: 120,
143
+ ...containerSx,
144
+ }}
145
+ {...formControlProps}
146
+ >
147
+ <InputLabel>Value</InputLabel>
148
+ <Select
149
+ value={filter.value}
150
+ label="Value"
151
+ onChange={(e) => onValueChange(e.target.value)}
152
+ {...selectProps}
153
+ >
154
+ {options.map(option => (
155
+ <MenuItem key={String(option.value)} value={option.value}>
156
+ {option.label}
157
+ </MenuItem>
158
+ ))}
159
+ </Select>
160
+ </FormControl>
161
+ );
162
+ }
163
+
164
+ // Date type
165
+ if (columnType === 'date') {
166
+ // Only single date picker, no 'between' support
167
+ return (
168
+ <LocalizationProvider dateAdapter={AdapterMoment}>
169
+ <DatePicker
170
+ value={filter.value ? moment(filter.value) : null}
171
+ onChange={(e) => onValueChange(e?.toDate())}
172
+ slotProps={{
173
+ textField: {
174
+ size: 'small',
175
+ label: 'Value',
176
+ sx: {
177
+ flex: 1,
178
+ minWidth: 120,
179
+ ...containerSx,
180
+ },
181
+ ...textFieldProps,
182
+ },
183
+ }}
184
+ {...datePickerProps}
185
+ />
186
+ </LocalizationProvider>
187
+ );
188
+ }
189
+
190
+ // Number type
191
+ if (columnType === 'number') {
192
+ // Only single number input, no 'between' support
193
+ return (
194
+ <TextField
195
+ size="small"
196
+ label="Value"
197
+ value={filter.value}
198
+ onChange={(e) => onValueChange(e.target.value)}
199
+ type="number"
200
+ sx={{
201
+ flex: 1,
202
+ minWidth: 120,
203
+ ...containerSx,
204
+ }}
205
+ {...textFieldProps}
206
+ />
207
+ );
208
+ }
209
+
210
+ // Default: text input
211
+ return (
212
+ <TextField
213
+ size="small"
214
+ label="Value"
215
+ value={filter.value}
216
+ onChange={(e) => onValueChange(e.target.value)}
217
+ sx={{
218
+ flex: 1,
219
+ minWidth: 120,
220
+ ...containerSx,
221
+ }}
222
+ {...textFieldProps}
223
+ />
224
+ );
225
+ }
@@ -1,8 +1,4 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.FILTER_OPERATORS = void 0;
4
- const tslib_1 = require("tslib");
5
- exports.FILTER_OPERATORS = {
1
+ export const FILTER_OPERATORS = {
6
2
  text: [
7
3
  {
8
4
  value: 'contains',
@@ -126,4 +122,5 @@ exports.FILTER_OPERATORS = {
126
122
  },
127
123
  ],
128
124
  };
129
- tslib_1.__exportStar(require("./filter-value-input"), exports);
125
+
126
+ export * from './filter-value-input';
@@ -0,0 +1,326 @@
1
+ import { ArrowUpwardOutlined, ArrowDownwardOutlined } from '@mui/icons-material';
2
+ import { Box, SxProps } from '@mui/material';
3
+ import { Header, flexRender } from '@tanstack/react-table';
4
+ import React, { useState, useRef, useCallback, useMemo } from 'react';
5
+
6
+ import { getSlotComponent, mergeSlotProps, extractSlotProps } from '../../utils/slot-helpers';
7
+
8
+ interface DraggableHeaderProps<T> {
9
+ header: Header<T, unknown>;
10
+ enableSorting?: boolean;
11
+ draggable?: boolean;
12
+ onColumnReorder?: (draggedColumnId: string, targetColumnId: string) => void;
13
+ // Enhanced customization props
14
+ containerSx?: SxProps;
15
+ sortIconProps?: any;
16
+ alignment?: 'left' | 'center' | 'right';
17
+ slots?: Record<string, any>;
18
+ slotProps?: Record<string, any>;
19
+ [key: string]: any;
20
+ }
21
+
22
+ export function DraggableHeader<T>(props: DraggableHeaderProps<T>) {
23
+ const {
24
+ header,
25
+ enableSorting = true,
26
+ draggable = false,
27
+ onColumnReorder,
28
+ containerSx,
29
+ sortIconProps,
30
+ alignment,
31
+ slots,
32
+ slotProps,
33
+ ...otherProps
34
+ } = props;
35
+
36
+ const [isDragging, setIsDragging] = useState(false);
37
+ const [dragOver, setDragOver] = useState(false);
38
+ const autoScrollIntervalRef = useRef<NodeJS.Timeout | null>(null);
39
+ const dragStartPositionRef = useRef<{ x: number; y: number } | null>(null);
40
+ const headerElementRef = useRef<HTMLDivElement>(null);
41
+
42
+ // Extract slot-specific props with enhanced merging
43
+ const sortIconAscSlotProps = extractSlotProps(slotProps, 'sortIconAsc');
44
+ const sortIconDescSlotProps = extractSlotProps(slotProps, 'sortIconDesc');
45
+
46
+ const SortIconAscSlot = getSlotComponent(slots, 'sortIconAsc', ArrowUpwardOutlined);
47
+ const SortIconDescSlot = getSlotComponent(slots, 'sortIconDesc', ArrowDownwardOutlined);
48
+
49
+ // Auto-scroll configuration
50
+ const AUTO_SCROLL_THRESHOLD = 50; // Distance from edge to trigger scroll
51
+ const AUTO_SCROLL_SPEED = 10; // Pixels per scroll interval
52
+ const AUTO_SCROLL_INTERVAL = 16; // ~60fps
53
+
54
+ const justifyContent = useMemo(() => {
55
+ return alignment === 'left' ? 'flex-start' : alignment === 'right' ? 'flex-end' : 'center';
56
+ }, [alignment]);
57
+
58
+ const findScrollableContainer = useCallback((element?: HTMLElement): HTMLElement | null => {
59
+ // Start from the provided element or try to find the current table
60
+ let searchElement = element;
61
+
62
+ if (!searchElement) {
63
+ // Start from the header element if available
64
+ if (headerElementRef.current) {
65
+ searchElement = headerElementRef.current.closest('table') as HTMLElement;
66
+ }
67
+ }
68
+
69
+ if (!searchElement) {
70
+ // Find the table that contains our header
71
+ const tables = Array.from(document.querySelectorAll('table'));
72
+ for (const table of tables) {
73
+ // Check if this table contains a header with our ID
74
+ const headerExists = table.querySelector('th'); // fallback
75
+ if (headerExists) {
76
+ searchElement = table;
77
+ break;
78
+ }
79
+ }
80
+ }
81
+
82
+ if (!searchElement) {
83
+ // Last resort: use the first table found
84
+ searchElement = document.querySelector('table') as HTMLElement;
85
+ }
86
+
87
+ if (!searchElement) return null;
88
+
89
+ // Walk up the DOM tree to find the scrollable container
90
+ let container: HTMLElement | null = searchElement;
91
+ while (container && container !== document.body) {
92
+ const styles = window.getComputedStyle(container);
93
+ if (styles.overflowX === 'auto' || styles.overflowX === 'scroll') {
94
+ return container;
95
+ }
96
+ container = container.parentElement;
97
+ }
98
+
99
+ return null;
100
+ }, []);
101
+
102
+ const startAutoScroll = useCallback((direction: 'left' | 'right') => {
103
+ if (autoScrollIntervalRef.current) {
104
+ clearInterval(autoScrollIntervalRef.current);
105
+ }
106
+
107
+ const container = findScrollableContainer();
108
+ if (!container) return;
109
+
110
+ autoScrollIntervalRef.current = setInterval(() => {
111
+ const scrollAmount = direction === 'left' ? -AUTO_SCROLL_SPEED : AUTO_SCROLL_SPEED;
112
+ const newScrollLeft = container.scrollLeft + scrollAmount;
113
+
114
+ // Check bounds
115
+ if (direction === 'left' && newScrollLeft <= 0) {
116
+ container.scrollLeft = 0;
117
+ clearInterval(autoScrollIntervalRef.current!);
118
+ autoScrollIntervalRef.current = null;
119
+ } else if (direction === 'right' && newScrollLeft >= container.scrollWidth - container.clientWidth) {
120
+ container.scrollLeft = container.scrollWidth - container.clientWidth;
121
+ clearInterval(autoScrollIntervalRef.current!);
122
+ autoScrollIntervalRef.current = null;
123
+ } else {
124
+ container.scrollLeft = newScrollLeft;
125
+ }
126
+ }, AUTO_SCROLL_INTERVAL);
127
+ }, [findScrollableContainer]);
128
+
129
+ const stopAutoScroll = useCallback(() => {
130
+ if (autoScrollIntervalRef.current) {
131
+ clearInterval(autoScrollIntervalRef.current);
132
+ autoScrollIntervalRef.current = null;
133
+ }
134
+ }, []);
135
+
136
+ const checkAutoScroll = useCallback((clientX: number) => {
137
+ const container = findScrollableContainer();
138
+ if (!container) return;
139
+
140
+ const containerRect = container.getBoundingClientRect();
141
+ const leftEdge = containerRect.left + AUTO_SCROLL_THRESHOLD;
142
+ const rightEdge = containerRect.right - AUTO_SCROLL_THRESHOLD;
143
+
144
+ if (clientX < leftEdge) {
145
+ startAutoScroll('left');
146
+ } else if (clientX > rightEdge) {
147
+ startAutoScroll('right');
148
+ } else {
149
+ stopAutoScroll();
150
+ }
151
+ }, [findScrollableContainer, startAutoScroll, stopAutoScroll]);
152
+
153
+ const handleDragStart = (e: React.DragEvent) => {
154
+ if (!draggable) return;
155
+
156
+ e.dataTransfer.setData('text/plain', header.id);
157
+ e.dataTransfer.effectAllowed = 'move';
158
+ setIsDragging(true);
159
+ dragStartPositionRef.current = { x: e.clientX, y: e.clientY };
160
+ };
161
+
162
+ const handleDrag = (e: React.DragEvent) => {
163
+ if (!draggable || !dragStartPositionRef.current) return;
164
+ checkAutoScroll(e.clientX);
165
+ };
166
+
167
+ const getSortIcon = () => {
168
+ if (!enableSorting) return null;
169
+ const sortDirection = header.column.getIsSorted();
170
+
171
+ const mergedSortIconProps = mergeSlotProps(
172
+ {
173
+ fontSize: 'small',
174
+ },
175
+ sortIconProps || {}
176
+ );
177
+
178
+ // Only show icons when column is actually sorted
179
+ if (sortDirection === 'asc') {
180
+ return (
181
+ <SortIconAscSlot
182
+ {...mergeSlotProps(
183
+ mergedSortIconProps,
184
+ sortIconAscSlotProps
185
+ )}
186
+ />
187
+ );
188
+ } if (sortDirection === 'desc') {
189
+ return (
190
+ <SortIconDescSlot
191
+ {...mergeSlotProps(
192
+ mergedSortIconProps,
193
+ sortIconDescSlotProps
194
+ )}
195
+ />
196
+ );
197
+ }
198
+ // Don't show any icon when not sorted
199
+ return null;
200
+ };
201
+
202
+ const handleDragEnd = () => {
203
+ setIsDragging(false);
204
+ setDragOver(false);
205
+ stopAutoScroll();
206
+ dragStartPositionRef.current = null;
207
+ };
208
+
209
+ const handleDragOver = (e: React.DragEvent) => {
210
+ if (!draggable) return;
211
+
212
+ e.preventDefault();
213
+ e.dataTransfer.dropEffect = 'move';
214
+ setDragOver(true);
215
+
216
+ // Check for auto-scroll during drag over
217
+ checkAutoScroll(e.clientX);
218
+ };
219
+
220
+ const handleDragLeave = () => {
221
+ setDragOver(false);
222
+ // Don't stop auto-scroll on drag leave as the drag might continue outside this element
223
+ };
224
+
225
+ const handleDrop = (e: React.DragEvent) => {
226
+ if (!draggable) return;
227
+
228
+ e.preventDefault();
229
+ const draggedColumnId = e.dataTransfer.getData('text/plain');
230
+ if (draggedColumnId !== header.id && onColumnReorder) {
231
+ onColumnReorder(draggedColumnId, header.id);
232
+ }
233
+
234
+ setDragOver(false);
235
+ stopAutoScroll();
236
+ };
237
+
238
+ const handleSort = () => {
239
+ if (!enableSorting || !header.column.getCanSort()) return;
240
+
241
+ const currentSort = header.column.getIsSorted();
242
+ if (currentSort === false) {
243
+ header.column.toggleSorting(false); // asc
244
+ } else if (currentSort === 'asc') {
245
+ header.column.toggleSorting(true); // desc
246
+ } else {
247
+ header.column.clearSorting(); // none
248
+ }
249
+ };
250
+
251
+ const getCursor = () => {
252
+ if (draggable) return 'grab';
253
+ if (enableSorting && header.column.getCanSort()) return 'pointer';
254
+ return 'default';
255
+ };
256
+
257
+ // Merge all props for maximum flexibility
258
+ const mergedContainerProps = mergeSlotProps(
259
+ {
260
+ ref: headerElementRef,
261
+ sx: {
262
+ display: 'flex',
263
+ alignItems: 'center',
264
+ justifyContent: justifyContent,
265
+ gap: 1,
266
+ cursor: getCursor(),
267
+ userSelect: 'none',
268
+ opacity: isDragging ? 0.5 : 1,
269
+ backgroundColor: dragOver ? 'rgba(25, 118, 210, 0.08)' : 'transparent',
270
+ borderLeft: dragOver ? '2px solid #1976d2' : 'none',
271
+ padding: dragOver ? '0 0 0 -2px' : '0',
272
+ width: '100%',
273
+ height: '100%',
274
+ minWidth: '0',
275
+ '&:active': {
276
+ cursor: draggable ? 'grabbing' : 'pointer',
277
+ },
278
+ '.header-content': {
279
+ display: 'block',
280
+ flex: 1,
281
+ minWidth: 0,
282
+ overflow: 'hidden',
283
+ whiteSpace: 'nowrap',
284
+ textOverflow: 'ellipsis',
285
+ },
286
+ ...containerSx,
287
+ },
288
+ draggable: draggable,
289
+ onDragStart: handleDragStart,
290
+ onDrag: handleDrag,
291
+ onDragEnd: handleDragEnd,
292
+ onDragOver: handleDragOver,
293
+ onDragLeave: handleDragLeave,
294
+ onDrop: handleDrop,
295
+ onClick: enableSorting ? handleSort : undefined,
296
+ },
297
+ otherProps
298
+ );
299
+
300
+ if (!draggable && !enableSorting) {
301
+ return flexRender(header.column.columnDef.header, header.getContext());
302
+ }
303
+
304
+ return (
305
+ <Box
306
+ {...mergedContainerProps}
307
+ >
308
+ <Box
309
+ component="span"
310
+ className='header-wrapper'
311
+ sx={{
312
+ display: 'inline-flex',
313
+ gap: 1,
314
+ }}
315
+ >
316
+ <Box component="span" className='header-content'>
317
+ {flexRender(header.column.columnDef.header, header.getContext())}
318
+ </Box>
319
+ {getSortIcon()}
320
+ </Box>
321
+ </Box>
322
+ );
323
+ }
324
+
325
+ // Memoize component to prevent unnecessary re-renders
326
+ export const DraggableHeaderMemo = React.memo(DraggableHeader) as typeof DraggableHeader;
@@ -1,2 +1,6 @@
1
+ /**
2
+ * Header components for DataTable
3
+ */
4
+
1
5
  export * from './table-header';
2
6
  export * from './draggable-header';