@dmsi/wedgekit-react 0.0.2

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 (263) hide show
  1. package/README.md +35 -0
  2. package/dist/chunk-27KIIUAR.js +59 -0
  3. package/dist/chunk-2G2E2JMA.js +123 -0
  4. package/dist/chunk-4C66DLIJ.js +51 -0
  5. package/dist/chunk-4RD5ZF2V.js +55 -0
  6. package/dist/chunk-4RJKB7LC.js +14 -0
  7. package/dist/chunk-4T7F5BZZ.js +26 -0
  8. package/dist/chunk-5GOBP2JS.js +53 -0
  9. package/dist/chunk-6ZY524ID.js +42 -0
  10. package/dist/chunk-AWQSSKCK.js +32 -0
  11. package/dist/chunk-BNHSAFMP.js +93 -0
  12. package/dist/chunk-BWRHL2AG.js +439 -0
  13. package/dist/chunk-DKKYR6DS.js +132 -0
  14. package/dist/chunk-E5ALT5W7.js +182 -0
  15. package/dist/chunk-FY7PTP6E.js +322 -0
  16. package/dist/chunk-GTCSRHPF.js +119 -0
  17. package/dist/chunk-I2UVVKQI.js +12 -0
  18. package/dist/chunk-IGQVA7SC.js +41 -0
  19. package/dist/chunk-K3IKUSZW.js +59 -0
  20. package/dist/chunk-KENSVWOY.js +151 -0
  21. package/dist/chunk-KX3O6GJ6.js +138 -0
  22. package/dist/chunk-L4UM372R.js +253 -0
  23. package/dist/chunk-ORMEWXMH.js +37 -0
  24. package/dist/chunk-Q3FKEKIN.js +23 -0
  25. package/dist/chunk-SEKKGFM6.js +28 -0
  26. package/dist/chunk-SY3HT54E.js +91 -0
  27. package/dist/chunk-TAW5ZZ4Z.js +346 -0
  28. package/dist/chunk-TRUPPHBQ.js +109 -0
  29. package/dist/chunk-TU55CHXU.js +30 -0
  30. package/dist/chunk-TWZZB4WO.js +114 -0
  31. package/dist/chunk-TYI74BSP.js +62 -0
  32. package/dist/chunk-U42SKNR6.js +104 -0
  33. package/dist/chunk-UU3FA6LV.js +72 -0
  34. package/dist/chunk-WVUIIBRR.js +51 -0
  35. package/dist/chunk-XUIPGYP5.js +39 -0
  36. package/dist/chunk-Z4UCFUF7.js +299 -0
  37. package/dist/components/Breadcrumbs.cjs +376 -0
  38. package/dist/components/Breadcrumbs.js +90 -0
  39. package/dist/components/Button.cjs +319 -0
  40. package/dist/components/Button.js +8 -0
  41. package/dist/components/CalendarRange.cjs +520 -0
  42. package/dist/components/CalendarRange.js +13 -0
  43. package/dist/components/Caption.cjs +283 -0
  44. package/dist/components/Caption.js +80 -0
  45. package/dist/components/Checkbox.cjs +378 -0
  46. package/dist/components/Checkbox.js +11 -0
  47. package/dist/components/ContentTab.cjs +382 -0
  48. package/dist/components/ContentTab.js +10 -0
  49. package/dist/components/ContentTabs.cjs +472 -0
  50. package/dist/components/ContentTabs.js +98 -0
  51. package/dist/components/DMSiLogo.cjs +79 -0
  52. package/dist/components/DMSiLogo.js +56 -0
  53. package/dist/components/DataGrid.cjs +3113 -0
  54. package/dist/components/DataGrid.js +758 -0
  55. package/dist/components/DataGridCell.cjs +1907 -0
  56. package/dist/components/DataGridCell.js +24 -0
  57. package/dist/components/DataTable.cjs +791 -0
  58. package/dist/components/DataTable.js +720 -0
  59. package/dist/components/DateInput.cjs +1130 -0
  60. package/dist/components/DateInput.js +170 -0
  61. package/dist/components/DateRangeInput.cjs +1131 -0
  62. package/dist/components/DateRangeInput.js +171 -0
  63. package/dist/components/DebugJson.cjs +50 -0
  64. package/dist/components/DebugJson.js +27 -0
  65. package/dist/components/Display.cjs +234 -0
  66. package/dist/components/Display.js +12 -0
  67. package/dist/components/EditingContext.cjs +73 -0
  68. package/dist/components/EditingContext.js +35 -0
  69. package/dist/components/FilterGroup.cjs +1431 -0
  70. package/dist/components/FilterGroup.js +231 -0
  71. package/dist/components/FullViewportBox.cjs +35 -0
  72. package/dist/components/FullViewportBox.js +12 -0
  73. package/dist/components/Grid.cjs +69 -0
  74. package/dist/components/Grid.js +36 -0
  75. package/dist/components/GridContainer.cjs +125 -0
  76. package/dist/components/GridContainer.js +92 -0
  77. package/dist/components/Heading.cjs +238 -0
  78. package/dist/components/Heading.js +14 -0
  79. package/dist/components/HorizontalDivider.cjs +33 -0
  80. package/dist/components/HorizontalDivider.js +10 -0
  81. package/dist/components/Icon.cjs +98 -0
  82. package/dist/components/Icon.js +7 -0
  83. package/dist/components/Input.cjs +672 -0
  84. package/dist/components/Input.js +21 -0
  85. package/dist/components/InputGroup.cjs +270 -0
  86. package/dist/components/InputGroup.js +60 -0
  87. package/dist/components/Label.cjs +223 -0
  88. package/dist/components/Label.js +8 -0
  89. package/dist/components/Link.cjs +262 -0
  90. package/dist/components/Link.js +8 -0
  91. package/dist/components/List.cjs +37 -0
  92. package/dist/components/List.js +14 -0
  93. package/dist/components/LiveChatComponent.cjs +63 -0
  94. package/dist/components/LiveChatComponent.js +40 -0
  95. package/dist/components/LogoAgilityTopBar.cjs +115 -0
  96. package/dist/components/LogoAgilityTopBar.js +92 -0
  97. package/dist/components/LogoDMSiTopBar.cjs +79 -0
  98. package/dist/components/LogoDMSiTopBar.js +7 -0
  99. package/dist/components/LogoMillworkTopBar.cjs +221 -0
  100. package/dist/components/LogoMillworkTopBar.js +198 -0
  101. package/dist/components/MainBar.cjs +211 -0
  102. package/dist/components/MainBar.js +65 -0
  103. package/dist/components/Menu.cjs +437 -0
  104. package/dist/components/Menu.js +11 -0
  105. package/dist/components/MenuOption.cjs +483 -0
  106. package/dist/components/MenuOption.js +13 -0
  107. package/dist/components/MobileDataGrid.cjs +658 -0
  108. package/dist/components/MobileDataGrid.js +125 -0
  109. package/dist/components/Modal.cjs +783 -0
  110. package/dist/components/Modal.js +245 -0
  111. package/dist/components/ModalButtons.cjs +385 -0
  112. package/dist/components/ModalButtons.js +10 -0
  113. package/dist/components/ModalContent.cjs +57 -0
  114. package/dist/components/ModalContent.js +7 -0
  115. package/dist/components/ModalHeader.cjs +426 -0
  116. package/dist/components/ModalHeader.js +11 -0
  117. package/dist/components/ModalScrim.cjs +64 -0
  118. package/dist/components/ModalScrim.js +7 -0
  119. package/dist/components/NavigationTab.cjs +431 -0
  120. package/dist/components/NavigationTab.js +10 -0
  121. package/dist/components/NavigationTabs.cjs +477 -0
  122. package/dist/components/NavigationTabs.js +56 -0
  123. package/dist/components/Notification.cjs +640 -0
  124. package/dist/components/Notification.js +117 -0
  125. package/dist/components/OptionPill.cjs +478 -0
  126. package/dist/components/OptionPill.js +11 -0
  127. package/dist/components/Paragraph.cjs +231 -0
  128. package/dist/components/Paragraph.js +8 -0
  129. package/dist/components/Password.cjs +700 -0
  130. package/dist/components/Password.js +53 -0
  131. package/dist/components/ProjectBar.cjs +242 -0
  132. package/dist/components/ProjectBar.js +63 -0
  133. package/dist/components/Radio.cjs +349 -0
  134. package/dist/components/Radio.js +131 -0
  135. package/dist/components/Search.cjs +767 -0
  136. package/dist/components/Search.js +12 -0
  137. package/dist/components/Select.cjs +758 -0
  138. package/dist/components/Select.js +12 -0
  139. package/dist/components/SideMenu.cjs +54 -0
  140. package/dist/components/SideMenu.js +21 -0
  141. package/dist/components/SideMenuGroup.cjs +422 -0
  142. package/dist/components/SideMenuGroup.js +83 -0
  143. package/dist/components/SideMenuItem.cjs +388 -0
  144. package/dist/components/SideMenuItem.js +70 -0
  145. package/dist/components/Stack.cjs +138 -0
  146. package/dist/components/Stack.js +7 -0
  147. package/dist/components/StatusPill.cjs +265 -0
  148. package/dist/components/StatusPill.js +52 -0
  149. package/dist/components/Stepper.cjs +885 -0
  150. package/dist/components/Stepper.js +105 -0
  151. package/dist/components/Subheader.cjs +226 -0
  152. package/dist/components/Subheader.js +8 -0
  153. package/dist/components/Surface.cjs +98 -0
  154. package/dist/components/Surface.js +40 -0
  155. package/dist/components/Swatch.cjs +1728 -0
  156. package/dist/components/Swatch.js +1319 -0
  157. package/dist/components/Textarea.cjs +269 -0
  158. package/dist/components/Textarea.js +96 -0
  159. package/dist/components/Theme.cjs +36 -0
  160. package/dist/components/Theme.js +7 -0
  161. package/dist/components/Time.cjs +1118 -0
  162. package/dist/components/Time.js +353 -0
  163. package/dist/components/Toast.cjs +644 -0
  164. package/dist/components/Toast.js +218 -0
  165. package/dist/components/Tooltip.cjs +273 -0
  166. package/dist/components/Tooltip.js +9 -0
  167. package/dist/components/TopBar.cjs +352 -0
  168. package/dist/components/TopBar.js +132 -0
  169. package/dist/components/useInfiniteScroll.cjs +57 -0
  170. package/dist/components/useInfiniteScroll.js +8 -0
  171. package/dist/components/useMatchesMedia.cjs +53 -0
  172. package/dist/components/useMatchesMedia.js +9 -0
  173. package/dist/components/useMenuSystem.cjs +358 -0
  174. package/dist/components/useMenuSystem.js +11 -0
  175. package/dist/components/useMounted.cjs +39 -0
  176. package/dist/components/useMounted.js +8 -0
  177. package/dist/fonts.css +21 -0
  178. package/dist/icons-light[FILL]-PPZXOLWS.woff2 +0 -0
  179. package/dist/icons-normal[FILL]-PPZXOLWS.woff2 +0 -0
  180. package/dist/index.css +4401 -0
  181. package/dist/open-sans-55T6A4JE.woff2 +0 -0
  182. package/dist/types.cjs +18 -0
  183. package/dist/types.js +0 -0
  184. package/package.json +66 -0
  185. package/src/brand.css +125 -0
  186. package/src/classNames.ts +144 -0
  187. package/src/components/Breadcrumbs.tsx +116 -0
  188. package/src/components/Button.tsx +210 -0
  189. package/src/components/CalendarRange.tsx +429 -0
  190. package/src/components/Caption.tsx +101 -0
  191. package/src/components/Checkbox.tsx +196 -0
  192. package/src/components/ContentTab.tsx +66 -0
  193. package/src/components/ContentTabs.tsx +103 -0
  194. package/src/components/DMSiLogo.tsx +32 -0
  195. package/src/components/DataGrid.tsx +948 -0
  196. package/src/components/DataGridCell.tsx +384 -0
  197. package/src/components/DataTable.tsx +835 -0
  198. package/src/components/DateInput.tsx +188 -0
  199. package/src/components/DateRangeInput.tsx +179 -0
  200. package/src/components/DebugJson.tsx +24 -0
  201. package/src/components/Display.tsx +60 -0
  202. package/src/components/EditingContext.tsx +40 -0
  203. package/src/components/FilterGroup.tsx +234 -0
  204. package/src/components/FullViewportBox.tsx +11 -0
  205. package/src/components/Grid.tsx +75 -0
  206. package/src/components/GridContainer.tsx +124 -0
  207. package/src/components/Heading.tsx +66 -0
  208. package/src/components/HorizontalDivider.tsx +3 -0
  209. package/src/components/Icon.tsx +36 -0
  210. package/src/components/Input.tsx +511 -0
  211. package/src/components/InputGroup.tsx +51 -0
  212. package/src/components/Label.tsx +40 -0
  213. package/src/components/Link.tsx +106 -0
  214. package/src/components/List.tsx +10 -0
  215. package/src/components/LiveChatComponent.tsx +56 -0
  216. package/src/components/LogoAgilityTopBar.tsx +53 -0
  217. package/src/components/LogoDMSiTopBar.tsx +32 -0
  218. package/src/components/LogoMillworkTopBar.tsx +118 -0
  219. package/src/components/MainBar.tsx +83 -0
  220. package/src/components/Menu.tsx +286 -0
  221. package/src/components/MenuOption.tsx +275 -0
  222. package/src/components/MobileDataGrid.tsx +135 -0
  223. package/src/components/Modal.tsx +271 -0
  224. package/src/components/ModalButtons.tsx +44 -0
  225. package/src/components/ModalContent.tsx +23 -0
  226. package/src/components/ModalHeader.tsx +41 -0
  227. package/src/components/ModalScrim.tsx +35 -0
  228. package/src/components/NavigationTab.tsx +89 -0
  229. package/src/components/NavigationTabs.tsx +63 -0
  230. package/src/components/Notification.tsx +120 -0
  231. package/src/components/OptionPill.tsx +114 -0
  232. package/src/components/Paragraph.tsx +49 -0
  233. package/src/components/Password.tsx +46 -0
  234. package/src/components/ProjectBar.tsx +76 -0
  235. package/src/components/Radio.tsx +140 -0
  236. package/src/components/Search.tsx +129 -0
  237. package/src/components/Select.tsx +104 -0
  238. package/src/components/SideMenu.tsx +21 -0
  239. package/src/components/SideMenuGroup.tsx +81 -0
  240. package/src/components/SideMenuItem.tsx +90 -0
  241. package/src/components/Stack.tsx +179 -0
  242. package/src/components/StatusPill.tsx +51 -0
  243. package/src/components/Stepper.tsx +91 -0
  244. package/src/components/Subheader.tsx +44 -0
  245. package/src/components/Surface.tsx +34 -0
  246. package/src/components/Swatch.tsx +1066 -0
  247. package/src/components/Textarea.tsx +101 -0
  248. package/src/components/Theme.tsx +13 -0
  249. package/src/components/Time.tsx +438 -0
  250. package/src/components/Toast.tsx +244 -0
  251. package/src/components/Tooltip.tsx +137 -0
  252. package/src/components/TopBar.tsx +124 -0
  253. package/src/components/useInfiniteScroll.tsx +40 -0
  254. package/src/components/useMatchesMedia.tsx +28 -0
  255. package/src/components/useMenuSystem.tsx +367 -0
  256. package/src/components/useMounted.tsx +14 -0
  257. package/src/darkmode.css +140 -0
  258. package/src/fonts.css +23 -0
  259. package/src/index.css +509 -0
  260. package/src/index.tsx +2 -0
  261. package/src/types.ts +149 -0
  262. package/src/utils/formatting.tsx +81 -0
  263. package/src/utils.ts +23 -0
@@ -0,0 +1,948 @@
1
+ "use client";
2
+
3
+ import React, { ReactNode, useCallback, useId, useRef, useState } from "react";
4
+
5
+ // TanStack Table
6
+ import {
7
+ Column,
8
+ ColumnDef,
9
+ ColumnFiltersState,
10
+ FilterFn,
11
+ flexRender,
12
+ getCoreRowModel,
13
+ getFilteredRowModel,
14
+ getSortedRowModel,
15
+ Header,
16
+ PartialKeys,
17
+ RowData,
18
+ SortDirection,
19
+ SortingState,
20
+ Table,
21
+ TableOptionsResolved,
22
+ useReactTable,
23
+ } from "@tanstack/react-table";
24
+
25
+ import {
26
+ useVirtualizer,
27
+ VirtualItem,
28
+ Virtualizer,
29
+ } from "@tanstack/react-virtual";
30
+
31
+ // DnD Kit
32
+ import {
33
+ closestCenter,
34
+ DndContext,
35
+ DragEndEvent,
36
+ KeyboardSensor,
37
+ MouseSensor,
38
+ TouchSensor,
39
+ useSensor,
40
+ useSensors,
41
+ } from "@dnd-kit/core";
42
+ import {
43
+ arrayMove,
44
+ horizontalListSortingStrategy,
45
+ SortableContext,
46
+ } from "@dnd-kit/sortable";
47
+ import { restrictToHorizontalAxis } from "@dnd-kit/modifiers";
48
+
49
+ // UI Components
50
+ import { Button } from "./Button";
51
+ import { Checkbox } from "./Checkbox";
52
+ import {
53
+ DataGridCell,
54
+ DragAlongCell,
55
+ DraggableCellHeader,
56
+ } from "./DataGridCell";
57
+ import { Icon } from "./Icon";
58
+ import { Input } from "./Input";
59
+ import { Search } from "./Search";
60
+ import { Label } from "./Label";
61
+ import { Menu } from "./Menu";
62
+ import { MenuOption } from "./MenuOption";
63
+ import { Paragraph } from "./Paragraph";
64
+ import { Select } from "./Select";
65
+ import { Subheader } from "./Subheader";
66
+ import { Tooltip } from "./Tooltip";
67
+
68
+ // Utils & Hooks
69
+ import { useInfiniteScroll } from "./useInfiniteScroll";
70
+ import { componentGap, componentPadding } from "../classNames";
71
+ import clsx from "clsx";
72
+ import { Row } from "@tanstack/react-table";
73
+
74
+ // Constants
75
+ const PAGE_SIZE_OPTIONS = [5, 10, 15, 20, 25, 30, 35];
76
+ const NO_RESULTS_HEIGHT = "h-[120px]";
77
+
78
+ function adaptTableStateSetter<T>(
79
+ setter: React.Dispatch<React.SetStateAction<T>>,
80
+ ) {
81
+ return (valueOrFn: T | ((prev: T) => T)) => {
82
+ setter((prev) =>
83
+ typeof valueOrFn === "function"
84
+ ? (valueOrFn as (prev: T) => T)(prev)
85
+ : valueOrFn,
86
+ );
87
+ };
88
+ }
89
+
90
+ // Types
91
+ export interface DataGridPagination {
92
+ pageIndex: number;
93
+ pageSize: number;
94
+ total: number;
95
+ onPageChange: (pageIndex: number) => void;
96
+ onPageSizeChange?: (pageSize: number) => void;
97
+ }
98
+
99
+ export interface DataGridProps<T extends Record<string, unknown>> {
100
+ data: T[];
101
+ columns: ColumnDef<T>[];
102
+ status?: string;
103
+ locked?: boolean;
104
+ isLoadingMore?: boolean;
105
+ onLoadMore?: () => void;
106
+ hasMore?: boolean;
107
+ pagination?: DataGridPagination;
108
+ showFilterRow?: boolean;
109
+ sorting?: SortingState;
110
+ onSortingChange?: (state: SortingState) => void;
111
+ columnFilters?: ColumnFiltersState;
112
+ onColumnFiltersChange?: (filters: ColumnFiltersState) => void;
113
+ rowSelection?: Record<string, boolean>;
114
+ onRowSelectionChange?: (selection: Record<string, boolean>) => void;
115
+ filteredSortedData?: T[];
116
+ totalRowCount: number;
117
+ hideStatusBar?: boolean;
118
+ centerHeader?: boolean;
119
+ enableColumnSelector?: boolean;
120
+ }
121
+
122
+ export function DataGrid<T extends Record<string, unknown>>({
123
+ data,
124
+ columns,
125
+ status,
126
+ isLoadingMore = false,
127
+ onLoadMore,
128
+ pagination,
129
+ showFilterRow = false,
130
+ hasMore = false,
131
+ sorting: externalSorting,
132
+ onSortingChange,
133
+ columnFilters: externalColumnFilters,
134
+ onColumnFiltersChange,
135
+ rowSelection: externalRowSelection,
136
+ onRowSelectionChange,
137
+ filteredSortedData,
138
+ totalRowCount,
139
+ hideStatusBar,
140
+ centerHeader,
141
+ enableColumnSelector,
142
+ }: DataGridProps<T>) {
143
+ const [columnOrder, setColumnOrder] = useState<string[]>(() =>
144
+ columns.map((c) => c.id!),
145
+ );
146
+ const [localSorting, setLocalSorting] = useState<SortingState>([]);
147
+ const [localColumnFilters, setLocalColumnFilters] =
148
+ useState<ColumnFiltersState>([]);
149
+ const [localRowSelection, setLocalRowSelection] = useState<
150
+ Record<string, boolean>
151
+ >({});
152
+
153
+ const sortingState = pagination
154
+ ? (externalSorting ?? localSorting)
155
+ : localSorting;
156
+ const setSortingState: React.Dispatch<React.SetStateAction<SortingState>> =
157
+ pagination
158
+ ? (updaterOrValue) => {
159
+ const value =
160
+ typeof updaterOrValue === "function"
161
+ ? (updaterOrValue as (prev: SortingState) => SortingState)(
162
+ externalSorting ?? [],
163
+ )
164
+ : updaterOrValue;
165
+ (onSortingChange ?? setLocalSorting)(value);
166
+ }
167
+ : setLocalSorting;
168
+
169
+ const columnFilterState = pagination
170
+ ? (externalColumnFilters ?? localColumnFilters)
171
+ : localColumnFilters;
172
+
173
+ const setColumnFilterState: React.Dispatch<
174
+ React.SetStateAction<ColumnFiltersState>
175
+ > = pagination
176
+ ? (updaterOrValue) => {
177
+ const value =
178
+ typeof updaterOrValue === "function"
179
+ ? (
180
+ updaterOrValue as (
181
+ prev: ColumnFiltersState,
182
+ ) => ColumnFiltersState
183
+ )(externalColumnFilters ?? [])
184
+ : updaterOrValue;
185
+ (onColumnFiltersChange ?? setLocalColumnFilters)(value);
186
+ }
187
+ : setLocalColumnFilters;
188
+
189
+ const rowSelection = pagination
190
+ ? (externalRowSelection ?? localRowSelection)
191
+ : localRowSelection;
192
+ const setRowSelection: React.Dispatch<
193
+ React.SetStateAction<Record<string, boolean>>
194
+ > = pagination
195
+ ? (updaterOrValue) => {
196
+ const value =
197
+ typeof updaterOrValue === "function"
198
+ ? (
199
+ updaterOrValue as (
200
+ prev: Record<string, boolean>,
201
+ ) => Record<string, boolean>
202
+ )(externalRowSelection ?? {})
203
+ : updaterOrValue;
204
+ (onRowSelectionChange ?? setLocalRowSelection)(value);
205
+ }
206
+ : setLocalRowSelection;
207
+
208
+ const id = useId();
209
+ const containerRef = React.useRef<HTMLDivElement>(null);
210
+
211
+ const [columnVisibility, setColumnVisibility] = useState<
212
+ Record<string, boolean>
213
+ >(() => {
214
+ const initialVisibility: Record<string, boolean> = {};
215
+ columns.forEach((column) => {
216
+ if (column.id) {
217
+ initialVisibility[column.id] = column.meta?.visible ?? true;
218
+ }
219
+ });
220
+ return initialVisibility;
221
+ });
222
+
223
+ const toggleColumnVisibility = useCallback(
224
+ (id: string, isVisible: boolean) => {
225
+ setColumnVisibility((prev) => ({ ...prev, [id]: isVisible }));
226
+ },
227
+ [setColumnVisibility],
228
+ );
229
+
230
+ const resetColumnVisibility = useCallback(() => {
231
+ setColumnVisibility(() => {
232
+ const initialVisibility: Record<string, boolean> = {};
233
+ columns.forEach((column) => {
234
+ if (column.id) {
235
+ initialVisibility[column.id] = column.meta?.visible ?? true;
236
+ }
237
+ });
238
+ return initialVisibility;
239
+ });
240
+ }, [columns]);
241
+
242
+ const table = useReactTable<T>({
243
+ columns,
244
+ data,
245
+ getCoreRowModel: getCoreRowModel(),
246
+ getSortedRowModel: getSortedRowModel(),
247
+ getFilteredRowModel: getFilteredRowModel(),
248
+ columnResizeMode: "onChange",
249
+ getRowId: (row, index) => String(row.id ?? index + 1),
250
+ state: {
251
+ columnOrder,
252
+ sorting: sortingState,
253
+ columnFilters: columnFilterState,
254
+ rowSelection,
255
+ columnVisibility,
256
+ },
257
+ onColumnOrderChange: setColumnOrder,
258
+ onSortingChange: adaptTableStateSetter(setSortingState),
259
+ onColumnFiltersChange: adaptTableStateSetter(setColumnFilterState),
260
+ onRowSelectionChange: adaptTableStateSetter(setRowSelection),
261
+ filterFns: {
262
+ startsWith: (row, columnId, filterValue) =>
263
+ (row.getValue(columnId) as string)
264
+ ?.toLowerCase()
265
+ .startsWith(filterValue.toLowerCase()),
266
+ endsWith: (row, columnId, filterValue) =>
267
+ (row.getValue(columnId) as string)
268
+ ?.toLowerCase()
269
+ .endsWith(filterValue.toLowerCase()),
270
+ },
271
+ });
272
+
273
+ const allRowIds = pagination
274
+ ? (filteredSortedData?.map((row) => String(row.id)) ?? [])
275
+ : Array.from({ length: totalRowCount ?? data.length }, (_, i) =>
276
+ String(i + 1),
277
+ );
278
+
279
+ const allSelectedAcrossPages = allRowIds.every((id) => rowSelection[id]);
280
+ const someSelectedAcrossPages =
281
+ !allSelectedAcrossPages && allRowIds.some((id) => rowSelection[id]);
282
+
283
+ const toggleSelectAllAcrossPages = () => {
284
+ setRowSelection((prev) => {
285
+ const isSelecting = !allSelectedAcrossPages;
286
+
287
+ if (isSelecting) {
288
+ const newSelection: Record<string, boolean> = {};
289
+ for (const id of allRowIds) {
290
+ newSelection[id] = true;
291
+ }
292
+ return { ...prev, ...newSelection };
293
+ } else {
294
+ const updatedSelection: Record<string, boolean> = { ...prev };
295
+ for (const id of allRowIds) {
296
+ delete updatedSelection[id];
297
+ }
298
+ return updatedSelection;
299
+ }
300
+ });
301
+ };
302
+
303
+ useInfiniteScroll({
304
+ containerRef,
305
+ onLoadMore: onLoadMore ?? (() => {}),
306
+ isLoading: isLoadingMore,
307
+ enabled: !pagination,
308
+ });
309
+
310
+ const handleDragEnd = (event: DragEndEvent) => {
311
+ const { active, over } = event;
312
+ if (active && over && active.id !== over.id) {
313
+ setColumnOrder((prev) => {
314
+ const oldIndex = prev.indexOf(active.id as string);
315
+ const newIndex = prev.indexOf(over.id as string);
316
+ return arrayMove(prev, oldIndex, newIndex);
317
+ });
318
+ }
319
+ };
320
+
321
+ const sensors = useSensors(
322
+ useSensor(MouseSensor),
323
+ useSensor(TouchSensor),
324
+ useSensor(KeyboardSensor),
325
+ );
326
+
327
+ const visibleColumns = table.getVisibleLeafColumns();
328
+
329
+ const columnVirtualizer = useVirtualizer<
330
+ HTMLDivElement,
331
+ HTMLTableCellElement
332
+ >({
333
+ count: visibleColumns.length,
334
+ estimateSize: (index) => visibleColumns[index].getSize(), //estimate width of each column for accurate scrollbar dragging
335
+ getScrollElement: () => containerRef.current,
336
+ horizontal: true,
337
+ overscan: 3, //how many columns to render on each side off screen each way
338
+ });
339
+
340
+ const virtualColumns = columnVirtualizer.getVirtualItems();
341
+
342
+ let virtualPaddingLeft: number | undefined;
343
+ let virtualPaddingRight: number | undefined;
344
+
345
+ if (columnVirtualizer && virtualColumns?.length) {
346
+ virtualPaddingLeft = virtualColumns[0]?.start ?? 0;
347
+ virtualPaddingRight =
348
+ columnVirtualizer.getTotalSize() -
349
+ (virtualColumns[virtualColumns.length - 1]?.end ?? 0);
350
+ }
351
+
352
+ return (
353
+ <DndContext
354
+ id={id}
355
+ collisionDetection={closestCenter}
356
+ modifiers={[restrictToHorizontalAxis]}
357
+ onDragEnd={handleDragEnd}
358
+ sensors={sensors}
359
+ >
360
+ <SortableContext
361
+ items={columnOrder}
362
+ strategy={horizontalListSortingStrategy}
363
+ >
364
+ <div className="flex flex-col flex-1 h-full w-full rounded border border-border-primary-normal overflow-hidden text-text-primary-normal">
365
+ <div
366
+ className="overflow-auto scrollbar-thin h-full relative contain-paint will-change-transform"
367
+ ref={containerRef}
368
+ >
369
+ <table className="min-w-full grid">
370
+ <thead className="sticky top-0 z-10 grid">
371
+ {table.getHeaderGroups().map((headerGroup) => (
372
+ <tr key={headerGroup.id} className="flex w-full">
373
+ {virtualPaddingLeft ? (
374
+ // fake empty column to the left for virtualization scroll padding
375
+ <th
376
+ style={{ display: "flex", width: virtualPaddingLeft }}
377
+ />
378
+ ) : null}
379
+
380
+ {virtualColumns.map((virtualColumn) => {
381
+ const header = headerGroup.headers[virtualColumn.index];
382
+ if (typeof header.column.columnDef.header === "string") {
383
+ const customHeaderWidth =
384
+ header.column.columnDef.meta?.headerWidth;
385
+
386
+ return (
387
+ <DraggableCellHeader
388
+ key={header.id}
389
+ header={header}
390
+ locked={header.column.columnDef.meta?.locked}
391
+ center={centerHeader}
392
+ width={customHeaderWidth}
393
+ className={clsx(
394
+ header.column.getCanSort()
395
+ ? "cursor-pointer"
396
+ : "cursor-grab",
397
+ "group",
398
+ )}
399
+ >
400
+ <Subheader tall>
401
+ {header.column.columnDef.header}
402
+ </Subheader>
403
+
404
+ {getSortIcon(header.column.getIsSorted())}
405
+
406
+ {!header.column.getIsSorted() &&
407
+ header.column.getCanSort() &&
408
+ getSortIcon(
409
+ header.column.getNextSortingOrder(),
410
+ true,
411
+ )}
412
+
413
+ {header.column.getSortIndex() !== -1 &&
414
+ table.getState().sorting.length > 1 && (
415
+ <Subheader tall>
416
+ {header.column.getSortIndex() + 1}
417
+ </Subheader>
418
+ )}
419
+
420
+ {!header.column.columnDef.meta?.locked && (
421
+ <div
422
+ onDoubleClick={(e) => {
423
+ e.stopPropagation();
424
+ header.column.resetSize();
425
+ }}
426
+ onMouseDown={(e) => {
427
+ e.stopPropagation();
428
+ header.getResizeHandler()(e);
429
+ }}
430
+ onTouchStart={(e) => {
431
+ e.stopPropagation();
432
+ header.getResizeHandler()(e);
433
+ }}
434
+ className="absolute right-0 inset-y-0 w-px bg-black cursor-col-resize"
435
+ />
436
+ )}
437
+ </DraggableCellHeader>
438
+ );
439
+ }
440
+ return (
441
+ <React.Fragment key={header.id}>
442
+ {header.column.columnDef.meta?.checkbox ? (
443
+ <DataGridCell
444
+ type="header"
445
+ component="checkbox"
446
+ locked={header.column.columnDef.meta?.locked}
447
+ >
448
+ <Checkbox
449
+ checked={allSelectedAcrossPages}
450
+ indeterminate={someSelectedAcrossPages}
451
+ onChange={toggleSelectAllAcrossPages}
452
+ />
453
+ </DataGridCell>
454
+ ) : (
455
+ flexRender(
456
+ header.column.columnDef.header,
457
+ header.getContext(),
458
+ )
459
+ )}
460
+ </React.Fragment>
461
+ );
462
+ })}
463
+
464
+ {virtualPaddingRight ? (
465
+ //fake empty column to the right for virtualization scroll padding
466
+ <th
467
+ style={{ display: "flex", width: virtualPaddingRight }}
468
+ />
469
+ ) : null}
470
+ {enableColumnSelector && (
471
+ <ColumnSelectorHeaderCell
472
+ table={table}
473
+ toggleColumnVisibility={toggleColumnVisibility}
474
+ resetColumnVisibility={resetColumnVisibility}
475
+ />
476
+ )}
477
+ </tr>
478
+ ))}
479
+ </thead>
480
+
481
+ <TableBody
482
+ columnVirtualizer={columnVirtualizer}
483
+ table={table}
484
+ tableContainerRef={containerRef}
485
+ virtualPaddingLeft={virtualPaddingLeft}
486
+ virtualPaddingRight={virtualPaddingRight}
487
+ pagination={pagination}
488
+ isLoadingMore={isLoadingMore}
489
+ hasMore={hasMore}
490
+ showFilterRow={showFilterRow}
491
+ enableColumnSelector={enableColumnSelector}
492
+ />
493
+ </table>
494
+ </div>
495
+
496
+ {table.getRowModel().rows.length === 0 && (
497
+ <div
498
+ className={clsx(
499
+ NO_RESULTS_HEIGHT,
500
+ "flex flex-col items-center justify-center",
501
+ componentGap,
502
+ componentPadding,
503
+ )}
504
+ >
505
+ <Subheader color="text-secondary-normal">No Results</Subheader>
506
+ <Paragraph color="text-secondary-normal">
507
+ To view results, enter or update your search criteria.
508
+ </Paragraph>
509
+ </div>
510
+ )}
511
+
512
+ {!hideStatusBar && (
513
+ <div className="p-2 pt-[7px] border-t border-border-primary-normal h-full min-h-[34px]">
514
+ {pagination && (
515
+ <div className="flex justify-between items-center">
516
+ <div className="flex items-center gap-1 w-min">
517
+ <Select
518
+ wrapperClassName="!w-20"
519
+ value={pagination.pageSize.toString()}
520
+ onChange={(e) =>
521
+ pagination.onPageSizeChange?.(Number(e.target.value))
522
+ }
523
+ renderMenu={(props) => (
524
+ <Menu {...props} onClick={() => props.setShow(false)}>
525
+ {PAGE_SIZE_OPTIONS.map((option) => (
526
+ <MenuOption
527
+ key={option}
528
+ selected={pagination.pageSize === option}
529
+ onClick={() =>
530
+ pagination.onPageSizeChange?.(option)
531
+ }
532
+ >
533
+ {option}
534
+ </MenuOption>
535
+ ))}
536
+ </Menu>
537
+ )}
538
+ />
539
+ <Label className="whitespace-nowrap">Per Page</Label>
540
+ </div>
541
+
542
+ <div className="flex items-center gap-2">
543
+ <Button
544
+ iconOnly
545
+ leftIcon={<Icon name="chevron_left" />}
546
+ onClick={() =>
547
+ pagination.onPageChange(pagination.pageIndex - 1)
548
+ }
549
+ variant="tertiary"
550
+ disabled={pagination.pageIndex === 0}
551
+ />
552
+ <Paragraph>
553
+ {pagination.pageIndex * pagination.pageSize + 1} -{" "}
554
+ {Math.min(
555
+ (pagination.pageIndex + 1) * pagination.pageSize,
556
+ pagination.total,
557
+ )}{" "}
558
+ of {pagination.total}
559
+ </Paragraph>
560
+ <Button
561
+ iconOnly
562
+ leftIcon={<Icon name="chevron_right" />}
563
+ onClick={() =>
564
+ pagination.onPageChange(pagination.pageIndex + 1)
565
+ }
566
+ variant="tertiary"
567
+ disabled={
568
+ (pagination.pageIndex + 1) * pagination.pageSize >=
569
+ pagination.total
570
+ }
571
+ />
572
+ </div>
573
+ </div>
574
+ )}
575
+
576
+ {status && <Paragraph>{status}</Paragraph>}
577
+ </div>
578
+ )}
579
+ </div>
580
+ </SortableContext>
581
+ </DndContext>
582
+ );
583
+ }
584
+
585
+ DataGrid.displayName = "DataGrid";
586
+
587
+ interface TableBodyProps<TData extends RowData> {
588
+ columnVirtualizer: Virtualizer<HTMLDivElement, HTMLTableCellElement>;
589
+ table: Table<TData>;
590
+ tableContainerRef: React.RefObject<HTMLDivElement | null>;
591
+ virtualPaddingLeft: number | undefined;
592
+ virtualPaddingRight: number | undefined;
593
+ pagination: DataGridPagination | undefined;
594
+ isLoadingMore: boolean;
595
+ hasMore: boolean;
596
+ showFilterRow: boolean;
597
+ enableColumnSelector?: boolean;
598
+ }
599
+
600
+ // Helpers
601
+
602
+ function TableBody<T>({
603
+ columnVirtualizer,
604
+ table,
605
+ tableContainerRef,
606
+ virtualPaddingLeft,
607
+ virtualPaddingRight,
608
+ pagination,
609
+ isLoadingMore,
610
+ hasMore,
611
+ showFilterRow,
612
+ enableColumnSelector = false,
613
+ }: TableBodyProps<T>) {
614
+ const { rows } = table.getRowModel();
615
+
616
+ const rowVirtualizer = useVirtualizer<HTMLDivElement, HTMLTableRowElement>({
617
+ count: rows.length,
618
+ estimateSize: () => 40,
619
+ getScrollElement: () => tableContainerRef.current,
620
+ overscan: 8,
621
+ });
622
+
623
+ const virtualRows = rowVirtualizer.getVirtualItems();
624
+
625
+ return (
626
+ <tbody
627
+ style={{
628
+ display: "grid",
629
+ height: `${showFilterRow ? rowVirtualizer.getTotalSize() + 40 : rowVirtualizer.getTotalSize()}px`, // tells scrollbar how big the table is
630
+ position: "relative", // needed for absolute positioning of rows
631
+ }}
632
+ >
633
+ {showFilterRow && (
634
+ <tr
635
+ style={{
636
+ display: "flex",
637
+ position: "sticky",
638
+ top: "40px",
639
+ width: "100%",
640
+ height: "40px",
641
+ zIndex: 10,
642
+ }}
643
+ className="even:bg-background-grouped-primary-normal odd:bg-background-grouped-secondary-normal"
644
+ >
645
+ {table.getHeaderGroups().flatMap((x) =>
646
+ x.headers.map((header) => (
647
+ <DragAlongCell
648
+ noPadding
649
+ key={header.id}
650
+ cell={header}
651
+ width={header.column.columnDef.meta?.headerWidth}
652
+ >
653
+ {header.column.getCanFilter() &&
654
+ (header.column.columnDef.meta?.filterRowCell?.({
655
+ header,
656
+ table,
657
+ }) ?? (
658
+ <Search
659
+ removeRoundness
660
+ onChange={(e) =>
661
+ header.column.setFilterValue(e.target.value)
662
+ }
663
+ value={(header.column.getFilterValue() ?? "") as string}
664
+ placeholder=""
665
+ removeSearchIcon
666
+ />
667
+ ))}
668
+ </DragAlongCell>
669
+ )),
670
+ )}
671
+ </tr>
672
+ )}
673
+
674
+ {virtualRows.map((virtualRow) => {
675
+ const row = rows[virtualRow.index] as Row<T>;
676
+
677
+ return (
678
+ <TableBodyRow
679
+ columnVirtualizer={columnVirtualizer}
680
+ key={row.id}
681
+ row={row}
682
+ rowVirtualizer={rowVirtualizer}
683
+ virtualPaddingLeft={virtualPaddingLeft}
684
+ virtualPaddingRight={virtualPaddingRight}
685
+ virtualRow={virtualRow}
686
+ showFilterRow={showFilterRow}
687
+ enableColumnSelector={enableColumnSelector}
688
+ />
689
+ );
690
+ })}
691
+
692
+ {!pagination && isLoadingMore && hasMore && (
693
+ <tr
694
+ style={{
695
+ display: "flex",
696
+ position: "absolute",
697
+ width: "100%",
698
+ transform: `translateY(${virtualRows[virtualRows.length - 1].start + 40}px)`,
699
+ }}
700
+ className="odd:bg-background-grouped-primary-normal even:bg-background-grouped-secondary-normal"
701
+ >
702
+ {table.getAllLeafColumns().map((column) => (
703
+ <LoadingCell key={column.id} column={column.columnDef} />
704
+ ))}
705
+ </tr>
706
+ )}
707
+ </tbody>
708
+ );
709
+ }
710
+
711
+ interface TableBodyRowProps<T> {
712
+ columnVirtualizer: Virtualizer<HTMLDivElement, HTMLTableCellElement>;
713
+ row: Row<T>;
714
+ rowVirtualizer: Virtualizer<HTMLDivElement, HTMLTableRowElement>;
715
+ virtualPaddingLeft: number | undefined;
716
+ virtualPaddingRight: number | undefined;
717
+ virtualRow: VirtualItem;
718
+ showFilterRow: boolean;
719
+ enableColumnSelector?: boolean;
720
+ }
721
+
722
+ function TableBodyRow<T>({
723
+ columnVirtualizer,
724
+ row,
725
+ // rowVirtualizer,
726
+ virtualPaddingLeft,
727
+ virtualPaddingRight,
728
+ virtualRow,
729
+ showFilterRow,
730
+ enableColumnSelector = false,
731
+ }: TableBodyRowProps<T>) {
732
+ const visibleCells = row.getVisibleCells();
733
+ const virtualColumns = columnVirtualizer.getVirtualItems();
734
+
735
+ const isError =
736
+ typeof row.original === "object" &&
737
+ row.original !== null &&
738
+ "rowState" in row.original &&
739
+ row.original.rowState === "error";
740
+
741
+ return (
742
+ <tr
743
+ key={row.id}
744
+ className={clsx(
745
+ "transition-colors hover:bg-background-action-secondary-hover",
746
+ row.getIsSelected() && "!bg-background-action-secondary-hover",
747
+ isError && "!bg-background-action-critical-secondary-hover",
748
+ showFilterRow
749
+ ? "even:bg-background-grouped-primary-normal odd:bg-background-grouped-secondary-normal"
750
+ : "odd:bg-background-grouped-primary-normal even:bg-background-grouped-secondary-normal",
751
+ )}
752
+ style={{
753
+ display: "flex",
754
+ position: "absolute",
755
+ transform: `translateY(${showFilterRow ? virtualRow.start + 40 : virtualRow.start}px)`,
756
+ width: "100%",
757
+ }}
758
+ >
759
+ {virtualPaddingLeft ? (
760
+ // fake empty column to the left for virtualization scroll padding
761
+ <td style={{ display: "flex", width: virtualPaddingLeft }} />
762
+ ) : null}
763
+
764
+ {virtualColumns.map((virtualColumn) => {
765
+ const cell = visibleCells[virtualColumn.index];
766
+ return cell.column.columnDef.meta?.useCustomRenderer ? (
767
+ <React.Fragment key={cell.id}>
768
+ {flexRender(cell.column.columnDef.cell, cell.getContext())}
769
+ </React.Fragment>
770
+ ) : (
771
+ <DragAlongCell key={cell.id} cell={cell}>
772
+ <Tooltip
773
+ showOnTruncation
774
+ message={cell.getValue() as string}
775
+ position="bottom"
776
+ >
777
+ <Paragraph addOverflow tall>
778
+ {cell.getValue() as ReactNode | string}
779
+ </Paragraph>
780
+ </Tooltip>
781
+ </DragAlongCell>
782
+ );
783
+ })}
784
+
785
+ {virtualPaddingRight ? (
786
+ // fake empty column to the right for virtualization scroll padding
787
+ <td style={{ display: "flex", width: virtualPaddingRight }} />
788
+ ) : null}
789
+
790
+ {enableColumnSelector && <td></td>}
791
+ </tr>
792
+ );
793
+ }
794
+
795
+ const LoadingCell = <T extends RowData>({
796
+ column,
797
+ }: {
798
+ column: ColumnDef<T>;
799
+ }) => {
800
+ const key = `loading-${column.id}`;
801
+ if (column.cell === "checkbox") {
802
+ return (
803
+ <DataGridCell key={key}>
804
+ <Checkbox disabled />
805
+ </DataGridCell>
806
+ );
807
+ }
808
+ if (column.cell === "input") {
809
+ return (
810
+ <DataGridCell key={key} component="input">
811
+ <Input
812
+ align="left"
813
+ disabled
814
+ wrapperClassName="!rounded-none !border-0"
815
+ />
816
+ </DataGridCell>
817
+ );
818
+ }
819
+ return (
820
+ <DataGridCell key={key}>
821
+ <div className="bg-linear-270 to-neutral-300/[24%] from-neutral-300/[12%] rounded-xs w-full max-w-25 h-6"></div>
822
+ </DataGridCell>
823
+ );
824
+ };
825
+
826
+ function ColumnSelectorHeaderCell<T>({
827
+ table,
828
+ toggleColumnVisibility,
829
+ resetColumnVisibility,
830
+ }: {
831
+ table: Table<T>;
832
+ toggleColumnVisibility: (id: string, isVisible: boolean) => void;
833
+ resetColumnVisibility: () => void;
834
+ }) {
835
+ const ref = useRef<HTMLElement>(null);
836
+ const [show, setShow] = useState(false);
837
+
838
+ return (
839
+ <DataGridCell
840
+ width="48"
841
+ type="header"
842
+ color="text-secondary-normal"
843
+ ref={ref}
844
+ >
845
+ <Button
846
+ onClick={() => setShow((prev) => !prev)}
847
+ variant="navigation"
848
+ iconOnly
849
+ leftIcon={<Icon name="tune" />}
850
+ ></Button>
851
+ <Menu
852
+ positionTo={ref}
853
+ position="bottom-right"
854
+ show={show}
855
+ setShow={setShow}
856
+ >
857
+ <Button
858
+ variant="tertiary"
859
+ onClick={() => {
860
+ resetColumnVisibility();
861
+ setShow(false);
862
+ }}
863
+ >
864
+ Reset to default
865
+ </Button>
866
+ {table.getAllColumns().map((column) => (
867
+ <ColumnSelectorMenuOption
868
+ key={column.id}
869
+ column={column}
870
+ toggleColumnVisibility={toggleColumnVisibility}
871
+ />
872
+ ))}
873
+ </Menu>
874
+ </DataGridCell>
875
+ );
876
+ }
877
+
878
+ function ColumnSelectorMenuOption<T>({
879
+ column,
880
+ toggleColumnVisibility,
881
+ }: {
882
+ column: Column<T, unknown>;
883
+ toggleColumnVisibility: (id: string, isVisible: boolean) => void;
884
+ }) {
885
+ const [isVisible, setIsVisible] = useState(column.getIsVisible());
886
+ const label =
887
+ typeof column.columnDef.header === "string"
888
+ ? column.columnDef.header
889
+ : null;
890
+ return (
891
+ <MenuOption selected={isVisible} defaultChecked={isVisible}>
892
+ <Checkbox
893
+ label={label ?? "Unknown"}
894
+ checked={isVisible}
895
+ onChange={(e) => {
896
+ setIsVisible(e.target.checked);
897
+ toggleColumnVisibility(column.id, e.target.checked);
898
+ }}
899
+ />
900
+ </MenuOption>
901
+ );
902
+ }
903
+
904
+ function getSortIcon(sort: SortDirection | false, nextSort = false) {
905
+ const iconClassName = clsx(
906
+ "text-icon-on-action-primary-normal",
907
+ nextSort && "hidden group-hover:block",
908
+ );
909
+ if (sort === "asc")
910
+ return <Icon size={16} className={iconClassName} name="arrow_upward" />;
911
+ if (sort === "desc")
912
+ return <Icon size={16} className={iconClassName} name="arrow_downward" />;
913
+ return null;
914
+ }
915
+
916
+ // Extend TanStack ColumnMeta
917
+ declare module "@tanstack/react-table" {
918
+ interface TableOptions<TData extends RowData>
919
+ extends PartialKeys<
920
+ TableOptionsResolved<TData>,
921
+ "state" | "onStateChange" | "renderFallbackValue"
922
+ > {
923
+ filterFns?: FilterFns;
924
+ }
925
+ interface FilterFns {
926
+ endsWith?: FilterFn<RowData>;
927
+ startsWith?: FilterFn<RowData>;
928
+ }
929
+
930
+ interface ColumnMeta<TData extends RowData, TValue> {
931
+ filterVariant?: "text" | "select" | "range";
932
+ className?: string;
933
+ sticky?: boolean;
934
+ useCustomRenderer?: boolean;
935
+ locked?: boolean;
936
+ checkbox?: boolean;
937
+ headerWidth?: string;
938
+ visible?: boolean;
939
+ filterRowCell?: ({
940
+ header,
941
+ table,
942
+ }: {
943
+ header: Header<TData, TValue>;
944
+ table: Table<TData>;
945
+ }) => ReactNode;
946
+ }
947
+ }
948
+ export type { ColumnDef };