@mui/x-data-grid 5.14.0 → 5.15.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 (290) hide show
  1. package/CHANGELOG.md +147 -5
  2. package/DataGrid/DataGrid.js +7 -1
  3. package/DataGrid/useDataGridProps.js +1 -0
  4. package/colDef/gridStringColDef.js +1 -1
  5. package/components/GridRow.js +5 -1
  6. package/components/base/GridOverlays.js +2 -2
  7. package/components/cell/GridEditInputCell.d.ts +2 -5
  8. package/components/cell/GridEditInputCell.js +13 -14
  9. package/components/cell/GridEditSingleSelectCell.d.ts +4 -0
  10. package/components/cell/GridEditSingleSelectCell.js +11 -4
  11. package/components/columnSelection/GridCellCheckboxRenderer.js +5 -0
  12. package/components/containers/GridRoot.js +4 -2
  13. package/components/toolbar/GridToolbarDensitySelector.js +13 -4
  14. package/components/toolbar/GridToolbarExportContainer.js +13 -2
  15. package/constants/envConstants.d.ts +1 -1
  16. package/constants/envConstants.js +2 -11
  17. package/constants/gridClasses.d.ts +16 -0
  18. package/constants/gridClasses.js +1 -1
  19. package/constants/localeTextConstants.js +1 -1
  20. package/hooks/features/dimensions/useGridDimensions.js +6 -1
  21. package/hooks/features/editRows/useGridCellEditing.new.d.ts +1 -1
  22. package/hooks/features/editRows/useGridCellEditing.new.js +26 -16
  23. package/hooks/features/editRows/useGridCellEditing.old.js +2 -2
  24. package/hooks/features/editRows/useGridEditing.new.d.ts +1 -1
  25. package/hooks/features/editRows/useGridEditing.new.js +4 -0
  26. package/hooks/features/editRows/useGridEditing.old.js +1 -1
  27. package/hooks/features/editRows/useGridRowEditing.new.d.ts +1 -1
  28. package/hooks/features/editRows/useGridRowEditing.new.js +16 -10
  29. package/hooks/features/export/utils.js +8 -1
  30. package/hooks/features/filter/gridFilterState.d.ts +12 -1
  31. package/hooks/features/filter/gridFilterUtils.d.ts +8 -5
  32. package/hooks/features/filter/gridFilterUtils.js +74 -43
  33. package/hooks/features/filter/useGridFilter.js +16 -3
  34. package/hooks/features/focus/useGridFocus.js +11 -6
  35. package/hooks/features/keyboardNavigation/useGridKeyboardNavigation.d.ts +1 -1
  36. package/hooks/features/keyboardNavigation/useGridKeyboardNavigation.js +42 -34
  37. package/hooks/features/pagination/useGridPageSize.js +3 -1
  38. package/hooks/features/rows/gridRowsSelector.d.ts +14 -0
  39. package/hooks/features/rows/gridRowsSelector.js +20 -1
  40. package/hooks/features/rows/gridRowsState.d.ts +8 -1
  41. package/hooks/features/rows/gridRowsUtils.d.ts +4 -0
  42. package/hooks/features/rows/gridRowsUtils.js +21 -3
  43. package/hooks/features/rows/index.d.ts +1 -1
  44. package/hooks/features/rows/index.js +1 -1
  45. package/hooks/features/rows/useGridRows.js +5 -2
  46. package/hooks/features/rows/useGridRowsMeta.js +19 -4
  47. package/hooks/features/rows/useGridRowsPreProcessors.js +2 -1
  48. package/hooks/features/scroll/useGridScroll.js +7 -2
  49. package/hooks/features/selection/useGridSelection.js +7 -3
  50. package/hooks/features/sorting/useGridSorting.js +8 -0
  51. package/hooks/features/statePersistence/gridStatePersistenceInterface.d.ts +3 -0
  52. package/hooks/features/virtualization/useGridVirtualScroller.d.ts +3 -1
  53. package/hooks/features/virtualization/useGridVirtualScroller.js +31 -16
  54. package/index.js +1 -1
  55. package/internals/index.d.ts +5 -1
  56. package/internals/index.js +4 -0
  57. package/legacy/DataGrid/DataGrid.js +7 -1
  58. package/legacy/DataGrid/useDataGridProps.js +1 -0
  59. package/legacy/colDef/gridStringColDef.js +1 -1
  60. package/legacy/components/GridRow.js +5 -1
  61. package/legacy/components/base/GridOverlays.js +2 -2
  62. package/legacy/components/cell/GridEditInputCell.js +13 -14
  63. package/legacy/components/cell/GridEditSingleSelectCell.js +11 -3
  64. package/legacy/components/columnSelection/GridCellCheckboxRenderer.js +5 -0
  65. package/legacy/components/containers/GridRoot.js +4 -2
  66. package/legacy/components/toolbar/GridToolbarDensitySelector.js +14 -5
  67. package/legacy/components/toolbar/GridToolbarExportContainer.js +15 -2
  68. package/legacy/constants/envConstants.js +2 -11
  69. package/legacy/constants/gridClasses.js +1 -1
  70. package/legacy/constants/localeTextConstants.js +1 -1
  71. package/legacy/hooks/features/dimensions/useGridDimensions.js +6 -1
  72. package/legacy/hooks/features/editRows/useGridCellEditing.new.js +27 -17
  73. package/legacy/hooks/features/editRows/useGridCellEditing.old.js +2 -2
  74. package/legacy/hooks/features/editRows/useGridEditing.new.js +4 -0
  75. package/legacy/hooks/features/editRows/useGridEditing.old.js +1 -1
  76. package/legacy/hooks/features/editRows/useGridRowEditing.new.js +16 -10
  77. package/legacy/hooks/features/export/utils.js +13 -1
  78. package/legacy/hooks/features/filter/gridFilterUtils.js +84 -55
  79. package/legacy/hooks/features/filter/useGridFilter.js +16 -3
  80. package/legacy/hooks/features/focus/useGridFocus.js +11 -6
  81. package/legacy/hooks/features/keyboardNavigation/useGridKeyboardNavigation.js +47 -34
  82. package/legacy/hooks/features/pagination/useGridPageSize.js +3 -1
  83. package/legacy/hooks/features/rows/gridRowsSelector.js +23 -0
  84. package/legacy/hooks/features/rows/gridRowsUtils.js +21 -3
  85. package/legacy/hooks/features/rows/index.js +1 -1
  86. package/legacy/hooks/features/rows/useGridRows.js +5 -2
  87. package/legacy/hooks/features/rows/useGridRowsMeta.js +19 -4
  88. package/legacy/hooks/features/rows/useGridRowsPreProcessors.js +2 -1
  89. package/legacy/hooks/features/scroll/useGridScroll.js +7 -2
  90. package/legacy/hooks/features/selection/useGridSelection.js +7 -3
  91. package/legacy/hooks/features/sorting/useGridSorting.js +8 -0
  92. package/legacy/hooks/features/virtualization/useGridVirtualScroller.js +32 -16
  93. package/legacy/index.js +1 -1
  94. package/legacy/internals/index.js +4 -0
  95. package/legacy/locales/arSD.js +1 -1
  96. package/legacy/locales/bgBG.js +1 -1
  97. package/legacy/locales/csCZ.js +1 -1
  98. package/legacy/locales/daDK.js +1 -1
  99. package/legacy/locales/deDE.js +9 -9
  100. package/legacy/locales/elGR.js +1 -1
  101. package/legacy/locales/esES.js +1 -1
  102. package/legacy/locales/faIR.js +1 -1
  103. package/legacy/locales/fiFI.js +1 -1
  104. package/legacy/locales/frFR.js +1 -1
  105. package/legacy/locales/heIL.js +1 -1
  106. package/legacy/locales/huHU.js +1 -1
  107. package/legacy/locales/itIT.js +15 -15
  108. package/legacy/locales/jaJP.js +3 -3
  109. package/legacy/locales/koKR.js +34 -30
  110. package/legacy/locales/nbNO.js +1 -1
  111. package/legacy/locales/nlNL.js +1 -1
  112. package/legacy/locales/plPL.js +1 -1
  113. package/legacy/locales/ptBR.js +1 -1
  114. package/legacy/locales/roRO.js +1 -1
  115. package/legacy/locales/ruRU.js +1 -1
  116. package/legacy/locales/skSK.js +1 -1
  117. package/legacy/locales/svSE.js +1 -1
  118. package/legacy/locales/trTR.js +1 -1
  119. package/legacy/locales/ukUA.js +1 -1
  120. package/legacy/locales/viVN.js +1 -1
  121. package/legacy/locales/zhCN.js +37 -33
  122. package/legacy/locales/zhTW.js +1 -1
  123. package/legacy/utils/keyboardUtils.js +8 -5
  124. package/locales/arSD.js +1 -1
  125. package/locales/bgBG.js +1 -1
  126. package/locales/csCZ.js +1 -1
  127. package/locales/daDK.js +1 -1
  128. package/locales/deDE.js +9 -9
  129. package/locales/elGR.js +1 -1
  130. package/locales/esES.js +1 -1
  131. package/locales/faIR.js +1 -1
  132. package/locales/fiFI.js +1 -1
  133. package/locales/frFR.js +1 -1
  134. package/locales/heIL.js +1 -1
  135. package/locales/huHU.js +1 -1
  136. package/locales/itIT.js +15 -15
  137. package/locales/jaJP.js +3 -3
  138. package/locales/koKR.js +30 -30
  139. package/locales/nbNO.js +1 -1
  140. package/locales/nlNL.js +1 -1
  141. package/locales/plPL.js +1 -1
  142. package/locales/ptBR.js +1 -1
  143. package/locales/roRO.js +1 -1
  144. package/locales/ruRU.js +1 -1
  145. package/locales/skSK.js +1 -1
  146. package/locales/svSE.js +1 -1
  147. package/locales/trTR.js +1 -1
  148. package/locales/ukUA.js +1 -1
  149. package/locales/viVN.js +1 -1
  150. package/locales/zhCN.js +33 -33
  151. package/locales/zhTW.js +1 -1
  152. package/models/gridRows.d.ts +5 -0
  153. package/models/props/DataGridProps.d.ts +8 -3
  154. package/modern/DataGrid/DataGrid.js +7 -1
  155. package/modern/DataGrid/useDataGridProps.js +1 -0
  156. package/modern/colDef/gridStringColDef.js +1 -1
  157. package/modern/components/GridRow.js +5 -1
  158. package/modern/components/base/GridOverlays.js +2 -2
  159. package/modern/components/cell/GridEditInputCell.js +13 -14
  160. package/modern/components/cell/GridEditSingleSelectCell.js +11 -4
  161. package/modern/components/columnSelection/GridCellCheckboxRenderer.js +5 -0
  162. package/modern/components/containers/GridRoot.js +4 -2
  163. package/modern/components/toolbar/GridToolbarDensitySelector.js +11 -4
  164. package/modern/components/toolbar/GridToolbarExportContainer.js +11 -2
  165. package/modern/constants/envConstants.js +2 -11
  166. package/modern/constants/gridClasses.js +1 -1
  167. package/modern/constants/localeTextConstants.js +1 -1
  168. package/modern/hooks/features/dimensions/useGridDimensions.js +6 -1
  169. package/modern/hooks/features/editRows/useGridCellEditing.new.js +24 -16
  170. package/modern/hooks/features/editRows/useGridCellEditing.old.js +2 -2
  171. package/modern/hooks/features/editRows/useGridEditing.new.js +4 -0
  172. package/modern/hooks/features/editRows/useGridEditing.old.js +1 -1
  173. package/modern/hooks/features/editRows/useGridRowEditing.new.js +16 -10
  174. package/modern/hooks/features/export/utils.js +6 -1
  175. package/modern/hooks/features/filter/gridFilterUtils.js +73 -42
  176. package/modern/hooks/features/filter/useGridFilter.js +16 -3
  177. package/modern/hooks/features/focus/useGridFocus.js +11 -6
  178. package/modern/hooks/features/keyboardNavigation/useGridKeyboardNavigation.js +42 -30
  179. package/modern/hooks/features/pagination/useGridPageSize.js +3 -1
  180. package/modern/hooks/features/rows/gridRowsSelector.js +18 -1
  181. package/modern/hooks/features/rows/gridRowsUtils.js +19 -3
  182. package/modern/hooks/features/rows/index.js +1 -1
  183. package/modern/hooks/features/rows/useGridRows.js +5 -2
  184. package/modern/hooks/features/rows/useGridRowsMeta.js +17 -4
  185. package/modern/hooks/features/rows/useGridRowsPreProcessors.js +2 -1
  186. package/modern/hooks/features/scroll/useGridScroll.js +5 -2
  187. package/modern/hooks/features/selection/useGridSelection.js +7 -1
  188. package/modern/hooks/features/sorting/useGridSorting.js +8 -0
  189. package/modern/hooks/features/virtualization/useGridVirtualScroller.js +30 -15
  190. package/modern/index.js +1 -1
  191. package/modern/internals/index.js +4 -0
  192. package/modern/locales/arSD.js +1 -1
  193. package/modern/locales/bgBG.js +1 -1
  194. package/modern/locales/csCZ.js +1 -1
  195. package/modern/locales/daDK.js +1 -1
  196. package/modern/locales/deDE.js +9 -9
  197. package/modern/locales/elGR.js +1 -1
  198. package/modern/locales/esES.js +1 -1
  199. package/modern/locales/faIR.js +1 -1
  200. package/modern/locales/fiFI.js +1 -1
  201. package/modern/locales/frFR.js +1 -1
  202. package/modern/locales/heIL.js +1 -1
  203. package/modern/locales/huHU.js +1 -1
  204. package/modern/locales/itIT.js +15 -15
  205. package/modern/locales/jaJP.js +3 -3
  206. package/modern/locales/koKR.js +30 -30
  207. package/modern/locales/nbNO.js +1 -1
  208. package/modern/locales/nlNL.js +1 -1
  209. package/modern/locales/plPL.js +1 -1
  210. package/modern/locales/ptBR.js +1 -1
  211. package/modern/locales/roRO.js +1 -1
  212. package/modern/locales/ruRU.js +1 -1
  213. package/modern/locales/skSK.js +1 -1
  214. package/modern/locales/svSE.js +1 -1
  215. package/modern/locales/trTR.js +1 -1
  216. package/modern/locales/ukUA.js +1 -1
  217. package/modern/locales/viVN.js +1 -1
  218. package/modern/locales/zhCN.js +33 -33
  219. package/modern/locales/zhTW.js +1 -1
  220. package/modern/utils/keyboardUtils.js +7 -2
  221. package/node/DataGrid/DataGrid.js +7 -1
  222. package/node/DataGrid/useDataGridProps.js +1 -0
  223. package/node/colDef/gridStringColDef.js +1 -1
  224. package/node/components/GridRow.js +5 -1
  225. package/node/components/base/GridOverlays.js +2 -2
  226. package/node/components/cell/GridEditInputCell.js +15 -16
  227. package/node/components/cell/GridEditSingleSelectCell.js +10 -4
  228. package/node/components/columnSelection/GridCellCheckboxRenderer.js +5 -0
  229. package/node/components/containers/GridRoot.js +3 -1
  230. package/node/components/toolbar/GridToolbarDensitySelector.js +13 -4
  231. package/node/components/toolbar/GridToolbarExportContainer.js +13 -2
  232. package/node/constants/envConstants.js +2 -13
  233. package/node/constants/gridClasses.js +1 -1
  234. package/node/constants/localeTextConstants.js +1 -1
  235. package/node/hooks/features/dimensions/useGridDimensions.js +7 -1
  236. package/node/hooks/features/editRows/useGridCellEditing.new.js +26 -16
  237. package/node/hooks/features/editRows/useGridCellEditing.old.js +2 -2
  238. package/node/hooks/features/editRows/useGridEditing.new.js +4 -0
  239. package/node/hooks/features/editRows/useGridEditing.old.js +1 -1
  240. package/node/hooks/features/editRows/useGridRowEditing.new.js +16 -10
  241. package/node/hooks/features/export/utils.js +7 -0
  242. package/node/hooks/features/filter/gridFilterUtils.js +81 -47
  243. package/node/hooks/features/filter/useGridFilter.js +15 -2
  244. package/node/hooks/features/focus/useGridFocus.js +11 -6
  245. package/node/hooks/features/keyboardNavigation/useGridKeyboardNavigation.js +43 -34
  246. package/node/hooks/features/pagination/useGridPageSize.js +4 -1
  247. package/node/hooks/features/rows/gridRowsSelector.js +24 -2
  248. package/node/hooks/features/rows/gridRowsUtils.js +23 -2
  249. package/node/hooks/features/rows/index.js +70 -12
  250. package/node/hooks/features/rows/useGridRows.js +5 -2
  251. package/node/hooks/features/rows/useGridRowsMeta.js +20 -4
  252. package/node/hooks/features/rows/useGridRowsPreProcessors.js +2 -1
  253. package/node/hooks/features/scroll/useGridScroll.js +7 -1
  254. package/node/hooks/features/selection/useGridSelection.js +7 -3
  255. package/node/hooks/features/sorting/useGridSorting.js +8 -0
  256. package/node/hooks/features/virtualization/useGridVirtualScroller.js +31 -16
  257. package/node/index.js +1 -1
  258. package/node/internals/index.js +36 -0
  259. package/node/locales/arSD.js +1 -1
  260. package/node/locales/bgBG.js +1 -1
  261. package/node/locales/csCZ.js +1 -1
  262. package/node/locales/daDK.js +1 -1
  263. package/node/locales/deDE.js +9 -9
  264. package/node/locales/elGR.js +1 -1
  265. package/node/locales/esES.js +1 -1
  266. package/node/locales/faIR.js +1 -1
  267. package/node/locales/fiFI.js +1 -1
  268. package/node/locales/frFR.js +1 -1
  269. package/node/locales/heIL.js +1 -1
  270. package/node/locales/huHU.js +1 -1
  271. package/node/locales/itIT.js +15 -15
  272. package/node/locales/jaJP.js +3 -3
  273. package/node/locales/koKR.js +30 -30
  274. package/node/locales/nbNO.js +1 -1
  275. package/node/locales/nlNL.js +1 -1
  276. package/node/locales/plPL.js +1 -1
  277. package/node/locales/ptBR.js +1 -1
  278. package/node/locales/roRO.js +1 -1
  279. package/node/locales/ruRU.js +1 -1
  280. package/node/locales/skSK.js +1 -1
  281. package/node/locales/svSE.js +1 -1
  282. package/node/locales/trTR.js +1 -1
  283. package/node/locales/ukUA.js +1 -1
  284. package/node/locales/viVN.js +1 -1
  285. package/node/locales/zhCN.js +33 -33
  286. package/node/locales/zhTW.js +1 -1
  287. package/node/utils/keyboardUtils.js +10 -4
  288. package/package.json +1 -1
  289. package/utils/keyboardUtils.d.ts +2 -2
  290. package/utils/keyboardUtils.js +7 -2
@@ -10,4 +10,4 @@ import { DataGridProcessedProps } from '../../../models/props/DataGridProps';
10
10
  * @requires useGridScroll (method) - can be after
11
11
  * @requires useGridColumnSpanning (method) - can be after
12
12
  */
13
- export declare const useGridKeyboardNavigation: (apiRef: React.MutableRefObject<GridApiCommunity>, props: Pick<DataGridProcessedProps, 'pagination' | 'paginationMode'>) => void;
13
+ export declare const useGridKeyboardNavigation: (apiRef: React.MutableRefObject<GridApiCommunity>, props: Pick<DataGridProcessedProps, 'pagination' | 'paginationMode' | 'getRowId'>) => void;
@@ -9,6 +9,12 @@ import { gridClasses } from '../../../constants/gridClasses';
9
9
  import { GridCellModes } from '../../../models/gridEditRowModel';
10
10
  import { isNavigationKey } from '../../../utils/keyboardUtils';
11
11
  import { GRID_DETAIL_PANEL_TOGGLE_FIELD } from '../../../constants/gridDetailPanelToggleField';
12
+ import { gridPinnedRowsSelector } from '../rows/gridRowsSelector';
13
+
14
+ function enrichPageRowsWithPinnedRows(apiRef, rows) {
15
+ const pinnedRows = gridPinnedRowsSelector(apiRef) || {};
16
+ return [...(pinnedRows.top || []), ...rows, ...(pinnedRows.bottom || [])];
17
+ }
12
18
  /**
13
19
  * @requires useGridSorting (method) - can be after
14
20
  * @requires useGridFilter (state) - can be after
@@ -19,20 +25,19 @@ import { GRID_DETAIL_PANEL_TOGGLE_FIELD } from '../../../constants/gridDetailPan
19
25
  * @requires useGridColumnSpanning (method) - can be after
20
26
  */
21
27
 
28
+
22
29
  export const useGridKeyboardNavigation = (apiRef, props) => {
23
30
  const logger = useGridLogger(apiRef, 'useGridKeyboardNavigation');
24
- const currentPage = useGridVisibleRows(apiRef, props);
31
+ const initialCurrentPageRows = useGridVisibleRows(apiRef, props).rows;
32
+ const currentPageRows = React.useMemo(() => enrichPageRowsWithPinnedRows(apiRef, initialCurrentPageRows), [apiRef, initialCurrentPageRows]);
25
33
  /**
26
34
  * @param {number} colIndex Index of the column to focus
27
35
  * @param {number} rowIndex index of the row to focus
28
36
  * @param {string} closestColumnToUse Which closest column cell to use when the cell is spanned by `colSpan`.
29
37
  */
30
38
 
31
- const goToCell = React.useCallback((colIndex, rowIndex, closestColumnToUse = 'left') => {
32
- var _visibleSortedRows$ro;
33
-
39
+ const goToCell = React.useCallback((colIndex, rowId, closestColumnToUse = 'left') => {
34
40
  const visibleSortedRows = gridVisibleSortedRowEntriesSelector(apiRef);
35
- const rowId = (_visibleSortedRows$ro = visibleSortedRows[rowIndex]) == null ? void 0 : _visibleSortedRows$ro.id;
36
41
  const nextCellColSpanInfo = apiRef.current.unstable_getCellColSpanInfo(rowId, colIndex);
37
42
 
38
43
  if (nextCellColSpanInfo && nextCellColSpanInfo.spannedByColSpan) {
@@ -41,12 +46,15 @@ export const useGridKeyboardNavigation = (apiRef, props) => {
41
46
  } else if (closestColumnToUse === 'right') {
42
47
  colIndex = nextCellColSpanInfo.rightVisibleCellIndex;
43
48
  }
44
- }
49
+ } // `scrollToIndexes` requires a rowIndex relative to all visible rows.
50
+ // Those rows do not include pinned rows, but pinned rows do not need scroll anyway.
45
51
 
46
- logger.debug(`Navigating to cell row ${rowIndex}, col ${colIndex}`);
52
+
53
+ const rowIndexRelativeToAllRows = visibleSortedRows.findIndex(row => row.id === rowId);
54
+ logger.debug(`Navigating to cell row ${rowIndexRelativeToAllRows}, col ${colIndex}`);
47
55
  apiRef.current.scrollToIndexes({
48
56
  colIndex,
49
- rowIndex
57
+ rowIndex: rowIndexRelativeToAllRows
50
58
  });
51
59
  const field = apiRef.current.getVisibleColumns()[colIndex].field;
52
60
  apiRef.current.setCellFocus(rowId, field);
@@ -59,19 +67,21 @@ export const useGridKeyboardNavigation = (apiRef, props) => {
59
67
  const field = apiRef.current.getVisibleColumns()[colIndex].field;
60
68
  apiRef.current.setColumnHeaderFocus(field, event);
61
69
  }, [apiRef, logger]);
70
+ const getRowIdFromIndex = React.useCallback(rowIndex => {
71
+ return currentPageRows[rowIndex].id;
72
+ }, [currentPageRows]);
62
73
  const handleCellNavigationKeyDown = React.useCallback((params, event) => {
63
74
  const dimensions = apiRef.current.getRootDimensions();
64
75
 
65
- if (!currentPage.range || !dimensions) {
76
+ if (currentPageRows.length === 0 || !dimensions) {
66
77
  return;
67
78
  }
68
79
 
69
80
  const viewportPageSize = apiRef.current.unstable_getViewportPageSize();
70
- const visibleSortedRows = gridVisibleSortedRowEntriesSelector(apiRef);
71
81
  const colIndexBefore = params.field ? apiRef.current.getColumnIndex(params.field) : 0;
72
- const rowIndexBefore = visibleSortedRows.findIndex(row => row.id === params.id);
73
- const firstRowIndexInPage = currentPage.range.firstRowIndex;
74
- const lastRowIndexInPage = currentPage.range.lastRowIndex;
82
+ const rowIndexBefore = currentPageRows.findIndex(row => row.id === params.id);
83
+ const firstRowIndexInPage = 0;
84
+ const lastRowIndexInPage = currentPageRows.length - 1;
75
85
  const firstColIndex = 0;
76
86
  const lastColIndex = gridVisibleColumnDefinitionsSelector(apiRef).length - 1;
77
87
  let shouldPreventDefault = true;
@@ -82,7 +92,7 @@ export const useGridKeyboardNavigation = (apiRef, props) => {
82
92
  {
83
93
  // "Enter" is only triggered by the row / cell editing feature
84
94
  if (rowIndexBefore < lastRowIndexInPage) {
85
- goToCell(colIndexBefore, rowIndexBefore + 1);
95
+ goToCell(colIndexBefore, getRowIdFromIndex(rowIndexBefore + 1));
86
96
  }
87
97
 
88
98
  break;
@@ -91,7 +101,7 @@ export const useGridKeyboardNavigation = (apiRef, props) => {
91
101
  case 'ArrowUp':
92
102
  {
93
103
  if (rowIndexBefore > firstRowIndexInPage) {
94
- goToCell(colIndexBefore, rowIndexBefore - 1);
104
+ goToCell(colIndexBefore, getRowIdFromIndex(rowIndexBefore - 1));
95
105
  } else {
96
106
  goToHeader(colIndexBefore, event);
97
107
  }
@@ -102,7 +112,7 @@ export const useGridKeyboardNavigation = (apiRef, props) => {
102
112
  case 'ArrowRight':
103
113
  {
104
114
  if (colIndexBefore < lastColIndex) {
105
- goToCell(colIndexBefore + 1, rowIndexBefore, 'right');
115
+ goToCell(colIndexBefore + 1, getRowIdFromIndex(rowIndexBefore), 'right');
106
116
  }
107
117
 
108
118
  break;
@@ -111,7 +121,7 @@ export const useGridKeyboardNavigation = (apiRef, props) => {
111
121
  case 'ArrowLeft':
112
122
  {
113
123
  if (colIndexBefore > firstColIndex) {
114
- goToCell(colIndexBefore - 1, rowIndexBefore);
124
+ goToCell(colIndexBefore - 1, getRowIdFromIndex(rowIndexBefore));
115
125
  }
116
126
 
117
127
  break;
@@ -121,9 +131,9 @@ export const useGridKeyboardNavigation = (apiRef, props) => {
121
131
  {
122
132
  // "Tab" is only triggered by the row / cell editing feature
123
133
  if (event.shiftKey && colIndexBefore > firstColIndex) {
124
- goToCell(colIndexBefore - 1, rowIndexBefore, 'left');
134
+ goToCell(colIndexBefore - 1, getRowIdFromIndex(rowIndexBefore), 'left');
125
135
  } else if (!event.shiftKey && colIndexBefore < lastColIndex) {
126
- goToCell(colIndexBefore + 1, rowIndexBefore, 'right');
136
+ goToCell(colIndexBefore + 1, getRowIdFromIndex(rowIndexBefore), 'right');
127
137
  }
128
138
 
129
139
  break;
@@ -144,7 +154,7 @@ export const useGridKeyboardNavigation = (apiRef, props) => {
144
154
  }
145
155
 
146
156
  if (!event.shiftKey && rowIndexBefore < lastRowIndexInPage) {
147
- goToCell(colIndexBefore, Math.min(rowIndexBefore + viewportPageSize, lastRowIndexInPage));
157
+ goToCell(colIndexBefore, getRowIdFromIndex(Math.min(rowIndexBefore + viewportPageSize, lastRowIndexInPage)));
148
158
  }
149
159
 
150
160
  break;
@@ -153,7 +163,7 @@ export const useGridKeyboardNavigation = (apiRef, props) => {
153
163
  case 'PageDown':
154
164
  {
155
165
  if (rowIndexBefore < lastRowIndexInPage) {
156
- goToCell(colIndexBefore, Math.min(rowIndexBefore + viewportPageSize, lastRowIndexInPage));
166
+ goToCell(colIndexBefore, getRowIdFromIndex(Math.min(rowIndexBefore + viewportPageSize, lastRowIndexInPage)));
157
167
  }
158
168
 
159
169
  break;
@@ -165,7 +175,7 @@ export const useGridKeyboardNavigation = (apiRef, props) => {
165
175
  const nextRowIndex = Math.max(rowIndexBefore - viewportPageSize, firstRowIndexInPage);
166
176
 
167
177
  if (nextRowIndex !== rowIndexBefore && nextRowIndex >= firstRowIndexInPage) {
168
- goToCell(colIndexBefore, nextRowIndex);
178
+ goToCell(colIndexBefore, getRowIdFromIndex(nextRowIndex));
169
179
  } else {
170
180
  goToHeader(colIndexBefore, event);
171
181
  }
@@ -176,9 +186,9 @@ export const useGridKeyboardNavigation = (apiRef, props) => {
176
186
  case 'Home':
177
187
  {
178
188
  if (event.ctrlKey || event.metaKey || event.shiftKey) {
179
- goToCell(firstColIndex, firstRowIndexInPage);
189
+ goToCell(firstColIndex, getRowIdFromIndex(firstRowIndexInPage));
180
190
  } else {
181
- goToCell(firstColIndex, rowIndexBefore);
191
+ goToCell(firstColIndex, getRowIdFromIndex(rowIndexBefore));
182
192
  }
183
193
 
184
194
  break;
@@ -187,9 +197,9 @@ export const useGridKeyboardNavigation = (apiRef, props) => {
187
197
  case 'End':
188
198
  {
189
199
  if (event.ctrlKey || event.metaKey || event.shiftKey) {
190
- goToCell(lastColIndex, lastRowIndexInPage);
200
+ goToCell(lastColIndex, getRowIdFromIndex(lastRowIndexInPage));
191
201
  } else {
192
- goToCell(lastColIndex, rowIndexBefore);
202
+ goToCell(lastColIndex, getRowIdFromIndex(rowIndexBefore));
193
203
  }
194
204
 
195
205
  break;
@@ -204,10 +214,8 @@ export const useGridKeyboardNavigation = (apiRef, props) => {
204
214
  if (shouldPreventDefault) {
205
215
  event.preventDefault();
206
216
  }
207
- }, [apiRef, currentPage, goToCell, goToHeader]);
217
+ }, [apiRef, currentPageRows, goToCell, goToHeader, getRowIdFromIndex]);
208
218
  const handleColumnHeaderKeyDown = React.useCallback((params, event) => {
209
- var _currentPage$range$fi, _currentPage$range, _currentPage$range$la, _currentPage$range2;
210
-
211
219
  const headerTitleNode = event.currentTarget.querySelector(`.${gridClasses.columnHeaderTitleContainerContent}`);
212
220
  const isFromInsideContent = !!headerTitleNode && headerTitleNode.contains(event.target);
213
221
 
@@ -225,8 +233,8 @@ export const useGridKeyboardNavigation = (apiRef, props) => {
225
233
 
226
234
  const viewportPageSize = apiRef.current.unstable_getViewportPageSize();
227
235
  const colIndexBefore = params.field ? apiRef.current.getColumnIndex(params.field) : 0;
228
- const firstRowIndexInPage = (_currentPage$range$fi = (_currentPage$range = currentPage.range) == null ? void 0 : _currentPage$range.firstRowIndex) != null ? _currentPage$range$fi : null;
229
- const lastRowIndexInPage = (_currentPage$range$la = (_currentPage$range2 = currentPage.range) == null ? void 0 : _currentPage$range2.lastRowIndex) != null ? _currentPage$range$la : null;
236
+ const firstRowIndexInPage = 0;
237
+ const lastRowIndexInPage = currentPageRows.length - 1;
230
238
  const firstColIndex = 0;
231
239
  const lastColIndex = gridVisibleColumnDefinitionsSelector(apiRef).length - 1;
232
240
  let shouldPreventDefault = true;
@@ -235,7 +243,7 @@ export const useGridKeyboardNavigation = (apiRef, props) => {
235
243
  case 'ArrowDown':
236
244
  {
237
245
  if (firstRowIndexInPage !== null) {
238
- goToCell(colIndexBefore, firstRowIndexInPage);
246
+ goToCell(colIndexBefore, getRowIdFromIndex(firstRowIndexInPage));
239
247
  }
240
248
 
241
249
  break;
@@ -262,7 +270,7 @@ export const useGridKeyboardNavigation = (apiRef, props) => {
262
270
  case 'PageDown':
263
271
  {
264
272
  if (firstRowIndexInPage !== null && lastRowIndexInPage !== null) {
265
- goToCell(colIndexBefore, Math.min(firstRowIndexInPage + viewportPageSize, lastRowIndexInPage));
273
+ goToCell(colIndexBefore, getRowIdFromIndex(Math.min(firstRowIndexInPage + viewportPageSize, lastRowIndexInPage)));
266
274
  }
267
275
 
268
276
  break;
@@ -304,7 +312,7 @@ export const useGridKeyboardNavigation = (apiRef, props) => {
304
312
  if (shouldPreventDefault) {
305
313
  event.preventDefault();
306
314
  }
307
- }, [apiRef, currentPage, goToCell, goToHeader]);
315
+ }, [apiRef, currentPageRows, goToCell, goToHeader, getRowIdFromIndex]);
308
316
  const handleCellKeyDown = React.useCallback((params, event) => {
309
317
  // Ignore portal
310
318
  if (!event.currentTarget.contains(event.target)) {
@@ -4,6 +4,7 @@ import { useGridLogger, useGridApiMethod, useGridApiEventHandler, useGridSelecto
4
4
  import { gridPageSizeSelector } from './gridPaginationSelector';
5
5
  import { gridDensityRowHeightSelector } from '../density';
6
6
  import { useGridRegisterPipeProcessor } from '../../core/pipeProcessing';
7
+ import { calculatePinnedRowsHeight } from '../rows/gridRowsUtils';
7
8
  export const defaultPageSize = autoPageSize => autoPageSize ? 0 : 100;
8
9
 
9
10
  const mergeStateWithPageSize = pageSize => state => _extends({}, state, {
@@ -97,7 +98,8 @@ export const useGridPageSize = (apiRef, props) => {
97
98
  return;
98
99
  }
99
100
 
100
- const maximumPageSizeWithoutScrollBar = Math.floor(dimensions.viewportInnerSize.height / rowHeight);
101
+ const pinnedRowsHeight = calculatePinnedRowsHeight(apiRef);
102
+ const maximumPageSizeWithoutScrollBar = Math.floor((dimensions.viewportInnerSize.height - pinnedRowsHeight.top - pinnedRowsHeight.bottom) / rowHeight);
101
103
  apiRef.current.setPageSize(maximumPageSizeWithoutScrollBar);
102
104
  }, [apiRef, props.autoPageSize, rowHeight]);
103
105
  useGridApiEventHandler(apiRef, 'viewportInnerSizeChange', handleUpdateAutoPageSize);
@@ -9,3 +9,17 @@ export declare const gridRowTreeSelector: import("../../../utils/createSelector"
9
9
  export declare const gridRowGroupingNameSelector: import("../../../utils/createSelector").OutputSelector<GridStateCommunity, string>;
10
10
  export declare const gridRowTreeDepthSelector: import("../../../utils/createSelector").OutputSelector<GridStateCommunity, number>;
11
11
  export declare const gridRowIdsSelector: import("../../../utils/createSelector").OutputSelector<GridStateCommunity, import("../../..").GridRowId[]>;
12
+ /**
13
+ * @ignore - do not document.
14
+ */
15
+ export declare const gridAdditionalRowGroupsSelector: import("../../../utils/createSelector").OutputSelector<GridStateCommunity, {
16
+ pinnedRows?: import("./gridRowsState").GridPinnedRowsState | undefined;
17
+ } | undefined>;
18
+ /**
19
+ * @ignore - do not document.
20
+ */
21
+ export declare const gridPinnedRowsSelector: import("../../../utils/createSelector").OutputSelector<GridStateCommunity, import("./gridRowsState").GridPinnedRowsState | undefined>;
22
+ /**
23
+ * @ignore - do not document.
24
+ */
25
+ export declare const gridPinnedRowsCountSelector: import("../../../utils/createSelector").OutputSelector<GridStateCommunity, number>;
@@ -8,4 +8,23 @@ export const gridRowsIdToIdLookupSelector = createSelector(gridRowsStateSelector
8
8
  export const gridRowTreeSelector = createSelector(gridRowsStateSelector, rows => rows.tree);
9
9
  export const gridRowGroupingNameSelector = createSelector(gridRowsStateSelector, rows => rows.groupingName);
10
10
  export const gridRowTreeDepthSelector = createSelector(gridRowsStateSelector, rows => rows.treeDepth);
11
- export const gridRowIdsSelector = createSelector(gridRowsStateSelector, rows => rows.ids);
11
+ export const gridRowIdsSelector = createSelector(gridRowsStateSelector, rows => rows.ids);
12
+ /**
13
+ * @ignore - do not document.
14
+ */
15
+
16
+ export const gridAdditionalRowGroupsSelector = createSelector(gridRowsStateSelector, rows => rows == null ? void 0 : rows.additionalRowGroups);
17
+ /**
18
+ * @ignore - do not document.
19
+ */
20
+
21
+ export const gridPinnedRowsSelector = createSelector(gridAdditionalRowGroupsSelector, additionalRowGroups => additionalRowGroups == null ? void 0 : additionalRowGroups.pinnedRows);
22
+ /**
23
+ * @ignore - do not document.
24
+ */
25
+
26
+ export const gridPinnedRowsCountSelector = createSelector(gridPinnedRowsSelector, pinnedRows => {
27
+ var _pinnedRows$top, _pinnedRows$bottom;
28
+
29
+ return ((pinnedRows == null ? void 0 : (_pinnedRows$top = pinnedRows.top) == null ? void 0 : _pinnedRows$top.length) || 0) + ((pinnedRows == null ? void 0 : (_pinnedRows$bottom = pinnedRows.bottom) == null ? void 0 : _pinnedRows$bottom.length) || 0);
30
+ });
@@ -1,4 +1,4 @@
1
- import { GridRowId, GridRowsLookup, GridRowTreeConfig } from '../../../models/gridRows';
1
+ import { GridRowId, GridRowsLookup, GridRowTreeConfig, GridRowEntry } from '../../../models/gridRows';
2
2
  import type { DataGridProcessedProps } from '../../../models/props/DataGridProps';
3
3
  export interface GridRowTreeCreationParams {
4
4
  ids: GridRowId[];
@@ -17,6 +17,9 @@ export interface GridRowTreeCreationValue {
17
17
  ids: GridRowId[];
18
18
  idRowsLookup: GridRowsLookup;
19
19
  idToIdLookup: Record<string, GridRowId>;
20
+ additionalRowGroups?: {
21
+ pinnedRows?: GridPinnedRowsState;
22
+ };
20
23
  }
21
24
  export interface GridRowsInternalCache extends Omit<GridRowTreeCreationParams, 'previousTree'> {
22
25
  /**
@@ -51,3 +54,7 @@ export interface GridRowsState extends GridRowTreeCreationValue {
51
54
  groupingResponseBeforeRowHydration: GridRowTreeCreationValue;
52
55
  }
53
56
  export declare type GridHydrateRowsValue = GridRowTreeCreationValue;
57
+ export interface GridPinnedRowsState {
58
+ top?: GridRowEntry[];
59
+ bottom?: GridRowEntry[];
60
+ }
@@ -19,3 +19,7 @@ export declare const getRowsStateFromCache: ({ apiRef, previousTree, rowCountPro
19
19
  loadingProp: boolean | undefined;
20
20
  }) => GridRowsState;
21
21
  export declare const getTreeNodeDescendants: (tree: GridRowTreeConfig, parentId: GridRowId, skipAutoGeneratedRows: boolean) => GridRowId[];
22
+ export declare function calculatePinnedRowsHeight(apiRef: React.MutableRefObject<GridApiCommunity>): {
23
+ top: number;
24
+ bottom: number;
25
+ };
@@ -1,13 +1,14 @@
1
1
  import _extends from "@babel/runtime/helpers/esm/extends";
2
2
  import _objectWithoutPropertiesLoose from "@babel/runtime/helpers/esm/objectWithoutPropertiesLoose";
3
3
  const _excluded = ["rowsBeforePartialUpdates"];
4
-
4
+ import { gridPinnedRowsSelector } from './gridRowsSelector';
5
5
  /**
6
6
  * A helper function to check if the id provided is valid.
7
7
  * @param {GridRowId} id Id as [[GridRowId]].
8
8
  * @param {GridRowModel | Partial<GridRowModel>} row Row as [[GridRowModel]].
9
9
  * @param {string} detailErrorMessage A custom error message to display for invalid IDs
10
10
  */
11
+
11
12
  export function checkGridRowIdIsValid(id, row, detailErrorMessage = 'A row was provided without id in the rows prop:') {
12
13
  if (id == null) {
13
14
  throw new Error(['MUI: The data grid component requires all rows to have a unique `id` property.', 'Alternatively, you can use the `getRowId` prop to specify a custom id for each row.', detailErrorMessage, JSON.stringify(row)].join('\n'));
@@ -55,7 +56,7 @@ export const getRowsStateFromCache = ({
55
56
  previousTree
56
57
  }));
57
58
  const processedGroupingResponse = apiRef.current.unstable_applyPipeProcessors('hydrateRows', groupingResponse);
58
- const dataTopLevelRowCount = processedGroupingResponse.treeDepth === 1 ? processedGroupingResponse.ids.length : Object.values(processedGroupingResponse.tree).filter(node => node.parent == null).length;
59
+ const dataTopLevelRowCount = processedGroupingResponse.treeDepth === 1 ? processedGroupingResponse.ids.length : Object.values(processedGroupingResponse.tree).filter(node => node.parent == null && !node.isPinned).length;
59
60
  return _extends({}, processedGroupingResponse, {
60
61
  groupingResponseBeforeRowHydration: groupingResponse,
61
62
  loading: loadingProp,
@@ -86,4 +87,21 @@ export const getTreeNodeDescendants = (tree, parentId, skipAutoGeneratedRows) =>
86
87
  }
87
88
 
88
89
  return validDescendants;
89
- };
90
+ };
91
+ export function calculatePinnedRowsHeight(apiRef) {
92
+ var _pinnedRows$top, _pinnedRows$bottom;
93
+
94
+ const pinnedRows = gridPinnedRowsSelector(apiRef);
95
+ const topPinnedRowsHeight = (pinnedRows == null ? void 0 : (_pinnedRows$top = pinnedRows.top) == null ? void 0 : _pinnedRows$top.reduce((acc, value) => {
96
+ acc += apiRef.current.unstable_getRowHeight(value.id);
97
+ return acc;
98
+ }, 0)) || 0;
99
+ const bottomPinnedRowsHeight = (pinnedRows == null ? void 0 : (_pinnedRows$bottom = pinnedRows.bottom) == null ? void 0 : _pinnedRows$bottom.reduce((acc, value) => {
100
+ acc += apiRef.current.unstable_getRowHeight(value.id);
101
+ return acc;
102
+ }, 0)) || 0;
103
+ return {
104
+ top: topPinnedRowsHeight,
105
+ bottom: bottomPinnedRowsHeight
106
+ };
107
+ }
@@ -1,5 +1,5 @@
1
1
  export * from './gridRowsMetaSelector';
2
2
  export * from './gridRowsMetaState';
3
- export * from './gridRowsSelector';
3
+ export { gridRowsStateSelector, gridRowCountSelector, gridRowsLoadingSelector, gridTopLevelRowCountSelector, gridRowsLookupSelector, gridRowsIdToIdLookupSelector, gridRowTreeSelector, gridRowGroupingNameSelector, gridRowTreeDepthSelector, gridRowIdsSelector, } from './gridRowsSelector';
4
4
  export type { GridRowsState } from './gridRowsState';
5
5
  export { checkGridRowIdIsValid } from './gridRowsUtils';
@@ -1,4 +1,4 @@
1
1
  export * from './gridRowsMetaSelector';
2
2
  export * from './gridRowsMetaState';
3
- export * from './gridRowsSelector';
3
+ export { gridRowsStateSelector, gridRowCountSelector, gridRowsLoadingSelector, gridTopLevelRowCountSelector, gridRowsLookupSelector, gridRowsIdToIdLookupSelector, gridRowTreeSelector, gridRowGroupingNameSelector, gridRowTreeDepthSelector, gridRowIdsSelector } from './gridRowsSelector';
4
4
  export { checkGridRowIdIsValid } from './gridRowsUtils';
@@ -26,8 +26,11 @@ export const rowsStateInitializer = (state, props, apiRef) => {
26
26
  };
27
27
  export const useGridRows = (apiRef, props) => {
28
28
  if (process.env.NODE_ENV !== 'production') {
29
- // Freeze rows for immutability
30
- Object.freeze(props.rows);
29
+ try {
30
+ // Freeze the `rows` prop so developers have a fast failure if they try to use Array.prototype.push().
31
+ Object.freeze(props.rows);
32
+ } catch (error) {// Sometimes, it's impossible to freeze, so we give up on it.
33
+ }
31
34
  }
32
35
 
33
36
  const logger = useGridLogger(apiRef, 'useGridRows');
@@ -9,6 +9,7 @@ import { gridFilterStateSelector } from '../filter/gridFilterSelector';
9
9
  import { gridPaginationSelector } from '../pagination/gridPaginationSelector';
10
10
  import { gridSortingStateSelector } from '../sorting/gridSortingSelector';
11
11
  import { useGridRegisterPipeApplier } from '../../core/pipeProcessing';
12
+ import { gridPinnedRowsSelector } from './gridRowsSelector';
12
13
  export const rowsMetaStateInitializer = state => _extends({}, state, {
13
14
  rowsMeta: {
14
15
  currentPageTotalHeight: 0,
@@ -35,13 +36,14 @@ export const useGridRowsMeta = (apiRef, props) => {
35
36
  const paginationState = useGridSelector(apiRef, gridPaginationSelector);
36
37
  const sortingState = useGridSelector(apiRef, gridSortingStateSelector);
37
38
  const currentPage = useGridVisibleRows(apiRef, props);
39
+ const pinnedRows = useGridSelector(apiRef, gridPinnedRowsSelector);
38
40
  const hydrateRowsMeta = React.useCallback(() => {
41
+ var _pinnedRows$top, _pinnedRows$bottom;
42
+
39
43
  hasRowWithAutoHeight.current = false;
40
44
  const densityFactor = gridDensityFactorSelector(apiRef.current.state, apiRef.current.instanceId);
41
- const positions = [];
42
- const currentPageTotalHeight = currentPage.rows.reduce((acc, row) => {
43
- positions.push(acc);
44
45
 
46
+ const calculateRowProcessedSizes = row => {
45
47
  if (!rowsHeightLookup.current[row.id]) {
46
48
  rowsHeightLookup.current[row.id] = {
47
49
  sizes: {
@@ -113,9 +115,22 @@ export const useGridRowsMeta = (apiRef, props) => {
113
115
 
114
116
  const processedSizes = apiRef.current.unstable_applyPipeProcessors('rowHeight', initialHeights, row);
115
117
  rowsHeightLookup.current[row.id].sizes = processedSizes;
118
+ return processedSizes;
119
+ };
120
+
121
+ const positions = [];
122
+ const currentPageTotalHeight = currentPage.rows.reduce((acc, row) => {
123
+ positions.push(acc);
124
+ const processedSizes = calculateRowProcessedSizes(row);
116
125
  const finalRowHeight = Object.values(processedSizes).reduce((acc2, value) => acc2 + value, 0);
117
126
  return acc + finalRowHeight;
118
127
  }, 0);
128
+ pinnedRows == null ? void 0 : (_pinnedRows$top = pinnedRows.top) == null ? void 0 : _pinnedRows$top.forEach(row => {
129
+ calculateRowProcessedSizes(row);
130
+ });
131
+ pinnedRows == null ? void 0 : (_pinnedRows$bottom = pinnedRows.bottom) == null ? void 0 : _pinnedRows$bottom.forEach(row => {
132
+ calculateRowProcessedSizes(row);
133
+ });
119
134
  apiRef.current.setState(state => {
120
135
  return _extends({}, state, {
121
136
  rowsMeta: {
@@ -131,7 +146,7 @@ export const useGridRowsMeta = (apiRef, props) => {
131
146
  }
132
147
 
133
148
  apiRef.current.forceUpdate();
134
- }, [apiRef, currentPage.rows, rowHeightFromDensity, getRowHeightProp, getRowSpacing, getEstimatedRowHeight]);
149
+ }, [apiRef, currentPage.rows, rowHeightFromDensity, getRowHeightProp, getRowSpacing, getEstimatedRowHeight, pinnedRows]);
135
150
  const getRowHeight = React.useCallback(rowId => {
136
151
  const height = rowsHeightLookup.current[rowId];
137
152
  return height ? height.sizes.base : rowHeightFromDensity;
@@ -11,7 +11,8 @@ const flatRowTreeCreationMethod = ({
11
11
  for (let i = 0; i < ids.length; i += 1) {
12
12
  const rowId = ids[i];
13
13
 
14
- if (previousTree && previousTree[rowId] && previousTree[rowId].depth === 0 && previousTree[rowId].parent == null) {
14
+ if (previousTree && previousTree[rowId] && previousTree[rowId].depth === 0 && previousTree[rowId].parent == null && // pinned row can be unpinned
15
+ !previousTree[rowId].isPinned) {
15
16
  tree[rowId] = previousTree[rowId];
16
17
  } else {
17
18
  tree[rowId] = {
@@ -6,7 +6,8 @@ import { gridPageSelector, gridPageSizeSelector } from '../pagination/gridPagina
6
6
  import { gridRowCountSelector } from '../rows/gridRowsSelector';
7
7
  import { gridRowsMetaSelector } from '../rows/gridRowsMetaSelector';
8
8
  import { useGridApiMethod } from '../../utils/useGridApiMethod';
9
- import { gridVisibleSortedRowEntriesSelector } from '../filter/gridFilterSelector'; // Logic copied from https://www.w3.org/TR/wai-aria-practices/examples/listbox/js/listbox.js
9
+ import { gridVisibleSortedRowEntriesSelector } from '../filter/gridFilterSelector';
10
+ import { gridClasses } from '../../../constants/gridClasses'; // Logic copied from https://www.w3.org/TR/wai-aria-practices/examples/listbox/js/listbox.js
10
11
  // Similar to https://developer.mozilla.org/en-US/docs/Web/API/Element/scrollIntoView
11
12
 
12
13
  function scrollIntoView(dimensions) {
@@ -88,13 +89,17 @@ export const useGridScroll = (apiRef, props) => {
88
89
  }
89
90
 
90
91
  if (params.rowIndex != null) {
92
+ var _querySelector, _querySelector2;
93
+
91
94
  const rowsMeta = gridRowsMetaSelector(apiRef.current.state);
92
95
  const page = gridPageSelector(apiRef);
93
96
  const pageSize = gridPageSizeSelector(apiRef);
94
97
  const elementIndex = !props.pagination ? params.rowIndex : params.rowIndex - page * pageSize;
95
98
  const targetOffsetHeight = rowsMeta.positions[elementIndex + 1] ? rowsMeta.positions[elementIndex + 1] - rowsMeta.positions[elementIndex] : rowsMeta.currentPageTotalHeight - rowsMeta.positions[elementIndex];
99
+ const topPinnedRowsHeight = ((_querySelector = windowRef.current.querySelector(`.${gridClasses['pinnedRows--top']}`)) == null ? void 0 : _querySelector.clientHeight) || 0;
100
+ const bottomPinnedRowsHeight = ((_querySelector2 = windowRef.current.querySelector(`.${gridClasses['pinnedRows--bottom']}`)) == null ? void 0 : _querySelector2.clientHeight) || 0;
96
101
  scrollCoordinates.top = scrollIntoView({
97
- clientHeight: windowRef.current.clientHeight,
102
+ clientHeight: windowRef.current.clientHeight - topPinnedRowsHeight - bottomPinnedRowsHeight,
98
103
  scrollTop: windowRef.current.scrollTop,
99
104
  offsetHeight: targetOffsetHeight,
100
105
  offsetTop: rowsMeta.positions[elementIndex]
@@ -113,13 +113,13 @@ export const useGridSelection = (apiRef, props) => {
113
113
  }, [apiRef, logger]);
114
114
  const isRowSelected = React.useCallback(id => gridSelectionStateSelector(apiRef.current.state).includes(id), [apiRef]);
115
115
  const isRowSelectable = React.useCallback(id => {
116
- var _apiRef$current$getRo;
117
-
118
116
  if (propIsRowSelectable && !propIsRowSelectable(apiRef.current.getRowParams(id))) {
119
117
  return false;
120
118
  }
121
119
 
122
- if (((_apiRef$current$getRo = apiRef.current.getRowNode(id)) == null ? void 0 : _apiRef$current$getRo.position) === 'footer') {
120
+ const rowNode = apiRef.current.getRowNode(id);
121
+
122
+ if ((rowNode == null ? void 0 : rowNode.position) === 'footer' || rowNode != null && rowNode.isPinned) {
123
123
  return false;
124
124
  }
125
125
 
@@ -271,6 +271,10 @@ export const useGridSelection = (apiRef, props) => {
271
271
  }
272
272
  }
273
273
 
274
+ if (params.rowNode.isPinned) {
275
+ return;
276
+ }
277
+
274
278
  if (event.shiftKey && (canHaveMultipleSelection || checkboxSelection)) {
275
279
  expandMouseRowRangeSelection(params.id);
276
280
  } else {
@@ -195,6 +195,10 @@ export const useGridSorting = (apiRef, props) => {
195
195
  const bodyRowIds = [];
196
196
  const footerRowIds = [];
197
197
  gridRowIdsSelector(apiRef).forEach(rowId => {
198
+ if (rowTree[rowId].isPinned) {
199
+ return;
200
+ }
201
+
198
202
  if (rowTree[rowId].position === 'footer') {
199
203
  footerRowIds.push(rowId);
200
204
  } else {
@@ -207,6 +211,10 @@ export const useGridSorting = (apiRef, props) => {
207
211
  const bodyRows = [];
208
212
  const footerRowIds = [];
209
213
  Object.values(rowTree).forEach(rowNode => {
214
+ if (rowNode.isPinned) {
215
+ return;
216
+ }
217
+
210
218
  if (rowNode.position === 'footer') {
211
219
  footerRowIds.push(rowNode.id);
212
220
  } else {
@@ -20,6 +20,9 @@ export interface GridRestoreStatePreProcessingValue {
20
20
  */
21
21
  callbacks: (() => void)[];
22
22
  }
23
+ /**
24
+ * Object passed as parameter in the `exportState()` grid API method.
25
+ */
23
26
  export interface GridExportStateParams {
24
27
  /**
25
28
  * By default, the grid exports all the models.
@@ -1,5 +1,5 @@
1
1
  import * as React from 'react';
2
- import { GridRenderContext } from '../../../models';
2
+ import { GridRenderContext, GridRowEntry } from '../../../models';
3
3
  import { GridRowId, GridRowModel } from '../../../models/gridRows';
4
4
  export declare function binarySearch(offset: number, positions: number[], sliceStart?: number, sliceEnd?: number): number;
5
5
  export declare const getRenderableIndexes: ({ firstIndex, lastIndex, buffer, minFirstIndex, maxLastIndex, }: {
@@ -29,6 +29,8 @@ export declare const useGridVirtualScroller: (props: UseGridVirtualScrollerProps
29
29
  maxLastColumn?: number | undefined;
30
30
  availableSpace?: number | null | undefined;
31
31
  ignoreAutoHeight?: boolean | undefined;
32
+ rows?: GridRowEntry<any>[] | undefined;
33
+ rowIndexOffset?: number | undefined;
32
34
  }) => JSX.Element[] | null;
33
35
  getRootProps: ({ style, ...other }?: {
34
36
  style?: {} | undefined;