@opencorestack/opengridx 2.0.4 → 3.0.0

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 (221) hide show
  1. package/CHANGELOG.md +408 -3
  2. package/README.md +93 -72
  3. package/dist/index.d.ts +611 -121
  4. package/dist/opengridx.css +1 -1
  5. package/dist/opengridx.es.js +7992 -5650
  6. package/dist/opengridx.es.js.map +1 -1
  7. package/dist/opengridx.umd.js +17 -23
  8. package/dist/opengridx.umd.js.map +1 -1
  9. package/docs/API_REFERENCE.md +348 -161
  10. package/docs/README.md +6 -1
  11. package/docs/architecture/datagrid-orchestration.md +81 -0
  12. package/docs/architecture/grid-row-meta.md +102 -0
  13. package/docs/architecture/use-grid-columns.md +128 -0
  14. package/docs/architecture/use-grid-controlled-state.md +157 -0
  15. package/docs/architecture/use-grid-row-pipeline.md +120 -0
  16. package/docs/architecture/use-grid-scroll-sync.md +111 -0
  17. package/docs/architecture/use-grid-state-snapshot.md +90 -0
  18. package/docs/architecture/use-grid-virtualization.md +115 -0
  19. package/docs/architecture/use-grid-visible-rows.md +85 -0
  20. package/docs/assets/banner-alt.png +0 -0
  21. package/docs/assets/banner.png +0 -0
  22. package/docs/assets/hero.png +0 -0
  23. package/docs/assets/logo.png +0 -0
  24. package/docs/components/aggregation-footer.md +15 -10
  25. package/docs/components/cell.md +16 -6
  26. package/docs/components/column-group-header.md +55 -28
  27. package/docs/components/column-resize.md +17 -13
  28. package/docs/components/column-visibility.md +45 -22
  29. package/docs/components/datagrid.md +14 -12
  30. package/docs/components/empty-state.md +2 -1
  31. package/docs/components/error-overlay.md +12 -7
  32. package/docs/components/filter-panel.md +28 -8
  33. package/docs/components/header.md +28 -9
  34. package/docs/components/pagination.md +14 -8
  35. package/docs/components/row.md +21 -5
  36. package/docs/components/toolbar.md +27 -9
  37. package/docs/components/tooltip.md +16 -7
  38. package/docs/customization/slots-api.md +100 -36
  39. package/docs/customization/theming.md +66 -18
  40. package/docs/features/aggregation-pivot.md +75 -9
  41. package/docs/features/cell-spanning.md +80 -125
  42. package/docs/features/clipboard.md +41 -16
  43. package/docs/features/custom-pagination.md +38 -18
  44. package/docs/features/data-source.md +36 -13
  45. package/docs/features/editing-reordering.md +125 -16
  46. package/docs/features/export-guide.md +147 -41
  47. package/docs/features/filtering.md +44 -6
  48. package/docs/features/infinite-scroll.md +54 -46
  49. package/docs/features/keyboard-navigation.md +83 -0
  50. package/docs/features/list-view.md +58 -5
  51. package/docs/features/loading-states.md +18 -20
  52. package/docs/features/master-detail.md +18 -5
  53. package/docs/features/pdf-export.md +56 -19
  54. package/docs/features/pinning.md +23 -5
  55. package/docs/features/selection.md +50 -10
  56. package/docs/features/sorting-pagination.md +66 -14
  57. package/docs/features/state-persistence.md +78 -10
  58. package/docs/features/toolbar-customization.md +26 -17
  59. package/docs/features/tree-data-grouping.md +44 -9
  60. package/docs/features/virtualization.md +64 -15
  61. package/docs/migration/v1-to-v2.md +115 -0
  62. package/docs/migration/v2-to-v3.md +1222 -0
  63. package/docs/performance.md +124 -0
  64. package/docs/roadmap.md +16 -10
  65. package/lib/components/Cell/Cell.css +13 -1
  66. package/lib/components/Cell/Cell.tsx +130 -57
  67. package/lib/components/Cell/CellErrorBoundary.tsx +12 -6
  68. package/lib/components/Cell/GridEditInputCell.tsx +114 -41
  69. package/lib/components/ColumnGroupHeader/ColumnGroupHeader.css +7 -1
  70. package/lib/components/ColumnResizeHandle/ColumnResizeHandle.css +11 -0
  71. package/lib/components/ColumnResizeHandle/ColumnResizeHandle.tsx +104 -38
  72. package/lib/components/ColumnResizeHandle/clampResizeWidth.ts +13 -0
  73. package/lib/components/ColumnVisibilityPanel/ColumnVisibilityPanel.css +6 -0
  74. package/lib/components/ColumnVisibilityPanel/ColumnVisibilityPanel.tsx +21 -13
  75. package/lib/components/DataGrid/DataGrid.css +84 -12
  76. package/lib/components/DataGrid/DataGrid.tsx +606 -872
  77. package/lib/components/DataGrid/GridAggregationFooter.tsx +53 -17
  78. package/lib/components/DataGrid/GridEmptyState.tsx +7 -1
  79. package/lib/components/DataGrid/GridErrorOverlay.tsx +15 -12
  80. package/lib/components/DataGrid/GridListView.tsx +166 -23
  81. package/lib/components/DataGrid/GridLiveRegion.tsx +31 -0
  82. package/lib/components/DataGrid/GridLoadingOverlay.tsx +27 -0
  83. package/lib/components/DataGrid/GridPaginationArea.tsx +44 -0
  84. package/lib/components/DataGrid/GridPinnedRows.tsx +65 -11
  85. package/lib/components/DataGrid/GridStandaloneColumnPanel.tsx +40 -38
  86. package/lib/components/DataGrid/GridToolbarSlot.tsx +51 -0
  87. package/lib/components/DataGrid/GridVirtualRows.tsx +48 -25
  88. package/lib/components/DetailPanel/DetailPanel.css +0 -6
  89. package/lib/components/DetailPanel/DetailPanel.tsx +34 -5
  90. package/lib/components/DetailPanel/DetailPanelContent.tsx +17 -0
  91. package/lib/components/FilterPanel/FilterPanel.css +13 -2
  92. package/lib/components/FilterPanel/FilterPanel.tsx +272 -99
  93. package/lib/components/Header/ColumnMenu.tsx +91 -39
  94. package/lib/components/Header/Header.css +3 -3
  95. package/lib/components/Header/Header.tsx +179 -160
  96. package/lib/components/ListView/ListView.css +25 -0
  97. package/lib/components/ListView/ListViewRow.tsx +79 -10
  98. package/lib/components/Pagination/Pagination.tsx +15 -7
  99. package/lib/components/Row/Row.tsx +185 -75
  100. package/lib/components/Toolbar/GlobalSearch.css +6 -3
  101. package/lib/components/Toolbar/GlobalSearch.tsx +26 -27
  102. package/lib/components/Toolbar/GridToolbar.css +12 -11
  103. package/lib/components/Toolbar/GridToolbar.tsx +133 -89
  104. package/lib/components/Toolbar/PivotPanel.tsx +89 -49
  105. package/lib/components/Tooltip/Tooltip.css +20 -0
  106. package/lib/components/Tooltip/Tooltip.tsx +68 -35
  107. package/lib/components/ui/Button.tsx +3 -0
  108. package/lib/components/ui/Checkbox.tsx +2 -1
  109. package/lib/components/ui/ExpandIcon.css +0 -9
  110. package/lib/components/ui/ExpandIcon.tsx +4 -1
  111. package/lib/hooks/core/gridApiPlaceholder.ts +34 -0
  112. package/lib/hooks/core/gridToolbarHostContext.ts +14 -0
  113. package/lib/hooks/core/useDataGrid.ts +115 -173
  114. package/lib/hooks/core/useGridAggregationApi.ts +72 -0
  115. package/lib/hooks/core/useGridApiMethods.ts +115 -0
  116. package/lib/hooks/core/useGridApiRef.ts +15 -3
  117. package/lib/hooks/core/useGridApiRefBinding.ts +18 -0
  118. package/lib/hooks/core/useGridAriaRows.ts +38 -0
  119. package/lib/hooks/core/useGridClipboardApi.ts +38 -0
  120. package/lib/hooks/core/useGridColumnLookup.ts +30 -0
  121. package/lib/hooks/core/useGridColumns.tsx +284 -76
  122. package/lib/hooks/core/useGridColumnsPanel.ts +77 -0
  123. package/lib/hooks/core/useGridControlledState.ts +99 -6
  124. package/lib/hooks/core/useGridDetailPanel.ts +51 -0
  125. package/lib/hooks/core/useGridDevWarnings.ts +123 -0
  126. package/lib/hooks/core/useGridFocusHandlers.ts +50 -0
  127. package/lib/hooks/core/useGridGroupingColumn.ts +62 -0
  128. package/lib/hooks/core/useGridHeaderHandlers.ts +92 -0
  129. package/lib/hooks/core/useGridHierarchy.ts +81 -0
  130. package/lib/hooks/core/useGridKeyboardNavigation.ts +452 -250
  131. package/lib/hooks/core/useGridLiveRowSelection.ts +67 -0
  132. package/lib/hooks/core/useGridPageCorrection.ts +55 -0
  133. package/lib/hooks/core/useGridRowIdOf.ts +32 -0
  134. package/lib/hooks/core/useGridRowInteractions.ts +81 -0
  135. package/lib/hooks/core/useGridRowPipeline.ts +69 -39
  136. package/lib/hooks/core/useGridRowSelection.ts +91 -0
  137. package/lib/hooks/core/useGridScrollSync.ts +80 -32
  138. package/lib/hooks/core/useGridScrollToIndexesApi.ts +45 -0
  139. package/lib/hooks/core/useGridStateSnapshot.ts +40 -5
  140. package/lib/hooks/core/useGridThemeDimensions.ts +49 -0
  141. package/lib/hooks/core/useGridToolbarProps.ts +97 -0
  142. package/lib/hooks/core/useGridViewport.ts +38 -0
  143. package/lib/hooks/core/useGridViewportSize.ts +26 -0
  144. package/lib/hooks/core/useGridVisibleRows.ts +20 -7
  145. package/lib/hooks/core/useLayout.ts +215 -195
  146. package/lib/hooks/core/useRowsScrollEndLatch.ts +41 -0
  147. package/lib/hooks/core/useStableColumns.ts +34 -0
  148. package/lib/hooks/features/useAggregation.ts +86 -90
  149. package/lib/hooks/features/useColumnGroupReorderGuard.ts +34 -0
  150. package/lib/hooks/features/useDetailPanelHeights.ts +29 -0
  151. package/lib/hooks/features/useGridClipboard.ts +133 -73
  152. package/lib/hooks/features/useGridDataSource.ts +354 -128
  153. package/lib/hooks/features/useGridEditing.ts +211 -51
  154. package/lib/hooks/features/useGridPivot.ts +92 -0
  155. package/lib/hooks/features/useGridSpanRenderWindow.ts +104 -0
  156. package/lib/hooks/features/useGridSpanning.ts +410 -306
  157. package/lib/hooks/features/usePivot.ts +0 -0
  158. package/lib/hooks/features/useServerTreeChildren.ts +50 -0
  159. package/lib/hooks/useColumnReorder.ts +38 -44
  160. package/lib/hooks/useRowGrouping.ts +335 -214
  161. package/lib/hooks/useRowReorder.ts +62 -31
  162. package/lib/hooks/useTreeData.ts +330 -262
  163. package/lib/index.ts +30 -2
  164. package/lib/state/index.ts +1 -0
  165. package/lib/state/types.ts +7 -1
  166. package/lib/state/useGridStateStorage.ts +88 -29
  167. package/lib/theme/DataGridThemeProvider.tsx +143 -38
  168. package/lib/theme/gridThemeContext.ts +5 -0
  169. package/lib/theme/index.ts +5 -0
  170. package/lib/theme/presets.ts +5 -4
  171. package/lib/theme/types.ts +40 -2
  172. package/lib/types/index.ts +311 -108
  173. package/lib/utils/aggregation/index.ts +157 -0
  174. package/lib/utils/aria/index.ts +40 -0
  175. package/lib/utils/columnGroups.ts +110 -0
  176. package/lib/utils/columnLookup.ts +33 -0
  177. package/lib/utils/columnWidth.ts +22 -0
  178. package/lib/utils/dataSource/index.ts +46 -0
  179. package/lib/utils/detailPanel.ts +66 -0
  180. package/lib/utils/dragData.ts +44 -0
  181. package/lib/utils/editing/index.ts +30 -0
  182. package/lib/utils/export/exportShared.ts +197 -0
  183. package/lib/utils/export/exportToExcelAdvanced.ts +344 -121
  184. package/lib/utils/export/exportToPdf.ts +143 -92
  185. package/lib/utils/export/groupLabel.ts +14 -0
  186. package/lib/utils/export/index.ts +278 -272
  187. package/lib/utils/export/pdfText.ts +50 -0
  188. package/lib/utils/filtering/index.ts +277 -148
  189. package/lib/utils/focus/index.ts +115 -0
  190. package/lib/utils/gridApiRows.ts +35 -0
  191. package/lib/utils/gridModes.ts +77 -0
  192. package/lib/utils/grouping/groupedExportRows.ts +91 -0
  193. package/lib/utils/pagination/index.ts +56 -0
  194. package/lib/utils/pinning/index.ts +77 -33
  195. package/lib/utils/pivot/index.ts +368 -0
  196. package/lib/utils/scroll/index.ts +78 -0
  197. package/lib/utils/scroll/scrollEnd.ts +18 -0
  198. package/lib/utils/sorting/index.ts +154 -30
  199. package/lib/utils/syntheticRows.ts +12 -0
  200. package/lib/utils/values.ts +206 -0
  201. package/lib/utils/viewport.ts +14 -0
  202. package/llms.txt +272 -166
  203. package/package.json +18 -6
  204. package/lib/components/ColumnGroupHeader/ColumnGroupHeader.tsx +0 -220
  205. package/lib/components/ColumnVisibilityPanel/ColumnVisibilityPanel.test.tsx +0 -85
  206. package/lib/components/DataGrid/DataGrid.regression.test.tsx +0 -132
  207. package/lib/components/DataGrid/DataGrid.smoke.test.tsx +0 -58
  208. package/lib/components/DataGrid/DataGrid.v2.test.tsx +0 -127
  209. package/lib/components/Header/Header.test.tsx +0 -135
  210. package/lib/components/Pagination/Pagination.test.tsx +0 -64
  211. package/lib/hooks/core/useDataGrid.regression.test.ts +0 -66
  212. package/lib/hooks/core/useGridControlledState.test.ts +0 -86
  213. package/lib/hooks/core/useGridKeyboardNavigation.test.ts +0 -176
  214. package/lib/hooks/core/useGridRowPipeline.test.ts +0 -117
  215. package/lib/hooks/features/useAggregation.test.ts +0 -175
  216. package/lib/hooks/features/usePivot.test.ts +0 -202
  217. package/lib/hooks/useRowGrouping.test.ts +0 -137
  218. package/lib/utils/export/exportToPdf.test.ts +0 -120
  219. package/lib/utils/export/groupedExport.test.ts +0 -144
  220. package/lib/utils/filtering/filtering.test.ts +0 -178
  221. package/lib/utils/sorting/sorting.test.ts +0 -88
@@ -1,8 +1,14 @@
1
- import { useState, useCallback } from 'react';
1
+ import { useState, useCallback, useMemo, useRef, useEffect } from 'react';
2
2
  import type { GridRowId, GridRowModel, GridRowOrderChangeParams } from '../types';
3
+ import { ROW_DRAG_MIME, hasDragToken, onNativeDragEnd, setDragToken } from '../utils/dragData';
3
4
 
4
5
  export interface UseRowReorderProps<R extends GridRowModel = GridRowModel> {
5
6
  onRowOrderChange?: (params: GridRowOrderChangeParams<R>) => void;
7
+ /**
8
+ * The consumer's rows, in the order the consumer gave them (not the sorted, filtered or
9
+ * paginated view). `oldIndex` / `targetIndex` are positions in this array, and only rows in it
10
+ * can be dragged or dropped on, so grid-made rows (group rows, generated tree parents) cannot.
11
+ */
6
12
  rows: R[];
7
13
  getRowId?: (row: R) => GridRowId;
8
14
  rowReordering?: boolean;
@@ -11,6 +17,8 @@ export interface UseRowReorderProps<R extends GridRowModel = GridRowModel> {
11
17
  export interface UseRowReorderReturn {
12
18
  draggedRowId: GridRowId | null;
13
19
  dragOverRowId: GridRowId | null;
20
+ /** Whether the row with this id can be dragged and dropped on. */
21
+ canReorderRow: (id: GridRowId) => boolean;
14
22
  onDragStart: ((id: GridRowId) => (event: React.DragEvent) => void) | undefined;
15
23
  onDragOver: ((id: GridRowId) => (event: React.DragEvent) => void) | undefined;
16
24
  onDragEnd: (() => void) | undefined;
@@ -23,58 +31,81 @@ export function useRowReorder<R extends GridRowModel = GridRowModel>(
23
31
  const { onRowOrderChange, rows, getRowId, rowReordering = false } = props;
24
32
  const [draggedRowId, setDraggedRowId] = useState<GridRowId | null>(null);
25
33
  const [dragOverRowId, setDragOverRowId] = useState<GridRowId | null>(null);
34
+ const detachDragEndRef = useRef<() => void>(() => {});
26
35
 
27
- const getRowIdInternal = useCallback((row: R) => {
28
- return getRowId ? getRowId(row) : row.id;
29
- }, [getRowId]);
36
+ const indexById = useMemo(() => {
37
+ const map = new Map<GridRowId, number>();
38
+ rows.forEach((row, index) => map.set(getRowId ? getRowId(row) : row.id, index));
39
+ return map;
40
+ }, [rows, getRowId]);
41
+
42
+ const canReorderRow = useCallback((id: GridRowId) => indexById.has(id), [indexById]);
43
+
44
+ const handleDragEnd = useCallback(() => {
45
+ detachDragEndRef.current();
46
+ detachDragEndRef.current = () => {};
47
+ setDraggedRowId(null);
48
+ setDragOverRowId(null);
49
+ }, []);
50
+
51
+ useEffect(() => () => detachDragEndRef.current(), []);
30
52
 
31
53
  const handleDragStart = useCallback((id: GridRowId) => (event: React.DragEvent) => {
32
54
  if (!rowReordering) return;
55
+ if (!indexById.has(id)) {
56
+ event.preventDefault();
57
+ return;
58
+ }
59
+ detachDragEndRef.current();
60
+ // Ends the drag even if the source row unmounts before the browser's dragend.
61
+ detachDragEndRef.current = onNativeDragEnd(event.currentTarget, handleDragEnd);
33
62
  setDraggedRowId(id);
34
- event.dataTransfer.effectAllowed = 'move';
35
-
36
- }, [rowReordering]);
63
+ if (event.dataTransfer) {
64
+ event.dataTransfer.effectAllowed = 'move';
65
+ setDragToken(event, ROW_DRAG_MIME, String(id));
66
+ }
67
+ }, [rowReordering, indexById, handleDragEnd]);
37
68
 
38
69
  const handleDragOver = useCallback((id: GridRowId) => (event: React.DragEvent) => {
39
- if (!rowReordering || !draggedRowId) return;
40
- event.preventDefault();
41
- event.dataTransfer.dropEffect = 'move';
70
+ if (!rowReordering || draggedRowId === null) return;
71
+ if (!hasDragToken(event, ROW_DRAG_MIME)) {
72
+ // Some other drag (a file, text, a column): any row drag we remember is over.
73
+ handleDragEnd();
74
+ return;
75
+ }
76
+ if (!indexById.has(id)) return;
77
+ event.preventDefault();
78
+ if (event.dataTransfer) event.dataTransfer.dropEffect = 'move';
42
79
 
43
80
  if (dragOverRowId !== id) {
44
81
  setDragOverRowId(id);
45
82
  }
46
- }, [rowReordering, draggedRowId, dragOverRowId]);
47
-
48
- const handleDragEnd = useCallback(() => {
49
- setDraggedRowId(null);
50
- setDragOverRowId(null);
51
- }, []);
83
+ }, [rowReordering, draggedRowId, dragOverRowId, indexById, handleDragEnd]);
52
84
 
53
85
  const handleDrop = useCallback((targetId: GridRowId) => (event: React.DragEvent) => {
54
86
  event.preventDefault();
55
-
56
- if (!draggedRowId || !onRowOrderChange) {
57
- handleDragEnd();
58
- return;
87
+ if (draggedRowId === null || !hasDragToken(event, ROW_DRAG_MIME)) {
88
+ handleDragEnd();
89
+ return;
59
90
  }
60
91
 
61
- const oldIndex = rows.findIndex(r => getRowIdInternal(r) === draggedRowId);
62
- const targetIndex = rows.findIndex(r => getRowIdInternal(r) === targetId);
92
+ const oldIndex = indexById.get(draggedRowId);
93
+ const targetIndex = indexById.get(targetId);
94
+ handleDragEnd();
63
95
 
64
- if (oldIndex !== -1 && targetIndex !== -1 && oldIndex !== targetIndex) {
65
- onRowOrderChange({
66
- row: rows[oldIndex],
67
- oldIndex,
68
- targetIndex
69
- });
96
+ if (onRowOrderChange && oldIndex !== undefined && targetIndex !== undefined && oldIndex !== targetIndex) {
97
+ onRowOrderChange({
98
+ row: rows[oldIndex],
99
+ oldIndex,
100
+ targetIndex
101
+ });
70
102
  }
71
-
72
- handleDragEnd();
73
- }, [draggedRowId, onRowOrderChange, rows, getRowIdInternal, handleDragEnd]);
103
+ }, [draggedRowId, onRowOrderChange, rows, indexById, handleDragEnd]);
74
104
 
75
105
  return {
76
106
  draggedRowId,
77
107
  dragOverRowId,
108
+ canReorderRow,
78
109
  onDragStart: rowReordering ? handleDragStart : undefined,
79
110
  onDragOver: rowReordering ? handleDragOver : undefined,
80
111
  onDragEnd: rowReordering ? handleDragEnd : undefined,