@opencorestack/opengridx 3.6.0 → 3.7.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 (74) hide show
  1. package/CHANGELOG.md +39 -0
  2. package/dist/ai.cjs +3 -3
  3. package/dist/ai.cjs.map +1 -1
  4. package/dist/ai.es.js +3 -3
  5. package/dist/ai.es.js.map +1 -1
  6. package/dist/index.d.ts +30 -0
  7. package/dist/opengridx.css +1 -1
  8. package/dist/opengridx.es.js +8756 -8244
  9. package/dist/opengridx.es.js.map +1 -1
  10. package/dist/opengridx.umd.js +15 -15
  11. package/dist/opengridx.umd.js.map +1 -1
  12. package/docs/API_REFERENCE.md +3 -2
  13. package/docs/architecture/datagrid-orchestration.md +46 -29
  14. package/docs/architecture/grid-row-meta.md +1 -1
  15. package/docs/customization/slots-api.md +1 -1
  16. package/docs/customization/theming.md +43 -0
  17. package/docs/features/virtualization.md +16 -2
  18. package/docs/performance.md +3 -1
  19. package/lib/components/AiAssistant/GridAiAssistantPanel.css +3 -1
  20. package/lib/components/Cell/Cell.css +4 -2
  21. package/lib/components/ColumnGroupHeader/ColumnGroupHeader.css +2 -2
  22. package/lib/components/ColumnVisibilityPanel/ColumnVisibilityPanel.css +3 -1
  23. package/lib/components/DataGrid/DataGrid.css +9 -12
  24. package/lib/components/DataGrid/DataGrid.tsx +163 -671
  25. package/lib/components/DataGrid/GridRoot.tsx +239 -0
  26. package/lib/components/DataGrid/GridViewport.tsx +314 -0
  27. package/lib/components/FilterPanel/FilterPanel.css +9 -8
  28. package/lib/components/Header/ColumnMenu.css +4 -3
  29. package/lib/components/Header/Header.css +5 -4
  30. package/lib/components/HeaderFilter/HeaderFilter.css +1 -1
  31. package/lib/components/ListView/ListView.css +4 -4
  32. package/lib/components/Pagination/Pagination.css +1 -1
  33. package/lib/components/Row/Row.css +2 -2
  34. package/lib/components/Toolbar/GridToolbar.css +8 -7
  35. package/lib/components/Toolbar/PivotPanel.css +3 -3
  36. package/lib/hooks/core/useGridDevWarnings.ts +3 -1
  37. package/lib/hooks/core/useGridEditPipeline.ts +55 -0
  38. package/lib/hooks/core/useGridRangeEditing.ts +129 -0
  39. package/lib/hooks/core/useGridRenderWindow.ts +66 -0
  40. package/lib/hooks/core/useGridScrollViewport.ts +42 -0
  41. package/lib/hooks/core/useGridSelectionAndStateApi.ts +61 -0
  42. package/lib/hooks/core/useGridToolbarStack.ts +49 -0
  43. package/lib/hooks/core/useGridViewApis.ts +46 -0
  44. package/lib/hooks/core/useLayout.ts +34 -24
  45. package/lib/styles/base/reset.css +5 -3
  46. package/lib/styles/base/variables.css +12 -0
  47. package/lib/theme/DataGridThemeProvider.tsx +15 -0
  48. package/lib/theme/__baseline__/default-theme.darwin.chromium.json +1503 -0
  49. package/lib/theme/__baseline__/default-theme.darwin.firefox.json +1503 -0
  50. package/lib/theme/__baseline__/default-theme.darwin.webkit.json +1503 -0
  51. package/lib/theme/types.ts +31 -0
  52. package/lib/types/ai.ts +109 -0
  53. package/lib/types/api.ts +169 -0
  54. package/lib/types/columns.ts +341 -0
  55. package/lib/types/dataSource.ts +40 -0
  56. package/lib/types/editing.ts +77 -0
  57. package/lib/types/export.ts +164 -0
  58. package/lib/types/filtering.ts +52 -0
  59. package/lib/types/grouping.ts +27 -0
  60. package/lib/types/index.ts +18 -1702
  61. package/lib/types/locale.ts +51 -0
  62. package/lib/types/props.ts +405 -0
  63. package/lib/types/rows.ts +132 -0
  64. package/lib/types/selection.ts +66 -0
  65. package/lib/types/slots.ts +56 -0
  66. package/lib/types/sorting.ts +25 -0
  67. package/lib/types/state.ts +35 -0
  68. package/lib/utils/export/exportShared.ts +22 -4
  69. package/lib/utils/export/index.ts +8 -4
  70. package/lib/utils/filtering/index.ts +8 -2
  71. package/lib/utils/parsing.ts +24 -1
  72. package/lib/utils/values.ts +31 -0
  73. package/llms.txt +1 -1
  74. package/package.json +4 -2
@@ -28,7 +28,7 @@
28
28
  }
29
29
 
30
30
  .ogx-list-view__row:hover {
31
- background: var(--ogx-color-gray-50, #f8fafc);
31
+ background: var(--ogx-grid-row-hover-background);
32
32
  }
33
33
 
34
34
  /* Keyboard focus (roving tab stop between list rows). */
@@ -41,11 +41,11 @@
41
41
  }
42
42
 
43
43
  .ogx-list-view__row--selected {
44
- background: var(--ogx-selection-bg, rgba(59, 130, 246, 0.08));
44
+ background: var(--ogx-selection-bg, var(--ogx-grid-row-selected-background));
45
45
  }
46
46
 
47
47
  .ogx-list-view__row--selected:hover {
48
- background: var(--ogx-selection-hover-bg, rgba(59, 130, 246, 0.13));
48
+ background: var(--ogx-selection-hover-bg, var(--ogx-grid-row-selected-hover-background));
49
49
  }
50
50
 
51
51
  /* ─── Checkbox column inside list row ────────────────────────────────────── */
@@ -79,7 +79,7 @@
79
79
  min-width: 0;
80
80
  font-family: var(--ogx-font-family);
81
81
  font-size: var(--ogx-font-size-sm);
82
- color: var(--ogx-grid-cell-text);
82
+ color: var(--ogx-grid-row-text);
83
83
  }
84
84
 
85
85
  /* ─── Toolbar in list view mode ──────────────────────────────────────────── */
@@ -9,7 +9,7 @@
9
9
  font-size: var(--ogx-font-size-sm);
10
10
  color: var(--ogx-grid-row-text);
11
11
  min-height: 52px;
12
- border-radius: 0 0 var(--ogx-border-radius-lg) var(--ogx-border-radius-lg);
12
+ border-radius: 0 0 var(--ogx-grid-border-radius, var(--ogx-border-radius-lg)) var(--ogx-grid-border-radius, var(--ogx-border-radius-lg));
13
13
  }
14
14
  .ogx-pagination__page-size {
15
15
  display: flex;
@@ -1,7 +1,7 @@
1
1
  .ogx__row {
2
2
  display: flex;
3
3
  align-items: stretch;
4
- border-bottom: 1px solid var(--ogx-grid-border-color);
4
+ border-bottom: var(--ogx-grid-row-divider-width) solid var(--ogx-grid-row-divider-color, var(--ogx-grid-border-color));
5
5
  background: var(--ogx-grid-background);
6
6
  position: relative;
7
7
  min-height: var(--ogx-row-height);
@@ -94,7 +94,7 @@
94
94
  }
95
95
  .ogx__row--skeleton {
96
96
  pointer-events: none;
97
- border-bottom: 1px solid var(--ogx-grid-border-color);
97
+ border-bottom: var(--ogx-grid-row-divider-width) solid var(--ogx-grid-row-divider-color, var(--ogx-grid-border-color));
98
98
  background-color: var(--ogx-grid-background);
99
99
  }
100
100
  .ogx__row--skeleton .ogx__skeleton-cell {
@@ -80,6 +80,7 @@
80
80
  z-index: 9999;
81
81
  overflow: hidden;
82
82
  animation: ogx-panel-in 0.15s ease-out;
83
+ font-family: var(--ogx-overlay-font-family, inherit);
83
84
  }
84
85
  @keyframes ogx-panel-in {
85
86
  from { opacity: 0; transform: translateY(-6px) scale(0.98); }
@@ -97,7 +98,7 @@
97
98
  display: flex;
98
99
  align-items: center;
99
100
  gap: var(--ogx-spacing-xs);
100
- font-family: var(--ogx-font-family);
101
+ font-family: var(--ogx-overlay-font-family, var(--ogx-font-family));
101
102
  font-size: var(--ogx-font-size-sm);
102
103
  font-weight: 600;
103
104
  color: var(--ogx-grid-header-text);
@@ -108,7 +109,7 @@
108
109
  border-radius: var(--ogx-border-radius-sm);
109
110
  background: transparent;
110
111
  color: var(--ogx-toolbar-btn-danger-text, var(--ogx-color-error, #ef4444));
111
- font-family: var(--ogx-font-family);
112
+ font-family: var(--ogx-overlay-font-family, var(--ogx-font-family));
112
113
  font-size: var(--ogx-font-size-xs);
113
114
  font-weight: 500;
114
115
  cursor: pointer;
@@ -124,7 +125,7 @@
124
125
  border-radius: var(--ogx-border-radius-sm);
125
126
  background: transparent;
126
127
  color: var(--ogx-grid-header-text);
127
- font-family: var(--ogx-font-family);
128
+ font-family: var(--ogx-overlay-font-family, var(--ogx-font-family));
128
129
  font-size: var(--ogx-font-size-xs);
129
130
  font-weight: 500;
130
131
  cursor: pointer;
@@ -142,7 +143,7 @@
142
143
  }
143
144
  .ogx-toolbar__empty {
144
145
  padding: var(--ogx-spacing-md) var(--ogx-spacing-md);
145
- font-family: var(--ogx-font-family);
146
+ font-family: var(--ogx-overlay-font-family, var(--ogx-font-family));
146
147
  font-size: var(--ogx-font-size-sm);
147
148
  color: var(--ogx-grid-header-text);
148
149
  line-height: 1.5;
@@ -171,9 +172,9 @@
171
172
  }
172
173
  .ogx-toolbar__agg-label {
173
174
  flex: 0 0 100px;
174
- font-family: var(--ogx-font-family);
175
- font-size: var(--ogx-font-size-xs);
176
- font-weight: 500;
175
+ font-family: var(--ogx-overlay-font-family, var(--ogx-font-family));
176
+ font-size: var(--ogx-overlay-font-size, var(--ogx-font-size-xs));
177
+ font-weight: var(--ogx-overlay-font-weight, 500);
177
178
  color: var(--ogx-grid-row-text);
178
179
  overflow: hidden;
179
180
  text-overflow: ellipsis;
@@ -9,7 +9,7 @@
9
9
  z-index: 9999;
10
10
  overflow: hidden;
11
11
  animation: ogx-panel-in 0.15s ease-out;
12
- font-family: var(--ogx-font-family);
12
+ font-family: var(--ogx-overlay-font-family, var(--ogx-font-family));
13
13
  }
14
14
  @keyframes ogx-panel-in {
15
15
  from { opacity: 0; transform: translateY(-6px) scale(0.98); }
@@ -37,7 +37,7 @@
37
37
  border-radius: var(--ogx-border-radius-sm);
38
38
  background: transparent;
39
39
  color: var(--ogx-color-error, #ef4444);
40
- font-family: var(--ogx-font-family);
40
+ font-family: var(--ogx-overlay-font-family, var(--ogx-font-family));
41
41
  font-size: var(--ogx-font-size-xs);
42
42
  font-weight: 500;
43
43
  cursor: pointer;
@@ -163,7 +163,7 @@
163
163
  border-radius: 999px;
164
164
  background: var(--ogx-grid-header-background);
165
165
  color: var(--ogx-grid-row-text);
166
- font-family: var(--ogx-font-family);
166
+ font-family: var(--ogx-overlay-font-family, var(--ogx-font-family));
167
167
  font-size: 12px;
168
168
  font-weight: 500;
169
169
  cursor: pointer;
@@ -87,7 +87,9 @@ export function useGridDevWarnings(params: UseGridDevWarningsParams): void {
87
87
  console.warn(
88
88
  `[OpenGridX] The grid content is ${Math.round(scrollHeight)}px tall, more than this browser lays out ` +
89
89
  '(about 17.9M px in Firefox, 33.5M px in Chrome and Safari). ' + reach +
90
- 'Use pagination, server-side or infinite loading, or a smaller rowHeight. See docs/features/virtualization.md.'
90
+ 'Load the rows on demand with a `dataSource` (server-side pages or infinite scroll, ' +
91
+ 'docs/features/data-source.md), use `pagination`, or a smaller rowHeight (density="compact"). ' +
92
+ 'See docs/features/virtualization.md#the-browser-height-limit.'
91
93
  );
92
94
  }, [scrollHeight, maxContentHeight, reachableRowCount, unpinnedRowCount]);
93
95
 
@@ -0,0 +1,55 @@
1
+ import type { GridColDef, GridRowId, GridRowModel } from '../../types';
2
+ import { useGridEditCommitChannel } from './useGridUndoRedo';
3
+ import { useGridBatchEdit, type UseGridBatchEditParams } from '../features/useGridBatchEdit';
4
+ import { useGridEditing } from '../features/useGridEditing';
5
+
6
+ export interface UseGridEditPipelineParams<R extends GridRowModel> {
7
+ /** The row store's lookup (rows stored since the last render are read through `batchEdit.getRow`). */
8
+ rowsLookup: ReadonlyMap<GridRowId, R>;
9
+ /** The stored rows, in store order. */
10
+ rows: R[];
11
+ getRowId: (row: R) => GridRowId;
12
+ columns: GridColDef<R>[];
13
+ processRowUpdate: UseGridBatchEditParams<R>['processRowUpdate'];
14
+ onProcessRowUpdateError: UseGridBatchEditParams<R>['onProcessRowUpdateError'];
15
+ replaceRows: UseGridBatchEditParams<R>['replaceRows'];
16
+ }
17
+
18
+ /**
19
+ * Steps 12a–13 of `DataGrid` (docs/architecture/datagrid-orchestration.md), in their call order: the edit
20
+ * commit channel, the batch edit and single-cell editing. Single edits store through `batchEdit.storeRow`
21
+ * and report to the channel; the undo/redo history (`useGridRangeEditing`, later) listens on it.
22
+ */
23
+ export function useGridEditPipeline<R extends GridRowModel>(params: UseGridEditPipelineParams<R>) {
24
+ const { rowsLookup, rows, getRowId, columns, processRowUpdate, onProcessRowUpdateError, replaceRows } = params;
25
+
26
+ // Commits (single edits and batch edits) reach the undo/redo history created further down.
27
+ const editCommitChannel = useGridEditCommitChannel();
28
+ // Batch edits (paste, range clear, undo, redo): one processRowUpdate per row, one store update.
29
+ const batchEdit = useGridBatchEdit<R>({
30
+ rowsLookup,
31
+ columns,
32
+ processRowUpdate,
33
+ onProcessRowUpdateError,
34
+ replaceRows,
35
+ onCommitted: editCommitChannel.emit,
36
+ });
37
+
38
+ const editingHandlers = useGridEditing({
39
+ rows,
40
+ getRowId,
41
+ columns,
42
+ processRowUpdate,
43
+ onProcessRowUpdateError,
44
+ onRowChange: (updatedRow, rowId) => {
45
+ // Replaces the edited row in the *current* store, under the edited row's id: this runs
46
+ // after an awaited processRowUpdate, by which time the rows prop (or a dataSource
47
+ // fetch) may have replaced the rows this render saw. The returned row is stored as is
48
+ // (the grid never writes an id onto it), even if it does not carry its key itself.
49
+ batchEdit.storeRow(rowId, updatedRow);
50
+ },
51
+ onCommitted: (changes) => editCommitChannel.emit(changes, 'edit'),
52
+ });
53
+
54
+ return { editCommitChannel, batchEdit, editingHandlers };
55
+ }
@@ -0,0 +1,129 @@
1
+ import type { MutableRefObject, RefObject } from 'react';
2
+ import type { DataGridProps, GridApi, GridCellParams, GridCellSelectionModel, GridColDef, GridRowId, GridRowMeta, GridRowModel } from '../../types';
3
+ import type { UseGridCellSelectionReturn } from './useGridCellSelection';
4
+ import type { FocusedCell } from './useGridKeyboardNavigation';
5
+ import type { LayoutResult } from './useLayout';
6
+ import type { UseGridBatchEditReturn } from '../features/useGridBatchEdit';
7
+ import { useGridCellSelectionApi } from './useGridCellSelectionApi';
8
+ import { useGridClipboardPaste } from './useGridClipboardPaste';
9
+ import { useGridUndoRedo, UNDO_HISTORY_LIMIT, type GridEditCommitChannel } from './useGridUndoRedo';
10
+ import { useGridFillHandle } from './useGridFillHandle';
11
+
12
+ /** The `DataGrid` props the range editing hooks read. */
13
+ export type GridRangeEditingProps<R extends GridRowModel> = Pick<DataGridProps<R>,
14
+ 'disableClipboardPaste' | 'disableRangeClear' | 'onClipboardPaste' | 'onBeforeClipboardPaste' |
15
+ 'undoRedo' | 'onHistoryChange' | 'disableFillHandle' | 'onFill'>;
16
+
17
+ export interface UseGridRangeEditingParams<R extends GridRowModel> {
18
+ props: GridRangeEditingProps<R>;
19
+ apiRef: MutableRefObject<GridApi>;
20
+ containerRef: RefObject<HTMLDivElement | null>;
21
+ viewportRef: RefObject<HTMLDivElement | null>;
22
+ selection: UseGridCellSelectionReturn;
23
+ model: GridCellSelectionModel;
24
+ getPendingModel: () => GridCellSelectionModel | null;
25
+ focusedCell: FocusedCell | null;
26
+ setFocusedCell: React.Dispatch<React.SetStateAction<FocusedCell | null>>;
27
+ allRenderableRows: R[];
28
+ getRowId: (row: R) => GridRowId;
29
+ navigationColumns: GridColDef<R>[];
30
+ columnIndexMap: Map<string, number>;
31
+ isCellEditable?: (params: GridCellParams<R>) => boolean;
32
+ rowMetaMap: Map<GridRowId, GridRowMeta>;
33
+ getSpanOrigin?: (rowId: GridRowId, field: string) => { rowId: GridRowId; field: string } | null;
34
+ isEditing: boolean;
35
+ batchEdit: UseGridBatchEditReturn<R>;
36
+ channel: GridEditCommitChannel;
37
+ layout: LayoutResult<R>;
38
+ rowHeight: number;
39
+ pinnedTopRowCount: number;
40
+ }
41
+
42
+ /**
43
+ * Steps 36a–36d of `DataGrid` (docs/architecture/datagrid-orchestration.md), in their call order: the cell
44
+ * selection API (anchor and focus kept together), clipboard paste and range clear, undo/redo, and the fill
45
+ * handle. Returns the fill handle (its position goes to the row renderers).
46
+ */
47
+ export function useGridRangeEditing<R extends GridRowModel>(params: UseGridRangeEditingParams<R>) {
48
+ const {
49
+ props, apiRef, containerRef, viewportRef, selection, model, getPendingModel, focusedCell, setFocusedCell,
50
+ allRenderableRows, getRowId, navigationColumns, columnIndexMap, isCellEditable, rowMetaMap, getSpanOrigin,
51
+ isEditing, batchEdit, channel, layout, rowHeight, pinnedTopRowCount,
52
+ } = params;
53
+ const {
54
+ disableClipboardPaste = false,
55
+ disableRangeClear = false,
56
+ onClipboardPaste,
57
+ onBeforeClipboardPaste,
58
+ undoRedo = false,
59
+ disableFillHandle = false,
60
+ onFill,
61
+ onHistoryChange,
62
+ } = props;
63
+
64
+ // Keeps the range anchor and the focused cell together; installs the cell selection API.
65
+ useGridCellSelectionApi({
66
+ apiRef,
67
+ selection,
68
+ model,
69
+ getPendingModel,
70
+ focusedCell,
71
+ setFocusedCell,
72
+ containerRef,
73
+ });
74
+
75
+ // Ctrl/Cmd+V and Delete on a range (cellSelection); apiRef.pasteText.
76
+ useGridClipboardPaste<R>({
77
+ apiRef, containerRef, viewportRef,
78
+ selection,
79
+ disableClipboardPaste, disableRangeClear,
80
+ focusedCell,
81
+ allRenderableRows,
82
+ getRowId,
83
+ navigationColumns,
84
+ isCellEditable,
85
+ rowMetaMap,
86
+ getSpanOrigin,
87
+ isEditing,
88
+ batchEdit,
89
+ onClipboardPaste,
90
+ onBeforeClipboardPaste,
91
+ });
92
+
93
+ // Undo / redo (undoRedo): history of committed edits, keys and apiRef methods.
94
+ useGridUndoRedo<R>({
95
+ apiRef,
96
+ enabled: Boolean(undoRedo),
97
+ limit: (typeof undoRedo === 'object' && undoRedo.limit) || UNDO_HISTORY_LIMIT,
98
+ onHistoryChange,
99
+ channel,
100
+ batchEdit,
101
+ isEditing,
102
+ containerRef, viewportRef,
103
+ selection,
104
+ setFocusedCell,
105
+ allRenderableRows,
106
+ getRowId,
107
+ navigationColumns,
108
+ layout,
109
+ rowHeight,
110
+ pinnedTopRowCount,
111
+ });
112
+
113
+ // Fill handle (cellSelection): drag the range's corner, Ctrl/Cmd+D and Ctrl/Cmd+R.
114
+ return useGridFillHandle<R>({
115
+ containerRef, viewportRef,
116
+ selection,
117
+ disableFillHandle,
118
+ isEditing,
119
+ allRenderableRows,
120
+ getRowId,
121
+ navigationColumns,
122
+ columnIndexMap,
123
+ isCellEditable,
124
+ rowMetaMap,
125
+ getSpanOrigin,
126
+ batchEdit,
127
+ onFill,
128
+ });
129
+ }
@@ -0,0 +1,66 @@
1
+ import type { GridColDef, GridRowId, GridRowModel } from '../../types';
2
+ import type { GridAriaRowLayout } from '../../utils/aria';
3
+ import type { GridSpanningResult } from '../features/useGridSpanning';
4
+ import { useGridSpanRowWindow, useGridSpanColumnWindow } from '../features/useGridSpanRenderWindow';
5
+ import { useGridAriaRows, type UseGridAriaRowsParams } from './useGridAriaRows';
6
+ import { useGridVisibleRows, type GridVisibleRow } from './useGridVisibleRows';
7
+ import type { GridVirtualizationResult } from './useGridVirtualization';
8
+ import type { LayoutResult } from './useLayout';
9
+
10
+ export interface UseGridRenderWindowParams<R extends GridRowModel> {
11
+ aria: UseGridAriaRowsParams;
12
+ spanning: GridSpanningResult;
13
+ virtualization: GridVirtualizationResult<R>;
14
+ layout: LayoutResult<R>;
15
+ pinnedTopRows: R[];
16
+ pinnedBottomRows: R[];
17
+ paginatedUnpinnedRows: R[];
18
+ sortedUnpinnedRows: R[];
19
+ pagination: boolean;
20
+ getRowId: (row: R) => GridRowId;
21
+ }
22
+
23
+ export interface UseGridRenderWindowResult<R extends GridRowModel> {
24
+ ariaRows: GridAriaRowLayout;
25
+ spanRowWindow: ReturnType<typeof useGridSpanRowWindow>;
26
+ visibleRows: GridVisibleRow<R>[];
27
+ renderColumns: GridColDef<R>[];
28
+ }
29
+
30
+ /**
31
+ * Steps 38–41 of `DataGrid` (docs/architecture/datagrid-orchestration.md), in their call order: the
32
+ * `aria-rowcount` / `aria-rowindex` bases, the render window widened to whole row spans, the rows to
33
+ * render (pinned + virtual centre) and the columns to render, widened to whole column spans.
34
+ */
35
+ export function useGridRenderWindow<R extends GridRowModel>(params: UseGridRenderWindowParams<R>): UseGridRenderWindowResult<R> {
36
+ const {
37
+ aria, spanning, virtualization, layout, pinnedTopRows, pinnedBottomRows, paginatedUnpinnedRows, sortedUnpinnedRows,
38
+ pagination, getRowId,
39
+ } = params;
40
+
41
+ const ariaRows = useGridAriaRows(aria);
42
+
43
+ const spanRowWindow = useGridSpanRowWindow({
44
+ spanning,
45
+ renderContext: virtualization.renderContext,
46
+ offsetTop: virtualization.offsetTop,
47
+ cumulativeHeights: layout.cumulativeHeights,
48
+ });
49
+
50
+ const visibleRows = useGridVisibleRows<R>({
51
+ renderContext: spanRowWindow.renderContext,
52
+ pinnedTopRows, pinnedBottomRows, paginatedUnpinnedRows, sortedUnpinnedRows, pagination,
53
+ getRowId,
54
+ });
55
+
56
+ const renderColumns = useGridSpanColumnWindow<R>({
57
+ spanning,
58
+ firstColumnIndex: virtualization.renderContext.firstColumnIndex,
59
+ lastColumnIndex: virtualization.renderContext.lastColumnIndex,
60
+ virtualColumns: virtualization.virtualColumns,
61
+ layout,
62
+ rows: visibleRows,
63
+ });
64
+
65
+ return { ariaRows, spanRowWindow, visibleRows, renderColumns };
66
+ }
@@ -0,0 +1,42 @@
1
+ import type { MutableRefObject, RefObject } from 'react';
2
+ import type { GridRowModel } from '../../types';
3
+ import { useGridViewport, type UseGridViewportParams } from './useGridViewport';
4
+ import { useGridMaxContentHeight } from './useGridMaxContentHeight';
5
+ import { useGridVirtualization, type UseGridVirtualizationParams } from './useGridVirtualization';
6
+ import type { LayoutResult } from './useLayout';
7
+
8
+ export interface UseGridScrollViewportParams<R extends GridRowModel> {
9
+ viewport: Omit<UseGridViewportParams, 'viewportRef' | 'rowCount'>;
10
+ viewportRef: MutableRefObject<HTMLDivElement | null>;
11
+ containerRef: RefObject<HTMLDivElement | null>;
12
+ layout: LayoutResult<R>;
13
+ viewportWidth: number;
14
+ viewportHeight: number;
15
+ /** The virtualization inputs that do not come from the viewport. */
16
+ virtualization: Pick<UseGridVirtualizationParams<R>,
17
+ 'autoHeight' | 'rowReordering' | 'hasDetailPanel' | 'checkboxSelection' | 'pinCheckboxColumn' | 'pinExpandColumn'>;
18
+ }
19
+
20
+ /**
21
+ * Steps 32–33 of `DataGrid` (docs/architecture/datagrid-orchestration.md), in their call order: scroll sync
22
+ * and viewport measurement, the tallest element this browser lays out (32a), and the render window.
23
+ */
24
+ export function useGridScrollViewport<R extends GridRowModel>(params: UseGridScrollViewportParams<R>) {
25
+ const { viewport, viewportRef, containerRef, layout, viewportWidth, viewportHeight, virtualization: options } = params;
26
+
27
+ const { scrollTop, scrollLeft, overscanRows, handleScroll, setViewportElement } = useGridViewport({
28
+ ...viewport, rowCount: layout.unpinnedRowsLength, viewportRef,
29
+ });
30
+
31
+ const maxContentHeight = useGridMaxContentHeight(containerRef);
32
+ const virtualization = useGridVirtualization({
33
+ layout, scrollTop, scrollLeft,
34
+ viewportWidth,
35
+ viewportHeight,
36
+ ...options,
37
+ overscanRows,
38
+ maxContentHeight: maxContentHeight ?? Infinity,
39
+ });
40
+
41
+ return { handleScroll, setViewportElement, maxContentHeight, virtualization };
42
+ }
@@ -0,0 +1,61 @@
1
+ import type { GridRowModel } from '../../types';
2
+ import { useGridRowInteractions, type UseGridRowInteractionsParams, type UseGridRowInteractionsResult } from './useGridRowInteractions';
3
+ import { useGridApiMethods, type UseGridApiMethodsParams } from './useGridApiMethods';
4
+ import type { UseGridControlledStateReturn } from './useGridControlledState';
5
+
6
+ /** The state API inputs that do not come from `useGridControlledState`. */
7
+ export type GridStateApiParams = Pick<UseGridApiMethodsParams,
8
+ 'apiRef' | 'multiSort' | 'selectedRowIds' | 'disableMultipleRowSelection' | 'isSyntheticRowId' | 'getVisibleRows' |
9
+ 'getAllFilteredRows' | 'visibleColumns'>;
10
+
11
+ export interface UseGridSelectionAndStateApiParams<R extends GridRowModel> {
12
+ controlledState: UseGridControlledStateReturn;
13
+ interactions: Omit<UseGridRowInteractionsParams<R>, 'selectedRowIds' | 'onSelectionModelChange' | 'disableMultipleRowSelection'>;
14
+ api: GridStateApiParams;
15
+ }
16
+
17
+ /**
18
+ * Steps 23–24 of `DataGrid` (docs/architecture/datagrid-orchestration.md), in their call order: row
19
+ * selection and the row click / checkbox handlers, then the state API methods (sort, filter, pagination,
20
+ * selection, row grouping, aggregation, visibility and pivot setters, `getGridAiState`) installed on `apiRef`.
21
+ */
22
+ export function useGridSelectionAndStateApi<R extends GridRowModel>(
23
+ params: UseGridSelectionAndStateApiParams<R>
24
+ ): UseGridRowInteractionsResult<R> {
25
+ const { controlledState, interactions, api } = params;
26
+ const {
27
+ sortModel, handleSortModelChange, filterModel, handleFilterModelChange, effectivePaginationModel,
28
+ handlePaginationModelChange, handleRowSelectionModelChange, rowGroupingModel, handleRowGroupingModelChange,
29
+ aggregationModel, handleAggregationModelChange, columnVisibilityModel, handleColumnVisibilityModelChange,
30
+ currentPivotModel, handlePivotModelChange,
31
+ } = controlledState;
32
+
33
+ const result = useGridRowInteractions<R>({
34
+ ...interactions,
35
+ selectedRowIds: api.selectedRowIds,
36
+ onSelectionModelChange: handleRowSelectionModelChange,
37
+ disableMultipleRowSelection: api.disableMultipleRowSelection,
38
+ });
39
+
40
+ useGridApiMethods({
41
+ ...api,
42
+ onSortModelChange: handleSortModelChange,
43
+ sortModel,
44
+ filterModel,
45
+ onFilterModelChange: handleFilterModelChange,
46
+ paginationModel: effectivePaginationModel,
47
+ onPaginationModelChange: handlePaginationModelChange,
48
+ getPendingRowSelectionModel: controlledState.getPendingRowSelectionModel,
49
+ onRowSelectionModelChange: handleRowSelectionModelChange,
50
+ rowGroupingModel,
51
+ onRowGroupingModelChange: handleRowGroupingModelChange,
52
+ aggregationModel,
53
+ onAggregationModelChange: handleAggregationModelChange,
54
+ columnVisibilityModel,
55
+ onColumnVisibilityModelChange: handleColumnVisibilityModelChange,
56
+ pivotModel: currentPivotModel,
57
+ onPivotModelChange: handlePivotModelChange,
58
+ });
59
+
60
+ return result;
61
+ }
@@ -0,0 +1,49 @@
1
+ import type { MutableRefObject, RefObject } from 'react';
2
+ import type { GridApi, GridLocaleText, GridRowModel } from '../../types';
3
+ import { useGridColumnsPanel } from './useGridColumnsPanel';
4
+ import { useGridStylesheetWarning } from './useGridDevWarnings';
5
+ import { useGridAiAssistant, type UseGridAiAssistantParams } from '../features/useGridAiAssistant';
6
+ import { useGridToolbarProps, type UseGridToolbarPropsParams } from './useGridToolbarProps';
7
+
8
+ /** What `useGridToolbarProps` needs besides the columns panel and the AI assistant built here. */
9
+ export type GridToolbarStackToolbarParams<R extends GridRowModel> = Omit<UseGridToolbarPropsParams<R>,
10
+ 'forceColumnsOpen' | 'onColumnsPanelClose' | 'aiAssistantEnabled' | 'aiAssistantOpen' | 'onAiAssistantToggle' |
11
+ 'aiAssistantLabel' | 'forceFiltersOpen' | 'onFiltersPanelClose' | 'apiRef'>;
12
+
13
+ export interface UseGridToolbarStackParams<R extends GridRowModel> {
14
+ apiRef: MutableRefObject<GridApi>;
15
+ containerRef: RefObject<HTMLDivElement | null>;
16
+ aiAssistant: Omit<UseGridAiAssistantParams, 'apiRef'>;
17
+ toolbar: GridToolbarStackToolbarParams<R>;
18
+ localeText: GridLocaleText | undefined;
19
+ }
20
+
21
+ /**
22
+ * Steps 44–46 of `DataGrid` (docs/architecture/datagrid-orchestration.md), in their call order: the columns
23
+ * panel (toolbar or standalone), the missing-stylesheet warning, the `aiAssistant` panel, and the props for
24
+ * `slots.toolbar` (which gets its Ask AI button from the assistant).
25
+ */
26
+ export function useGridToolbarStack<R extends GridRowModel>(params: UseGridToolbarStackParams<R>) {
27
+ const { apiRef, containerRef, aiAssistant, toolbar, localeText } = params;
28
+
29
+ const columnsPanel = useGridColumnsPanel();
30
+ useGridStylesheetWarning(containerRef);
31
+
32
+ // The aiAssistant prompt panel (v3.5): applies validated replies through apiRef; apiRef.openAiAssistant.
33
+ const aiAssistantPanel = useGridAiAssistant({ apiRef, ...aiAssistant });
34
+
35
+ const toolbarProps = useGridToolbarProps<R>({
36
+ ...toolbar,
37
+ apiRef,
38
+ forceColumnsOpen: columnsPanel.toolbarPanelRequested,
39
+ onColumnsPanelClose: columnsPanel.closeToolbarPanel,
40
+ aiAssistantEnabled: aiAssistantPanel.enabled,
41
+ aiAssistantOpen: aiAssistantPanel.open,
42
+ onAiAssistantToggle: aiAssistantPanel.togglePanel,
43
+ aiAssistantLabel: localeText?.aiAssistantButton,
44
+ forceFiltersOpen: columnsPanel.toolbarFiltersRequested,
45
+ onFiltersPanelClose: columnsPanel.closeToolbarFiltersPanel,
46
+ });
47
+
48
+ return { columnsPanel, aiAssistantPanel, toolbarProps };
49
+ }
@@ -0,0 +1,46 @@
1
+ import type { MutableRefObject, RefObject } from 'react';
2
+ import type { GridApi, GridColDef, GridRowId, GridRowModel } from '../../types';
3
+ import { useGridClipboardApi } from './useGridClipboardApi';
4
+ import { useGridScrollToIndexesApi } from './useGridScrollToIndexesApi';
5
+ import { useGridColumnAutosize } from './useGridColumnAutosize';
6
+ import type { LayoutResult } from './useLayout';
7
+
8
+ export interface UseGridViewApisParams<R extends GridRowModel> {
9
+ apiRef: MutableRefObject<GridApi>;
10
+ containerRef: RefObject<HTMLDivElement | null>;
11
+ viewportRef: RefObject<HTMLDivElement | null>;
12
+ /** Rendered data columns with their layout-resolved widths, in render order (what Ctrl/Cmd+C copies). */
13
+ copyColumns: GridColDef[];
14
+ getRowId: (row: GridRowModel) => GridRowId;
15
+ disableClipboardCopy: boolean;
16
+ /** The cell range's copy text while `cellSelection` is on. */
17
+ getCellRangeCopyText: (() => string | null) | undefined;
18
+ layout: LayoutResult<R>;
19
+ rowHeight: number;
20
+ /** Every column in display order (what auto-size measures). */
21
+ orderedColumns: GridColDef<R>[];
22
+ onColumnResize: (field: string, width: number) => void;
23
+ }
24
+
25
+ /**
26
+ * Steps 30–31a of `DataGrid` (docs/architecture/datagrid-orchestration.md), in their call order: the
27
+ * `apiRef` installers that need the laid-out view — copy, `scrollToIndexes` and column auto-size.
28
+ * Returns the resize handle's auto-size handler.
29
+ */
30
+ export function useGridViewApis<R extends GridRowModel>(params: UseGridViewApisParams<R>): (field: string) => void {
31
+ const {
32
+ apiRef, containerRef, viewportRef, copyColumns, getRowId, disableClipboardCopy, getCellRangeCopyText, layout, rowHeight,
33
+ orderedColumns, onColumnResize,
34
+ } = params;
35
+
36
+ useGridClipboardApi({
37
+ apiRef,
38
+ columns: copyColumns,
39
+ getRowId,
40
+ containerRef,
41
+ disableKeyboardShortcut: disableClipboardCopy,
42
+ getCellRangeCopyText,
43
+ });
44
+ useGridScrollToIndexesApi<R>({ apiRef, viewportRef, layout, rowHeight });
45
+ return useGridColumnAutosize<R>({ apiRef, containerRef, columns: orderedColumns, onColumnResize });
46
+ }