@dmsi/wedgekit-react 0.0.550 → 0.0.552

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 (180) hide show
  1. package/dist/{chunk-U3QGZAVS.js → chunk-JADOJNBI.js} +4 -4
  2. package/dist/{chunk-N2KPADIL.js → chunk-WNGFRQ4Y.js} +7 -7
  3. package/dist/{chunk-ZVY3TLXL.js → chunk-ZIPJMN2E.js} +4 -4
  4. package/dist/components/Alert.js +2 -2
  5. package/dist/components/CalendarRange.js +10 -10
  6. package/dist/components/DataGrid/ColumnSelectorHeaderCell/ColumnSelectorMenuOption.js +10 -10
  7. package/dist/components/DataGrid/ColumnSelectorHeaderCell/index.js +10 -10
  8. package/dist/components/DataGrid/PinnedColumns.js +10 -10
  9. package/dist/components/DataGrid/TableBody/LoadingCell.js +10 -10
  10. package/dist/components/DataGrid/TableBody/TableBodyRow.js +10 -10
  11. package/dist/components/DataGrid/TableBody/index.js +10 -10
  12. package/dist/components/DataGrid/index.js +10 -10
  13. package/dist/components/DataGrid/utils.js +10 -10
  14. package/dist/components/DateInput.js +10 -10
  15. package/dist/components/DateRangeInput.js +10 -10
  16. package/dist/components/FilterGroup.js +5 -5
  17. package/dist/components/MobileDataGrid/ColumnSelector/index.js +10 -10
  18. package/dist/components/MobileDataGrid/MobileDataGridHeader.js +10 -10
  19. package/dist/components/MobileDataGrid/RowDetailModalProvider/index.js +5 -5
  20. package/dist/components/MobileDataGrid/index.js +10 -10
  21. package/dist/components/Modal.js +4 -4
  22. package/dist/components/ModalButtons.js +2 -2
  23. package/dist/components/ModalHeader.js +2 -2
  24. package/dist/components/NavigationTab.js +2 -2
  25. package/dist/components/NavigationTabs.js +2 -2
  26. package/dist/components/NestedMenu.js +3 -3
  27. package/dist/components/Notification.js +3 -3
  28. package/dist/components/OptionPill.js +2 -2
  29. package/dist/components/PDFViewer/DownloadIcon.js +2 -2
  30. package/dist/components/PDFViewer/PDFNavigation.js +2 -2
  31. package/dist/components/PDFViewer/index.js +6 -6
  32. package/dist/components/ProductImagePreview/index.js +1 -1
  33. package/dist/components/Stepper.js +3 -3
  34. package/dist/components/Toast.js +3 -3
  35. package/dist/components/Upload.js +3 -3
  36. package/dist/components/index.js +16 -16
  37. package/package.json +8 -9
  38. package/src/brand.css +0 -125
  39. package/src/classNames.ts +0 -174
  40. package/src/components/AccessChangerTabItem.tsx +0 -71
  41. package/src/components/Accordion.tsx +0 -108
  42. package/src/components/Alert.tsx +0 -81
  43. package/src/components/Breadcrumbs.tsx +0 -142
  44. package/src/components/Button.tsx +0 -216
  45. package/src/components/CalendarRange.tsx +0 -628
  46. package/src/components/Caption.tsx +0 -144
  47. package/src/components/Card.tsx +0 -88
  48. package/src/components/Checkbox.tsx +0 -206
  49. package/src/components/CompactImagesPreview.tsx +0 -135
  50. package/src/components/ContentTab.tsx +0 -84
  51. package/src/components/ContentTabs.tsx +0 -136
  52. package/src/components/DMSiLogo.tsx +0 -33
  53. package/src/components/DataGrid/ColumnSelectorHeaderCell/ColumnSelectorMenuOption.tsx +0 -35
  54. package/src/components/DataGrid/ColumnSelectorHeaderCell/index.tsx +0 -74
  55. package/src/components/DataGrid/PinnedColumns.tsx +0 -183
  56. package/src/components/DataGrid/TableBody/LoadingCell.tsx +0 -44
  57. package/src/components/DataGrid/TableBody/TableBodyRow.tsx +0 -157
  58. package/src/components/DataGrid/TableBody/index.tsx +0 -185
  59. package/src/components/DataGrid/index.tsx +0 -756
  60. package/src/components/DataGrid/types.ts +0 -98
  61. package/src/components/DataGrid/utils.tsx +0 -15
  62. package/src/components/DataGridCell.tsx +0 -526
  63. package/src/components/DataTable.tsx +0 -881
  64. package/src/components/DateInput.tsx +0 -306
  65. package/src/components/DateRangeInput.tsx +0 -758
  66. package/src/components/DebugJson.tsx +0 -28
  67. package/src/components/Display.tsx +0 -66
  68. package/src/components/EditingContext.tsx +0 -43
  69. package/src/components/EmptyCartIcon.tsx +0 -18
  70. package/src/components/FilterGroup.tsx +0 -264
  71. package/src/components/FullViewportBox.tsx +0 -19
  72. package/src/components/Grid.tsx +0 -97
  73. package/src/components/Heading.tsx +0 -72
  74. package/src/components/HorizontalDivider.tsx +0 -22
  75. package/src/components/Icon.tsx +0 -39
  76. package/src/components/ImagePlaceholder.tsx +0 -22
  77. package/src/components/Input.tsx +0 -609
  78. package/src/components/InputGroup.tsx +0 -59
  79. package/src/components/Label.tsx +0 -46
  80. package/src/components/Link.tsx +0 -117
  81. package/src/components/List.tsx +0 -18
  82. package/src/components/ListGroup.tsx +0 -82
  83. package/src/components/LiveChatComponent.tsx +0 -56
  84. package/src/components/LoadingScrim.tsx +0 -33
  85. package/src/components/LogoAgilityTopBar.tsx +0 -54
  86. package/src/components/LogoDMSiTopBar.tsx +0 -33
  87. package/src/components/LogoMillworkTopBar.tsx +0 -119
  88. package/src/components/MainBar.tsx +0 -91
  89. package/src/components/MaxViewportBox.tsx +0 -19
  90. package/src/components/Menu.tsx +0 -316
  91. package/src/components/MenuOption.tsx +0 -330
  92. package/src/components/MobileDataGrid/ColumnList.tsx +0 -66
  93. package/src/components/MobileDataGrid/ColumnSelector/index.tsx +0 -97
  94. package/src/components/MobileDataGrid/GridContextProvider/GridContext.tsx +0 -25
  95. package/src/components/MobileDataGrid/GridContextProvider/index.tsx +0 -132
  96. package/src/components/MobileDataGrid/GridContextProvider/useGridContext.ts +0 -10
  97. package/src/components/MobileDataGrid/MobileDataGridCard/MobileDataGridColumn.tsx +0 -27
  98. package/src/components/MobileDataGrid/MobileDataGridCard/index.tsx +0 -138
  99. package/src/components/MobileDataGrid/MobileDataGridHeader.tsx +0 -81
  100. package/src/components/MobileDataGrid/RowDetailModalProvider/ModalContent.tsx +0 -42
  101. package/src/components/MobileDataGrid/RowDetailModalProvider/index.tsx +0 -68
  102. package/src/components/MobileDataGrid/dataGridReducer.ts +0 -55
  103. package/src/components/MobileDataGrid/index.tsx +0 -92
  104. package/src/components/MobileDataGrid/types.ts +0 -4
  105. package/src/components/Modal.tsx +0 -312
  106. package/src/components/ModalButtons.tsx +0 -62
  107. package/src/components/ModalContent.tsx +0 -31
  108. package/src/components/ModalHeader.tsx +0 -78
  109. package/src/components/ModalScrim.tsx +0 -42
  110. package/src/components/NavigationTab.tsx +0 -95
  111. package/src/components/NavigationTabs.tsx +0 -70
  112. package/src/components/NestedMenu.tsx +0 -131
  113. package/src/components/Notification.tsx +0 -128
  114. package/src/components/OptionPill.tsx +0 -139
  115. package/src/components/OrderCheckIcon.tsx +0 -19
  116. package/src/components/PDFViewer/DownloadIcon.tsx +0 -25
  117. package/src/components/PDFViewer/PDFElement.tsx +0 -90
  118. package/src/components/PDFViewer/PDFNavigation.tsx +0 -68
  119. package/src/components/PDFViewer/PDFPage.tsx +0 -34
  120. package/src/components/PDFViewer/index.tsx +0 -128
  121. package/src/components/Pagination.tsx +0 -182
  122. package/src/components/Paragraph.tsx +0 -55
  123. package/src/components/Password.tsx +0 -62
  124. package/src/components/ProductImagePreview/CarouselPagination.tsx +0 -54
  125. package/src/components/ProductImagePreview/MobileImageCarousel.tsx +0 -226
  126. package/src/components/ProductImagePreview/ProductPrimaryImage.tsx +0 -219
  127. package/src/components/ProductImagePreview/Thumbnail.tsx +0 -55
  128. package/src/components/ProductImagePreview/ZoomWindow.tsx +0 -136
  129. package/src/components/ProductImagePreview/index.tsx +0 -182
  130. package/src/components/ProductImagePreview/useProductImagePreview.ts +0 -211
  131. package/src/components/ProjectBar.tsx +0 -82
  132. package/src/components/Radio.tsx +0 -146
  133. package/src/components/Search.tsx +0 -152
  134. package/src/components/SearchResultImage/index.tsx +0 -39
  135. package/src/components/Select.tsx +0 -114
  136. package/src/components/SideMenu.tsx +0 -30
  137. package/src/components/SideMenuGroup.tsx +0 -95
  138. package/src/components/SideMenuItem.tsx +0 -109
  139. package/src/components/SimpleTable.tsx +0 -77
  140. package/src/components/SkeletonParagraph.tsx +0 -31
  141. package/src/components/Spinner.tsx +0 -32
  142. package/src/components/Stack.tsx +0 -347
  143. package/src/components/StatusPill.tsx +0 -59
  144. package/src/components/Stepper.tsx +0 -128
  145. package/src/components/Subheader.tsx +0 -50
  146. package/src/components/Surface.tsx +0 -37
  147. package/src/components/Swatch.tsx +0 -1341
  148. package/src/components/Textarea.tsx +0 -102
  149. package/src/components/Theme.tsx +0 -27
  150. package/src/components/Time.tsx +0 -460
  151. package/src/components/Toast.tsx +0 -268
  152. package/src/components/Tooltip.tsx +0 -159
  153. package/src/components/TopBar.tsx +0 -139
  154. package/src/components/Upload.tsx +0 -107
  155. package/src/components/WorldpayIframe.tsx +0 -7
  156. package/src/components/index.ts +0 -34
  157. package/src/components/useMenuSystem.tsx +0 -456
  158. package/src/components/useMounted.tsx +0 -14
  159. package/src/darkmode.css +0 -278
  160. package/src/fonts.css +0 -23
  161. package/src/hooks/index.ts +0 -4
  162. package/src/hooks/useInfiniteScroll.tsx +0 -40
  163. package/src/hooks/useKeydown.ts +0 -42
  164. package/src/hooks/useMatchesMedia.ts +0 -18
  165. package/src/hooks/useTableLayout.ts +0 -106
  166. package/src/index.css +0 -800
  167. package/src/index.tsx +0 -5
  168. package/src/types.ts +0 -150
  169. package/src/utils/date.ts +0 -236
  170. package/src/utils/formatting.tsx +0 -81
  171. package/src/utils/index.ts +0 -4
  172. package/src/utils/mergeObjectArrays.ts +0 -18
  173. package/src/utils.ts +0 -24
  174. package/dist/{chunk-7FQ7PGUF.js → chunk-7COWXCPA.js} +3 -3
  175. package/dist/{chunk-NKCFYM7A.js → chunk-7SFFUICM.js} +3 -3
  176. package/dist/{chunk-25RZP3VR.js → chunk-AKJUBFJK.js} +3 -3
  177. package/dist/{chunk-TAPYQBQU.js → chunk-CMMQTIVM.js} +3 -3
  178. package/dist/{chunk-GYEXSNFP.js → chunk-FWCVZWE6.js} +3 -3
  179. package/dist/{chunk-MV6W7OMC.js → chunk-QMMPHXVE.js} +3 -3
  180. package/dist/{chunk-GG5OZTI5.js → chunk-XRE52QTN.js} +3 -3
@@ -1,756 +0,0 @@
1
- "use client";
2
-
3
- import { useInfiniteScroll, useTableLayout } from "../../hooks";
4
- import { componentGap, componentPadding } from "../../classNames";
5
- import {
6
- Button,
7
- Checkbox,
8
- DataGridCell,
9
- DraggableCellHeader,
10
- Icon,
11
- Label,
12
- Menu,
13
- MenuOption,
14
- Paragraph,
15
- Select,
16
- Subheader,
17
- } from "..";
18
- import React, {
19
- useCallback,
20
- useEffect,
21
- useId,
22
- useImperativeHandle,
23
- useState,
24
- } from "react";
25
- import {
26
- ColumnFiltersState,
27
- flexRender,
28
- getCoreRowModel,
29
- getFilteredRowModel,
30
- getSortedRowModel,
31
- SortingState,
32
- useReactTable,
33
- } from "@tanstack/react-table";
34
-
35
- // DnD Kit
36
- import {
37
- closestCenter,
38
- DndContext,
39
- DragEndEvent,
40
- KeyboardSensor,
41
- MouseSensor,
42
- TouchSensor,
43
- useSensor,
44
- useSensors,
45
- } from "@dnd-kit/core";
46
- import {
47
- arrayMove,
48
- horizontalListSortingStrategy,
49
- SortableContext,
50
- } from "@dnd-kit/sortable";
51
- import { restrictToHorizontalAxis } from "@dnd-kit/modifiers";
52
- import { DataGridProps } from "./types";
53
- import { useVirtualizer } from "@tanstack/react-virtual";
54
- import clsx from "clsx";
55
- import { PinnedColumns } from "./PinnedColumns";
56
- import { getSortIcon } from "./utils";
57
- import { TableBody } from "./TableBody";
58
- import { NoResultsImg } from "../..";
59
-
60
- // Constants
61
- const PAGE_SIZE_OPTIONS = [5, 10, 15, 20, 25, 30, 35];
62
- const NO_RESULTS_HEIGHT = "h-[185px]";
63
-
64
- export function DataGrid<T extends Record<string, unknown>>({
65
- id,
66
- rowIdAccessor,
67
- testid,
68
- data,
69
- columns,
70
- status,
71
- isLoadingMore = false,
72
- onLoadMore,
73
- pagination,
74
- showFilterRow = false,
75
- hasMore = false,
76
- sorting: externalSorting,
77
- onSortingChange,
78
- columnFilters: externalColumnFilters,
79
- onColumnFiltersChange,
80
- rowSelection: externalRowSelection,
81
- onRowSelectionChange,
82
- filteredSortedData,
83
- totalRowCount,
84
- hideStatusBar,
85
- centerHeader,
86
- enableColumnSelector,
87
- predeterminedLeftPins = [],
88
- predeterminedRightPins = [],
89
- useMenuDefaultMinWidth,
90
- rowDisabled,
91
- rowDisabledAccessor,
92
- ref,
93
- }: DataGridProps<T>) {
94
- useImperativeHandle(ref, () => ({
95
- getSavedLayout: () => {
96
- return getSavedLayout();
97
- },
98
- }));
99
- const [localSorting, setLocalSorting] = useState<SortingState>([]);
100
- const [localColumnFilters, setLocalColumnFilters] =
101
- useState<ColumnFiltersState>([]);
102
- const [localRowSelection, setLocalRowSelection] = useState<
103
- Record<string, boolean>
104
- >({});
105
- const {
106
- columns: tableColumns,
107
- setColumns: setTableColumns,
108
- getSavedLayout,
109
- } = useTableLayout<T>(columns, id ?? testid);
110
- const [columnOrder, setColumnOrder] = useState<string[]>(
111
- tableColumns.map((c) => c.id!),
112
- );
113
-
114
- const [columnVisibility, setColumnVisibility] = useState<
115
- Record<string, boolean>
116
- >(
117
- Object.fromEntries(
118
- tableColumns
119
- .filter((column) => !!column.id)
120
- .map((column) => [column.id, column.meta?.visible ?? true]),
121
- ),
122
- );
123
-
124
- const updateColumnVisibility = useCallback(
125
- (updateOrder?: boolean) => {
126
- setColumnVisibility(
127
- Object.fromEntries(
128
- tableColumns
129
- .filter((column) => !!column.id)
130
- .map((column) => [column.id, column.meta?.visible ?? true]),
131
- ),
132
- );
133
- if (updateOrder) setColumnOrder(tableColumns.map((c) => c.id!));
134
- },
135
- [tableColumns],
136
- );
137
-
138
- const resetDefaultColumnVisibility = useCallback(() => {
139
- setTableColumns((prev) => {
140
- columns.forEach((column) => {
141
- const columnId = column.id;
142
- const isVisible = column.meta?.visible ?? true;
143
- const persistedIndex = prev.findIndex((col) => col.id === columnId);
144
- if (persistedIndex !== -1) {
145
- prev[persistedIndex].meta = {
146
- ...prev[persistedIndex].meta,
147
- visible: isVisible,
148
- };
149
- }
150
- });
151
- return [...prev];
152
- // @ts-expect-error Internal usage only
153
- }, true);
154
- }, [columns, setTableColumns]);
155
-
156
- useEffect(() => {
157
- updateColumnVisibility(true);
158
- }, [updateColumnVisibility]);
159
-
160
- const sortingState = pagination
161
- ? (externalSorting ?? localSorting)
162
- : localSorting;
163
- const setSortingState: React.Dispatch<React.SetStateAction<SortingState>> =
164
- pagination
165
- ? (updaterOrValue) => {
166
- const value =
167
- typeof updaterOrValue === "function"
168
- ? (updaterOrValue as (prev: SortingState) => SortingState)(
169
- externalSorting ?? [],
170
- )
171
- : updaterOrValue;
172
- (onSortingChange ?? setLocalSorting)(value);
173
- }
174
- : setLocalSorting;
175
-
176
- const columnFilterState = pagination
177
- ? (externalColumnFilters ?? localColumnFilters)
178
- : localColumnFilters;
179
-
180
- const setColumnFilterState: React.Dispatch<
181
- React.SetStateAction<ColumnFiltersState>
182
- > = pagination
183
- ? (updaterOrValue) => {
184
- const value =
185
- typeof updaterOrValue === "function"
186
- ? (
187
- updaterOrValue as (
188
- prev: ColumnFiltersState,
189
- ) => ColumnFiltersState
190
- )(externalColumnFilters ?? [])
191
- : updaterOrValue;
192
- (onColumnFiltersChange ?? setLocalColumnFilters)(value);
193
- }
194
- : setLocalColumnFilters;
195
-
196
- const rowSelection = externalRowSelection ?? localRowSelection;
197
-
198
- const setRowSelection: React.Dispatch<
199
- React.SetStateAction<Record<string, boolean>>
200
- > = useCallback(
201
- (updaterOrValue) => {
202
- if (pagination) {
203
- const value =
204
- typeof updaterOrValue === "function"
205
- ? (
206
- updaterOrValue as (
207
- prev: Record<string, boolean>,
208
- ) => Record<string, boolean>
209
- )(externalRowSelection ?? {})
210
- : updaterOrValue;
211
- (onRowSelectionChange ?? setLocalRowSelection)(value);
212
- } else if (externalRowSelection && onRowSelectionChange) {
213
- const value =
214
- typeof updaterOrValue === "function"
215
- ? (
216
- updaterOrValue as (
217
- prev: Record<string, boolean>,
218
- ) => Record<string, boolean>
219
- )(externalRowSelection ?? {})
220
- : updaterOrValue;
221
-
222
- onRowSelectionChange(value);
223
- } else {
224
- setLocalRowSelection(updaterOrValue);
225
- }
226
- },
227
- [externalRowSelection, onRowSelectionChange, pagination],
228
- );
229
-
230
- const dndId = useId();
231
- const containerRef = React.useRef<HTMLDivElement>(null);
232
-
233
- const toggleColumnVisibility = useCallback(
234
- (columnId: string, isVisible: boolean) => {
235
- setTableColumns((prev) => {
236
- const persistedIndex = prev.findIndex((col) => col.id === columnId);
237
- if (persistedIndex !== -1) {
238
- prev[persistedIndex].meta = {
239
- ...prev[persistedIndex].meta,
240
- visible: isVisible,
241
- };
242
- }
243
- return [...prev];
244
- // @ts-expect-error Internal usage only
245
- }, true);
246
- },
247
- [setTableColumns],
248
- );
249
-
250
- const table = useReactTable<T>({
251
- columns: tableColumns,
252
- data,
253
- getCoreRowModel: getCoreRowModel(),
254
- getSortedRowModel: getSortedRowModel(),
255
- getFilteredRowModel: getFilteredRowModel(),
256
- columnResizeMode: "onChange",
257
- getRowId: rowIdAccessor
258
- ? (row) => String(row[rowIdAccessor])
259
- : (row, index) => String(row.id ?? index + 1),
260
- state: {
261
- columnOrder,
262
- sorting: sortingState,
263
- columnFilters: columnFilterState,
264
- rowSelection,
265
- columnVisibility,
266
- },
267
- initialState: {
268
- columnPinning: {
269
- left: predeterminedLeftPins,
270
- right: predeterminedRightPins,
271
- },
272
- },
273
- enableColumnPinning:
274
- predeterminedLeftPins?.length > 0 || predeterminedRightPins.length > 0,
275
- onColumnOrderChange: setColumnOrder,
276
- onSortingChange: adaptTableStateSetter(setSortingState),
277
- onColumnFiltersChange: adaptTableStateSetter(setColumnFilterState),
278
- onRowSelectionChange: adaptTableStateSetter(setRowSelection),
279
- filterFns: {
280
- startsWith: (row, columnId, filterValue) => {
281
- const cellValue = row?.getValue(columnId);
282
-
283
- if (!cellValue || !filterValue) {
284
- return true;
285
- }
286
-
287
- return String(cellValue)
288
- .toLowerCase()
289
- .startsWith(String(filterValue).toLowerCase());
290
- },
291
- endsWith: (row, columnId, filterValue) => {
292
- const cellValue = row?.getValue(columnId);
293
-
294
- if (!cellValue || !filterValue) {
295
- return true;
296
- }
297
-
298
- return String(cellValue)
299
- .toLowerCase()
300
- .endsWith(String(filterValue).toLowerCase());
301
- },
302
- },
303
- });
304
-
305
- const allRowIds = pagination
306
- ? (filteredSortedData?.map((row) => String(row.id)) ?? [])
307
- : Array.from({ length: totalRowCount ?? data.length }, (_, i) =>
308
- String(i + 1),
309
- );
310
-
311
- const allSelectedAcrossPages = allRowIds.every(
312
- (rowId) => rowSelection[rowId],
313
- );
314
- const someSelectedAcrossPages =
315
- !allSelectedAcrossPages && allRowIds.some((rowId) => rowSelection[rowId]);
316
-
317
- const toggleSelectAllAcrossPages = () => {
318
- setRowSelection((prev) => {
319
- const isSelecting = !allSelectedAcrossPages;
320
-
321
- if (isSelecting) {
322
- const newSelection: Record<string, boolean> = {};
323
- for (const rowId of allRowIds) {
324
- newSelection[rowId] = true;
325
- }
326
- return { ...prev, ...newSelection };
327
- } else {
328
- const updatedSelection: Record<string, boolean> = { ...prev };
329
- for (const rowId of allRowIds) {
330
- delete updatedSelection[rowId];
331
- }
332
- return updatedSelection;
333
- }
334
- });
335
- };
336
-
337
- useInfiniteScroll({
338
- containerRef,
339
- onLoadMore: onLoadMore ?? (() => {}),
340
- isLoading: isLoadingMore,
341
- enabled: !pagination,
342
- });
343
-
344
- const handleDragEnd = (event: DragEndEvent) => {
345
- const { active, over } = event;
346
- if (active && over && active.id !== over.id) {
347
- setColumnOrder((prev) => {
348
- const oldIndex = prev.indexOf(active.id as string);
349
- const newIndex = prev.indexOf(over.id as string);
350
- const newOrder = arrayMove(prev, oldIndex, newIndex);
351
- setTableColumns((prev) => {
352
- // Mirror columnOrder's string = id
353
- const res = newOrder
354
- .map((id) => prev.find((col) => col.id === id)!)
355
- .filter(Boolean);
356
- return res;
357
- });
358
- return newOrder;
359
- });
360
- }
361
- };
362
-
363
- const sensors = useSensors(
364
- useSensor(MouseSensor),
365
- useSensor(TouchSensor),
366
- useSensor(KeyboardSensor),
367
- );
368
-
369
- const visibleColumns = table.getVisibleLeafColumns();
370
-
371
- const columnVirtualizer = useVirtualizer<
372
- HTMLDivElement,
373
- HTMLTableCellElement
374
- >({
375
- count: visibleColumns.length,
376
- estimateSize: (index) => visibleColumns[index].getSize(), //estimate width of each column for accurate scrollbar dragging
377
- getScrollElement: () => containerRef.current,
378
- horizontal: true,
379
- overscan: 8, //how many columns to render on each side off screen each way
380
- });
381
-
382
- const virtualColumns = columnVirtualizer.getVirtualItems();
383
-
384
- let virtualPaddingLeft: number | undefined;
385
- let virtualPaddingRight: number | undefined;
386
-
387
- if (columnVirtualizer && virtualColumns?.length) {
388
- virtualPaddingLeft = virtualColumns[0]?.start ?? 0;
389
- virtualPaddingRight =
390
- columnVirtualizer.getTotalSize() -
391
- (virtualColumns[virtualColumns.length - 1]?.end ?? 0);
392
- }
393
-
394
- const empty = table.getRowModel().rows.length === 0;
395
-
396
- return (
397
- <DndContext
398
- id={dndId}
399
- collisionDetection={closestCenter}
400
- modifiers={[restrictToHorizontalAxis]}
401
- onDragEnd={handleDragEnd}
402
- sensors={sensors}
403
- >
404
- <SortableContext
405
- items={columnOrder}
406
- strategy={horizontalListSortingStrategy}
407
- >
408
- <div
409
- id={id}
410
- data-testid={testid}
411
- className="flex flex-col grow-0 h-fit w-full rounded border border-border-primary-normal overflow-hidden text-text-primary-normal"
412
- >
413
- <div
414
- className={clsx(
415
- "flex overflow-auto scrollbar-thin relative contain-paint will-change-transform",
416
- empty ? "overflow-y-hidden" : "min-h-[120px]",
417
- )}
418
- ref={containerRef}
419
- >
420
- <PinnedColumns
421
- testid={testid}
422
- pinDirection="left"
423
- table={table}
424
- tableContainerRef={containerRef}
425
- pagination={pagination}
426
- isLoadingMore={isLoadingMore}
427
- hasMore={hasMore}
428
- showFilterRow={showFilterRow}
429
- />
430
-
431
- <table className="flex-1 flex flex-col min-h-min">
432
- <thead className="sticky top-0 z-10 grid">
433
- {table.getCenterHeaderGroups().map((headerGroup) => (
434
- <tr
435
- data-testid={
436
- testid
437
- ? `${testid}-header-row-${headerGroup.id}`
438
- : undefined
439
- }
440
- key={headerGroup.id}
441
- className="flex w-full"
442
- >
443
- {virtualPaddingLeft ? (
444
- // fake empty column to the left for virtualization scroll padding
445
- <th
446
- style={{ display: "flex", width: virtualPaddingLeft }}
447
- />
448
- ) : null}
449
-
450
- {virtualColumns.map((virtualColumn) => {
451
- const header = headerGroup.headers[virtualColumn.index];
452
- if (!header) {
453
- return;
454
- }
455
-
456
- if (typeof header.column.columnDef.header === "string") {
457
- const cellValue = table
458
- .getRowModel()
459
- .rows[0]?.getValue(header.column.id);
460
-
461
- // removed forced type usage
462
- const cellAlignment =
463
- header.column.columnDef.meta?.align ??
464
- (typeof cellValue === "number" ? "right" : "left");
465
-
466
- return (
467
- <DraggableCellHeader
468
- key={header.id}
469
- minWidth={`${header.column.getSize()}px`}
470
- id={id ? `${id}-header-${header.id}` : undefined}
471
- testid={
472
- testid
473
- ? `${testid}-header-${header.id}`
474
- : undefined
475
- }
476
- header={header}
477
- locked={header.column.columnDef.meta?.locked}
478
- center={centerHeader}
479
- className={clsx(
480
- header.column.getCanSort()
481
- ? "cursor-pointer"
482
- : "cursor-grab",
483
- "group",
484
- {
485
- "justify-start": cellAlignment === "left",
486
- "justify-end": cellAlignment === "right",
487
- },
488
- )}
489
- useMenuDefaultMinWidth={useMenuDefaultMinWidth}
490
- >
491
- {cellAlignment === "left" && (
492
- <Subheader tall>
493
- {header.column.columnDef.header}
494
- </Subheader>
495
- )}
496
-
497
- {getSortIcon(header.column.getIsSorted())}
498
-
499
- {!header.column.getIsSorted() &&
500
- header.column.getCanSort() &&
501
- getSortIcon(
502
- header.column.getNextSortingOrder(),
503
- true,
504
- )}
505
-
506
- {header.column.getSortIndex() !== -1 &&
507
- table.getState().sorting.length > 1 && (
508
- <Subheader tall>
509
- {header.column.getSortIndex() + 1}
510
- </Subheader>
511
- )}
512
- {cellAlignment === "right" && (
513
- <Subheader tall>
514
- {header.column.columnDef.header}
515
- </Subheader>
516
- )}
517
- <div
518
- onDoubleClick={(e) => {
519
- e.stopPropagation();
520
- header.column.resetSize();
521
- }}
522
- onMouseDown={(e) => {
523
- e.stopPropagation();
524
- header.getResizeHandler()(e);
525
- }}
526
- onTouchStart={(e) => {
527
- e.stopPropagation();
528
- header.getResizeHandler()(e);
529
- }}
530
- className="absolute right-0 inset-y-0 w-px bg-black cursor-col-resize"
531
- />
532
- </DraggableCellHeader>
533
- );
534
- }
535
- return (
536
- <React.Fragment key={header.id}>
537
- {header.column.columnDef.meta?.checkbox ? (
538
- <DataGridCell
539
- id={id ? `${id}-header-${header.id}` : undefined}
540
- testid={
541
- testid
542
- ? `${testid}-header-${header.id}`
543
- : undefined
544
- }
545
- type="header"
546
- component="checkbox"
547
- locked
548
- >
549
- <Checkbox
550
- id={
551
- id ? `${id}-select-all-checkbox` : undefined
552
- }
553
- testid={
554
- testid
555
- ? `${testid}-select-all-checkbox`
556
- : undefined
557
- }
558
- checked={allSelectedAcrossPages}
559
- indeterminate={someSelectedAcrossPages}
560
- onChange={toggleSelectAllAcrossPages}
561
- />
562
- </DataGridCell>
563
- ) : (
564
- flexRender(
565
- header.column.columnDef.header,
566
- header.getContext(),
567
- )
568
- )}
569
- </React.Fragment>
570
- );
571
- })}
572
-
573
- {virtualPaddingRight ? (
574
- //fake empty column to the right for virtualization scroll padding
575
- <th
576
- style={{ display: "flex", width: virtualPaddingRight }}
577
- />
578
- ) : null}
579
- </tr>
580
- ))}
581
- </thead>
582
-
583
- <TableBody
584
- id={id}
585
- testid={testid}
586
- columnVirtualizer={columnVirtualizer}
587
- table={table}
588
- tableContainerRef={containerRef}
589
- virtualPaddingLeft={virtualPaddingLeft}
590
- virtualPaddingRight={virtualPaddingRight}
591
- pagination={pagination}
592
- isLoadingMore={isLoadingMore}
593
- hasMore={hasMore}
594
- showFilterRow={showFilterRow}
595
- enableColumnSelector={enableColumnSelector}
596
- rowDisabled={rowDisabled}
597
- rowDisabledAccessor={rowDisabledAccessor}
598
- />
599
- </table>
600
-
601
- <PinnedColumns
602
- id={id}
603
- enableColumnSelector={enableColumnSelector}
604
- toggleColumnVisibility={toggleColumnVisibility}
605
- resetColumnVisibility={resetDefaultColumnVisibility}
606
- testid={testid}
607
- pinDirection="right"
608
- table={table}
609
- tableContainerRef={containerRef}
610
- pagination={pagination}
611
- isLoadingMore={isLoadingMore}
612
- hasMore={hasMore}
613
- showFilterRow={showFilterRow}
614
- />
615
- </div>
616
-
617
- {empty && (
618
- <div
619
- className={clsx(
620
- NO_RESULTS_HEIGHT,
621
- "flex flex-col items-center justify-center",
622
- componentGap,
623
- componentPadding,
624
- )}
625
- data-testid={testid ? `${testid}-no-results` : undefined}
626
- >
627
- <img
628
- src={
629
- (NoResultsImg as { src: string })?.src ??
630
- (NoResultsImg as unknown as string)
631
- }
632
- alt="No Results"
633
- className="h-30 opacity-20"
634
- width={120}
635
- height={120}
636
- />
637
- <Subheader color="text-secondary-normal">No Results</Subheader>
638
- <Paragraph color="text-secondary-normal">
639
- To view results, enter or update your search criteria.
640
- </Paragraph>
641
- </div>
642
- )}
643
-
644
- {!hideStatusBar && (
645
- <div className="p-2 pt-[7px] border-t border-border-primary-normal h-full min-h-[34px]">
646
- {pagination && (
647
- <div className="flex justify-between items-center">
648
- <div className="flex items-center gap-1 w-min">
649
- <Select
650
- id={id ? `${id}-pagesize-select` : undefined}
651
- testid={testid ? `${testid}-pagesize-select` : undefined}
652
- wrapperClassName="!w-20"
653
- value={pagination.pageSize.toString()}
654
- onChange={(e) =>
655
- pagination.onPageSizeChange?.(Number(e.target.value))
656
- }
657
- renderMenu={(props) => (
658
- <Menu
659
- {...props}
660
- id={id ? `${id}-pagesize-menu` : undefined}
661
- testid={
662
- testid ? `${testid}-pagesize-menu` : undefined
663
- }
664
- >
665
- {PAGE_SIZE_OPTIONS.map((option) => (
666
- <MenuOption
667
- id={
668
- id
669
- ? `${id}-pagesize-option-${option}`
670
- : undefined
671
- }
672
- key={option}
673
- selected={pagination.pageSize === option}
674
- onClick={() =>
675
- pagination.onPageSizeChange?.(option)
676
- }
677
- >
678
- {option}
679
- </MenuOption>
680
- ))}
681
- </Menu>
682
- )}
683
- />
684
- <Label>Per Page</Label>
685
- </div>
686
-
687
- <div className="flex items-center gap-2">
688
- <Button
689
- id={id ? `${id}-prev-page-button` : undefined}
690
- testid={testid ? `${testid}-prev-page-button` : undefined}
691
- iconOnly
692
- leftIcon={<Icon name="chevron_left" />}
693
- onClick={() =>
694
- pagination.onPageChange(pagination.pageIndex - 1)
695
- }
696
- variant="tertiary"
697
- disabled={pagination.pageIndex === 0}
698
- />
699
- <Paragraph>
700
- {pagination.pageIndex * pagination.pageSize + 1} -{" "}
701
- {Math.min(
702
- (pagination.pageIndex + 1) * pagination.pageSize,
703
- pagination.total,
704
- )}{" "}
705
- of {pagination.total}
706
- </Paragraph>
707
- <Button
708
- id={id ? `${id}-next-page-button` : undefined}
709
- testid={testid ? `${testid}-next-page-button` : undefined}
710
- iconOnly
711
- leftIcon={<Icon name="chevron_right" />}
712
- onClick={() =>
713
- pagination.onPageChange(pagination.pageIndex + 1)
714
- }
715
- variant="tertiary"
716
- disabled={
717
- (pagination.pageIndex + 1) * pagination.pageSize >=
718
- pagination.total
719
- }
720
- />
721
- </div>
722
- </div>
723
- )}
724
-
725
- {status && (
726
- <Paragraph
727
- testid={testid ? `${testid}-status-text` : undefined}
728
- >
729
- {status}
730
- </Paragraph>
731
- )}
732
- </div>
733
- )}
734
- </div>
735
- </SortableContext>
736
- </DndContext>
737
- );
738
- }
739
- DataGrid.displayName = "DataGrid";
740
-
741
- // Utils
742
- function adaptTableStateSetter<T>(
743
- setter: React.Dispatch<React.SetStateAction<T>>,
744
- ) {
745
- return (valueOrFn: T | ((prev: T) => T)) => {
746
- setter((prev) =>
747
- typeof valueOrFn === "function"
748
- ? (valueOrFn as (prev: T) => T)(prev)
749
- : valueOrFn,
750
- );
751
- };
752
- }
753
-
754
- export type { ColumnDef } from "@tanstack/react-table";
755
-
756
- export default DataGrid;