@mui/x-data-grid-pro 7.0.0-beta.6 → 7.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 (103) hide show
  1. package/CHANGELOG.md +311 -12
  2. package/DataGridPro/DataGridPro.js +18 -18
  3. package/DataGridPro/useDataGridProComponent.js +2 -3
  4. package/README.md +1 -1
  5. package/components/GridColumnHeaders.d.ts +1 -2
  6. package/components/GridColumnHeaders.js +7 -164
  7. package/components/headerFiltering/GridHeaderFilterCell.d.ts +8 -1
  8. package/components/headerFiltering/GridHeaderFilterCell.js +26 -9
  9. package/esm/DataGridPro/DataGridPro.js +18 -18
  10. package/esm/DataGridPro/useDataGridProComponent.js +1 -2
  11. package/esm/components/GridColumnHeaders.js +9 -166
  12. package/esm/components/GridDetailPanelToggleCell.js +1 -2
  13. package/esm/components/GridTreeDataGroupingCell.js +2 -3
  14. package/esm/components/headerFiltering/GridHeaderFilterCell.js +39 -26
  15. package/esm/components/headerFiltering/GridHeaderFilterClearButton.js +1 -2
  16. package/esm/components/headerFiltering/GridHeaderFilterMenu.js +1 -2
  17. package/esm/components/headerFiltering/GridHeaderFilterMenuContainer.js +1 -2
  18. package/esm/hooks/features/columnHeaders/useGridColumnHeaders.js +49 -16
  19. package/esm/hooks/features/columnPinning/useGridColumnPinning.js +7 -10
  20. package/esm/hooks/features/columnPinning/useGridColumnPinningPreProcessors.js +2 -0
  21. package/esm/hooks/features/columnReorder/useGridColumnReorder.js +2 -4
  22. package/esm/hooks/features/detailPanel/useGridDetailPanel.js +5 -10
  23. package/esm/hooks/features/detailPanel/useGridDetailPanelCache.js +1 -2
  24. package/esm/hooks/features/index.js +0 -1
  25. package/esm/hooks/features/infiniteLoader/useGridInfiniteLoader.js +6 -10
  26. package/esm/hooks/features/lazyLoader/useGridLazyLoader.js +3 -23
  27. package/esm/hooks/features/lazyLoader/useGridLazyLoaderPreProcessors.js +2 -6
  28. package/esm/hooks/features/rowPinning/useGridRowPinning.js +3 -5
  29. package/esm/hooks/features/rowPinning/useGridRowPinningPreProcessors.js +5 -7
  30. package/esm/hooks/features/treeData/gridTreeDataGroupColDef.js +1 -1
  31. package/esm/hooks/features/treeData/gridTreeDataUtils.js +1 -2
  32. package/esm/hooks/features/treeData/useGridTreeDataPreProcessors.js +1 -2
  33. package/esm/internals/index.js +0 -1
  34. package/esm/utils/releaseInfo.js +1 -1
  35. package/esm/utils/tree/insertDataRowInTree.js +8 -9
  36. package/esm/utils/tree/removeDataRowFromTree.js +3 -3
  37. package/esm/utils/tree/sortRowTree.js +1 -1
  38. package/esm/utils/tree/updateRowTree.js +1 -1
  39. package/esm/utils/tree/utils.js +6 -9
  40. package/hooks/features/columnHeaders/useGridColumnHeaders.d.ts +3 -5
  41. package/hooks/features/columnHeaders/useGridColumnHeaders.js +44 -11
  42. package/hooks/features/columnPinning/useGridColumnPinning.js +3 -3
  43. package/hooks/features/columnPinning/useGridColumnPinningPreProcessors.js +2 -0
  44. package/hooks/features/detailPanel/useGridDetailPanel.js +1 -1
  45. package/hooks/features/index.d.ts +0 -1
  46. package/hooks/features/index.js +0 -11
  47. package/hooks/features/infiniteLoader/useGridInfiniteLoader.js +2 -2
  48. package/hooks/features/lazyLoader/useGridLazyLoader.d.ts +1 -1
  49. package/hooks/features/lazyLoader/useGridLazyLoader.js +1 -19
  50. package/hooks/features/lazyLoader/useGridLazyLoaderPreProcessors.js +2 -5
  51. package/index.js +1 -1
  52. package/internals/index.d.ts +0 -1
  53. package/internals/index.js +0 -15
  54. package/models/dataGridProProps.d.ts +3 -36
  55. package/models/dataSource.d.ts +1 -1
  56. package/models/gridApiPro.d.ts +4 -4
  57. package/models/gridStatePro.d.ts +1 -2
  58. package/modern/DataGridPro/DataGridPro.js +18 -18
  59. package/modern/DataGridPro/useDataGridProComponent.js +1 -2
  60. package/modern/components/GridColumnHeaders.js +9 -166
  61. package/modern/components/headerFiltering/GridHeaderFilterCell.js +27 -10
  62. package/modern/hooks/features/columnHeaders/useGridColumnHeaders.js +46 -12
  63. package/modern/hooks/features/columnPinning/useGridColumnPinning.js +3 -3
  64. package/modern/hooks/features/columnPinning/useGridColumnPinningPreProcessors.js +2 -0
  65. package/modern/hooks/features/detailPanel/useGridDetailPanel.js +1 -1
  66. package/modern/hooks/features/index.js +0 -1
  67. package/modern/hooks/features/infiniteLoader/useGridInfiniteLoader.js +2 -2
  68. package/modern/hooks/features/lazyLoader/useGridLazyLoader.js +1 -19
  69. package/modern/hooks/features/lazyLoader/useGridLazyLoaderPreProcessors.js +2 -5
  70. package/modern/index.js +1 -1
  71. package/modern/internals/index.js +0 -1
  72. package/modern/utils/releaseInfo.js +1 -1
  73. package/package.json +6 -6
  74. package/typeOverloads/modules.d.ts +3 -3
  75. package/utils/releaseInfo.js +1 -1
  76. package/components/GridScrollArea.d.ts +0 -10
  77. package/components/GridScrollArea.js +0 -145
  78. package/esm/components/GridScrollArea.js +0 -137
  79. package/esm/hooks/features/columnResize/columnResizeSelector.js +0 -3
  80. package/esm/hooks/features/columnResize/columnResizeState.js +0 -1
  81. package/esm/hooks/features/columnResize/gridColumnResizeApi.js +0 -10
  82. package/esm/hooks/features/columnResize/index.js +0 -3
  83. package/esm/hooks/features/columnResize/useGridColumnResize.js +0 -547
  84. package/esm/utils/domUtils.js +0 -109
  85. package/hooks/features/columnResize/columnResizeSelector.d.ts +0 -3
  86. package/hooks/features/columnResize/columnResizeSelector.js +0 -10
  87. package/hooks/features/columnResize/columnResizeState.d.ts +0 -3
  88. package/hooks/features/columnResize/columnResizeState.js +0 -5
  89. package/hooks/features/columnResize/gridColumnResizeApi.d.ts +0 -44
  90. package/hooks/features/columnResize/gridColumnResizeApi.js +0 -16
  91. package/hooks/features/columnResize/index.d.ts +0 -3
  92. package/hooks/features/columnResize/index.js +0 -38
  93. package/hooks/features/columnResize/useGridColumnResize.d.ts +0 -10
  94. package/hooks/features/columnResize/useGridColumnResize.js +0 -548
  95. package/modern/components/GridScrollArea.js +0 -137
  96. package/modern/hooks/features/columnResize/columnResizeSelector.js +0 -3
  97. package/modern/hooks/features/columnResize/columnResizeState.js +0 -1
  98. package/modern/hooks/features/columnResize/gridColumnResizeApi.js +0 -10
  99. package/modern/hooks/features/columnResize/index.js +0 -3
  100. package/modern/hooks/features/columnResize/useGridColumnResize.js +0 -537
  101. package/modern/utils/domUtils.js +0 -107
  102. package/utils/domUtils.d.ts +0 -11
  103. package/utils/domUtils.js +0 -121
@@ -1,44 +0,0 @@
1
- import { GridColDef } from '@mui/x-data-grid';
2
- export declare const DEFAULT_GRID_AUTOSIZE_OPTIONS: {
3
- includeHeaders: boolean;
4
- includeOutliers: boolean;
5
- outliersFactor: number;
6
- expand: boolean;
7
- };
8
- export type GridAutosizeOptions = {
9
- /**
10
- * The columns to autosize. By default, applies to all columns.
11
- */
12
- columns?: GridColDef['field'][];
13
- /**
14
- * If true, include the header widths in the calculation.
15
- * @default false
16
- */
17
- includeHeaders?: boolean;
18
- /**
19
- * If true, width outliers will be ignored.
20
- * @default false
21
- */
22
- includeOutliers?: boolean;
23
- /**
24
- * The IQR factor range to detect outliers.
25
- * @default 1.5
26
- */
27
- outliersFactor?: number;
28
- /**
29
- * If the total width is less than the available width, expand columns to fill it.
30
- * @default false
31
- */
32
- expand?: boolean;
33
- };
34
- /**
35
- * The Resize API interface that is available in the grid `apiRef`.
36
- */
37
- export interface GridColumnResizeApi {
38
- /**
39
- * Auto-size the columns of the grid based on the cells' content and the space available.
40
- * @param {GridAutosizeOptions} options The autosizing options
41
- * @returns {Promise} A promise that resolves when autosizing is completed
42
- */
43
- autosizeColumns: (options?: GridAutosizeOptions) => Promise<void>;
44
- }
@@ -1,16 +0,0 @@
1
- "use strict";
2
-
3
- Object.defineProperty(exports, "__esModule", {
4
- value: true
5
- });
6
- exports.DEFAULT_GRID_AUTOSIZE_OPTIONS = void 0;
7
- const DEFAULT_GRID_AUTOSIZE_OPTIONS = exports.DEFAULT_GRID_AUTOSIZE_OPTIONS = {
8
- includeHeaders: true,
9
- includeOutliers: false,
10
- outliersFactor: 1.5,
11
- expand: false
12
- };
13
-
14
- /**
15
- * The Resize API interface that is available in the grid `apiRef`.
16
- */
@@ -1,3 +0,0 @@
1
- export * from './columnResizeSelector';
2
- export * from './columnResizeState';
3
- export * from './gridColumnResizeApi';
@@ -1,38 +0,0 @@
1
- "use strict";
2
-
3
- Object.defineProperty(exports, "__esModule", {
4
- value: true
5
- });
6
- var _columnResizeSelector = require("./columnResizeSelector");
7
- Object.keys(_columnResizeSelector).forEach(function (key) {
8
- if (key === "default" || key === "__esModule") return;
9
- if (key in exports && exports[key] === _columnResizeSelector[key]) return;
10
- Object.defineProperty(exports, key, {
11
- enumerable: true,
12
- get: function () {
13
- return _columnResizeSelector[key];
14
- }
15
- });
16
- });
17
- var _columnResizeState = require("./columnResizeState");
18
- Object.keys(_columnResizeState).forEach(function (key) {
19
- if (key === "default" || key === "__esModule") return;
20
- if (key in exports && exports[key] === _columnResizeState[key]) return;
21
- Object.defineProperty(exports, key, {
22
- enumerable: true,
23
- get: function () {
24
- return _columnResizeState[key];
25
- }
26
- });
27
- });
28
- var _gridColumnResizeApi = require("./gridColumnResizeApi");
29
- Object.keys(_gridColumnResizeApi).forEach(function (key) {
30
- if (key === "default" || key === "__esModule") return;
31
- if (key in exports && exports[key] === _gridColumnResizeApi[key]) return;
32
- Object.defineProperty(exports, key, {
33
- enumerable: true,
34
- get: function () {
35
- return _gridColumnResizeApi[key];
36
- }
37
- });
38
- });
@@ -1,10 +0,0 @@
1
- import * as React from 'react';
2
- import { GridStateInitializer } from '@mui/x-data-grid/internals';
3
- import { GridPrivateApiPro } from '../../../models/gridApiPro';
4
- import { DataGridProProcessedProps } from '../../../models/dataGridProProps';
5
- export declare const columnResizeStateInitializer: GridStateInitializer;
6
- /**
7
- * @requires useGridColumns (method, event)
8
- * TODO: improve experience for last column
9
- */
10
- export declare const useGridColumnResize: (apiRef: React.MutableRefObject<GridPrivateApiPro>, props: Pick<DataGridProProcessedProps, 'autosizeOptions' | 'autosizeOnMount' | 'disableAutosize' | 'onColumnResize' | 'onColumnWidthChange'>) => void;
@@ -1,548 +0,0 @@
1
- "use strict";
2
-
3
- var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
4
- Object.defineProperty(exports, "__esModule", {
5
- value: true
6
- });
7
- exports.useGridColumnResize = exports.columnResizeStateInitializer = void 0;
8
- var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends"));
9
- var React = _interopRequireWildcard(require("react"));
10
- var _utils = require("@mui/utils");
11
- var _xDataGrid = require("@mui/x-data-grid");
12
- var _internals = require("@mui/x-data-grid/internals");
13
- var _styles = require("@mui/material/styles");
14
- var _domUtils = require("../../../utils/domUtils");
15
- var _gridColumnResizeApi = require("./gridColumnResizeApi");
16
- function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); }
17
- function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && Object.prototype.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; }
18
- // TODO: remove support for Safari < 13.
19
- // https://caniuse.com/#search=touch-action
20
- //
21
- // Safari, on iOS, supports touch action since v13.
22
- // Over 80% of the iOS phones are compatible
23
- // in August 2020.
24
- // Utilizing the CSS.supports method to check if touch-action is supported.
25
- // Since CSS.supports is supported on all but Edge@12 and IE and touch-action
26
- // is supported on both Edge@12 and IE if CSS.supports is not available that means that
27
- // touch-action will be supported
28
- let cachedSupportsTouchActionNone = false;
29
- function doesSupportTouchActionNone() {
30
- if (cachedSupportsTouchActionNone === undefined) {
31
- if (typeof CSS !== 'undefined' && typeof CSS.supports === 'function') {
32
- cachedSupportsTouchActionNone = CSS.supports('touch-action', 'none');
33
- } else {
34
- cachedSupportsTouchActionNone = true;
35
- }
36
- }
37
- return cachedSupportsTouchActionNone;
38
- }
39
- function trackFinger(event, currentTouchId) {
40
- if (currentTouchId !== undefined && event.changedTouches) {
41
- for (let i = 0; i < event.changedTouches.length; i += 1) {
42
- const touch = event.changedTouches[i];
43
- if (touch.identifier === currentTouchId) {
44
- return {
45
- x: touch.clientX,
46
- y: touch.clientY
47
- };
48
- }
49
- }
50
- return false;
51
- }
52
- return {
53
- x: event.clientX,
54
- y: event.clientY
55
- };
56
- }
57
- function computeNewWidth(initialOffsetToSeparator, clickX, columnBounds, resizeDirection) {
58
- let newWidth = initialOffsetToSeparator;
59
- if (resizeDirection === 'Right') {
60
- newWidth += clickX - columnBounds.left;
61
- } else {
62
- newWidth += columnBounds.right - clickX;
63
- }
64
- return newWidth;
65
- }
66
- function computeOffsetToSeparator(clickX, columnBounds, resizeDirection) {
67
- if (resizeDirection === 'Left') {
68
- return clickX - columnBounds.left;
69
- }
70
- return columnBounds.right - clickX;
71
- }
72
- function flipResizeDirection(side) {
73
- if (side === 'Right') {
74
- return 'Left';
75
- }
76
- return 'Right';
77
- }
78
- function getResizeDirection(separator, direction) {
79
- const side = separator.classList.contains(_xDataGrid.gridClasses['columnSeparator--sideRight']) ? 'Right' : 'Left';
80
- if (direction === 'rtl') {
81
- // Resizing logic should be mirrored in the RTL case
82
- return flipResizeDirection(side);
83
- }
84
- return side;
85
- }
86
- function preventClick(event) {
87
- event.preventDefault();
88
- event.stopImmediatePropagation();
89
- }
90
-
91
- /**
92
- * Checker that returns a promise that resolves when the column virtualization
93
- * is disabled.
94
- */
95
- function useColumnVirtualizationDisabled(apiRef) {
96
- const promise = React.useRef();
97
- const selector = () => (0, _xDataGrid.gridVirtualizationColumnEnabledSelector)(apiRef);
98
- const value = (0, _xDataGrid.useGridSelector)(apiRef, selector);
99
- React.useEffect(() => {
100
- if (promise.current && value === false) {
101
- promise.current.resolve();
102
- promise.current = undefined;
103
- }
104
- });
105
- const asyncCheck = () => {
106
- if (!promise.current) {
107
- if (selector() === false) {
108
- return Promise.resolve();
109
- }
110
- promise.current = (0, _internals.createControllablePromise)();
111
- }
112
- return promise.current;
113
- };
114
- return asyncCheck;
115
- }
116
-
117
- /**
118
- * Basic statistical outlier detection, checks if the value is `F * IQR` away from
119
- * the Q1 and Q3 boundaries. IQR: interquartile range.
120
- */
121
- function excludeOutliers(inputValues, factor) {
122
- if (inputValues.length < 4) {
123
- return inputValues;
124
- }
125
- const values = inputValues.slice();
126
- values.sort((a, b) => a - b);
127
- const q1 = values[Math.floor(values.length * 0.25)];
128
- const q3 = values[Math.floor(values.length * 0.75) - 1];
129
- const iqr = q3 - q1;
130
-
131
- // We make a small adjustment if `iqr < 5` for the cases where the IQR is
132
- // very small (e.g. zero) due to very close by values in the input data.
133
- // Otherwise, with an IQR of `0`, anything outside that would be considered
134
- // an outlier, but it makes more sense visually to allow for this 5px variance
135
- // rather than showing a cropped cell.
136
- const deviation = iqr < 5 ? 5 : iqr * factor;
137
- return values.filter(v => v > q1 - deviation && v < q3 + deviation);
138
- }
139
- function extractColumnWidths(apiRef, options, columns) {
140
- const widthByField = {};
141
- const root = apiRef.current.rootElementRef.current;
142
- root.classList.add(_xDataGrid.gridClasses.autosizing);
143
- columns.forEach(column => {
144
- const cells = (0, _domUtils.findGridCells)(apiRef.current, column.field);
145
- const widths = cells.map(cell => {
146
- return cell.getBoundingClientRect().width ?? 0;
147
- });
148
- const filteredWidths = options.includeOutliers ? widths : excludeOutliers(widths, options.outliersFactor);
149
- if (options.includeHeaders) {
150
- const header = (0, _domUtils.findGridHeader)(apiRef.current, column.field);
151
- if (header) {
152
- const title = header.querySelector(`.${_xDataGrid.gridClasses.columnHeaderTitle}`);
153
- const content = header.querySelector(`.${_xDataGrid.gridClasses.columnHeaderTitleContainerContent}`);
154
- const iconContainer = header.querySelector(`.${_xDataGrid.gridClasses.iconButtonContainer}`);
155
- const menuContainer = header.querySelector(`.${_xDataGrid.gridClasses.menuIcon}`);
156
- const element = title ?? content;
157
- const style = window.getComputedStyle(header, null);
158
- const paddingWidth = parseInt(style.paddingLeft, 10) + parseInt(style.paddingRight, 10);
159
- const contentWidth = element.scrollWidth + 1;
160
- const width = contentWidth + paddingWidth + (iconContainer?.clientWidth ?? 0) + (menuContainer?.clientWidth ?? 0);
161
- filteredWidths.push(width);
162
- }
163
- }
164
- const hasColumnMin = column.minWidth !== -Infinity && column.minWidth !== undefined;
165
- const hasColumnMax = column.maxWidth !== Infinity && column.maxWidth !== undefined;
166
- const min = hasColumnMin ? column.minWidth : 0;
167
- const max = hasColumnMax ? column.maxWidth : Infinity;
168
- const maxContent = filteredWidths.length === 0 ? 0 : Math.max(...filteredWidths);
169
- widthByField[column.field] = (0, _internals.clamp)(maxContent, min, max);
170
- });
171
- root.classList.remove(_xDataGrid.gridClasses.autosizing);
172
- return widthByField;
173
- }
174
- const columnResizeStateInitializer = state => (0, _extends2.default)({}, state, {
175
- columnResize: {
176
- resizingColumnField: ''
177
- }
178
- });
179
- /**
180
- * @requires useGridColumns (method, event)
181
- * TODO: improve experience for last column
182
- */
183
- exports.columnResizeStateInitializer = columnResizeStateInitializer;
184
- const useGridColumnResize = (apiRef, props) => {
185
- const theme = (0, _styles.useTheme)();
186
- const logger = (0, _xDataGrid.useGridLogger)(apiRef, 'useGridColumnResize');
187
- const colDefRef = React.useRef();
188
- const previousMouseClickEvent = React.useRef();
189
- const columnHeaderElementRef = React.useRef();
190
- const headerFilterElementRef = React.useRef();
191
- const groupHeaderElementsRef = React.useRef([]);
192
- const cellElementsRef = React.useRef([]);
193
- const leftPinnedCellsAfterRef = React.useRef([]);
194
- const rightPinnedCellsBeforeRef = React.useRef([]);
195
- const fillerLeftRef = React.useRef();
196
- const fillerRightRef = React.useRef();
197
-
198
- // To improve accessibility, the separator has padding on both sides.
199
- // Clicking inside the padding area should be treated as a click in the separator.
200
- // This ref stores the offset between the click and the separator.
201
- const initialOffsetToSeparator = React.useRef();
202
- const resizeDirection = React.useRef();
203
- const stopResizeEventTimeout = (0, _internals.useTimeout)();
204
- const touchId = React.useRef();
205
- const updateWidth = newWidth => {
206
- logger.debug(`Updating width to ${newWidth} for col ${colDefRef.current.field}`);
207
- const prevWidth = columnHeaderElementRef.current.offsetWidth;
208
- const widthDiff = newWidth - prevWidth;
209
- colDefRef.current.computedWidth = newWidth;
210
- colDefRef.current.width = newWidth;
211
- colDefRef.current.flex = 0;
212
- columnHeaderElementRef.current.style.width = `${newWidth}px`;
213
- columnHeaderElementRef.current.style.minWidth = `${newWidth}px`;
214
- columnHeaderElementRef.current.style.maxWidth = `${newWidth}px`;
215
- const headerFilterElement = headerFilterElementRef.current;
216
- if (headerFilterElement) {
217
- headerFilterElement.style.width = `${newWidth}px`;
218
- headerFilterElement.style.minWidth = `${newWidth}px`;
219
- headerFilterElement.style.maxWidth = `${newWidth}px`;
220
- }
221
- groupHeaderElementsRef.current.forEach(element => {
222
- const div = element;
223
- let finalWidth;
224
- if (div.getAttribute('aria-colspan') === '1') {
225
- finalWidth = `${newWidth}px`;
226
- } else {
227
- // Cell with colspan > 1 cannot be just updated width new width.
228
- // Instead, we add width diff to the current width.
229
- finalWidth = `${div.offsetWidth + widthDiff}px`;
230
- }
231
- div.style.width = finalWidth;
232
- div.style.minWidth = finalWidth;
233
- div.style.maxWidth = finalWidth;
234
- });
235
- cellElementsRef.current.forEach(element => {
236
- const div = element;
237
- let finalWidth;
238
- if (div.getAttribute('aria-colspan') === '1') {
239
- finalWidth = `${newWidth}px`;
240
- } else {
241
- // Cell with colspan > 1 cannot be just updated width new width.
242
- // Instead, we add width diff to the current width.
243
- finalWidth = `${div.offsetWidth + widthDiff}px`;
244
- }
245
- div.style.setProperty('--width', finalWidth);
246
- });
247
- const pinnedPosition = apiRef.current.isColumnPinned(colDefRef.current.field);
248
- if (pinnedPosition === _xDataGrid.GridPinnedColumnPosition.LEFT) {
249
- updateProperty(fillerLeftRef.current, 'width', widthDiff);
250
- leftPinnedCellsAfterRef.current.forEach(cell => {
251
- updateProperty(cell, 'left', widthDiff);
252
- });
253
- }
254
- if (pinnedPosition === _xDataGrid.GridPinnedColumnPosition.RIGHT) {
255
- updateProperty(fillerRightRef.current, 'width', widthDiff);
256
- rightPinnedCellsBeforeRef.current.forEach(cell => {
257
- updateProperty(cell, 'right', widthDiff);
258
- });
259
- }
260
- };
261
- const finishResize = nativeEvent => {
262
- // eslint-disable-next-line @typescript-eslint/no-use-before-define
263
- stopListening();
264
-
265
- // Prevent double-clicks from being interpreted as two separate clicks
266
- if (previousMouseClickEvent.current) {
267
- const prevEvent = previousMouseClickEvent.current;
268
- const prevTimeStamp = prevEvent.timeStamp;
269
- const prevClientX = prevEvent.clientX;
270
- const prevClientY = prevEvent.clientY;
271
-
272
- // Check if the current event is part of a double-click
273
- if (nativeEvent.timeStamp - prevTimeStamp < 300 && nativeEvent.clientX === prevClientX && nativeEvent.clientY === prevClientY) {
274
- previousMouseClickEvent.current = undefined;
275
- return;
276
- }
277
- }
278
- if (colDefRef.current) {
279
- apiRef.current.setColumnWidth(colDefRef.current.field, colDefRef.current.width);
280
- logger.debug(`Updating col ${colDefRef.current.field} with new width: ${colDefRef.current.width}`);
281
- }
282
- stopResizeEventTimeout.start(0, () => {
283
- apiRef.current.publishEvent('columnResizeStop', null, nativeEvent);
284
- });
285
- };
286
- const storeReferences = (colDef, separator, xStart) => {
287
- const root = apiRef.current.rootElementRef.current;
288
- colDefRef.current = colDef;
289
- columnHeaderElementRef.current = (0, _domUtils.findHeaderElementFromField)(apiRef.current.columnHeadersContainerElementRef.current, colDef.field);
290
- const headerFilterElement = root.querySelector(`.${_xDataGrid.gridClasses.headerFilterRow} [data-field="${colDef.field}"]`);
291
- if (headerFilterElement) {
292
- headerFilterElementRef.current = headerFilterElement;
293
- }
294
- groupHeaderElementsRef.current = (0, _domUtils.findGroupHeaderElementsFromField)(apiRef.current.columnHeadersContainerElementRef?.current, colDef.field);
295
- cellElementsRef.current = (0, _domUtils.findGridCellElementsFromCol)(columnHeaderElementRef.current, apiRef.current);
296
- fillerLeftRef.current = (0, _domUtils.findGridElement)(apiRef.current, 'filler--pinnedLeft');
297
- fillerRightRef.current = (0, _domUtils.findGridElement)(apiRef.current, 'filler--pinnedRight');
298
- const pinnedPosition = apiRef.current.isColumnPinned(colDef.field);
299
- leftPinnedCellsAfterRef.current = pinnedPosition !== _xDataGrid.GridPinnedColumnPosition.LEFT ? [] : (0, _domUtils.findLeftPinnedCellsAfterCol)(apiRef.current, columnHeaderElementRef.current);
300
- rightPinnedCellsBeforeRef.current = pinnedPosition !== _xDataGrid.GridPinnedColumnPosition.RIGHT ? [] : (0, _domUtils.findRightPinnedCellsBeforeCol)(apiRef.current, columnHeaderElementRef.current);
301
- resizeDirection.current = getResizeDirection(separator, theme.direction);
302
- initialOffsetToSeparator.current = computeOffsetToSeparator(xStart, columnHeaderElementRef.current.getBoundingClientRect(), resizeDirection.current);
303
- };
304
- const handleResizeMouseUp = (0, _utils.unstable_useEventCallback)(finishResize);
305
- const handleResizeMouseMove = (0, _utils.unstable_useEventCallback)(nativeEvent => {
306
- // Cancel move in case some other element consumed a mouseup event and it was not fired.
307
- if (nativeEvent.buttons === 0) {
308
- handleResizeMouseUp(nativeEvent);
309
- return;
310
- }
311
- let newWidth = computeNewWidth(initialOffsetToSeparator.current, nativeEvent.clientX, columnHeaderElementRef.current.getBoundingClientRect(), resizeDirection.current);
312
- newWidth = (0, _internals.clamp)(newWidth, colDefRef.current.minWidth, colDefRef.current.maxWidth);
313
- updateWidth(newWidth);
314
- const params = {
315
- element: columnHeaderElementRef.current,
316
- colDef: colDefRef.current,
317
- width: newWidth
318
- };
319
- apiRef.current.publishEvent('columnResize', params, nativeEvent);
320
- });
321
- const handleTouchEnd = (0, _utils.unstable_useEventCallback)(nativeEvent => {
322
- const finger = trackFinger(nativeEvent, touchId.current);
323
- if (!finger) {
324
- return;
325
- }
326
- finishResize(nativeEvent);
327
- });
328
- const handleTouchMove = (0, _utils.unstable_useEventCallback)(nativeEvent => {
329
- const finger = trackFinger(nativeEvent, touchId.current);
330
- if (!finger) {
331
- return;
332
- }
333
-
334
- // Cancel move in case some other element consumed a touchmove event and it was not fired.
335
- if (nativeEvent.type === 'mousemove' && nativeEvent.buttons === 0) {
336
- handleTouchEnd(nativeEvent);
337
- return;
338
- }
339
- let newWidth = computeNewWidth(initialOffsetToSeparator.current, finger.x, columnHeaderElementRef.current.getBoundingClientRect(), resizeDirection.current);
340
- newWidth = (0, _internals.clamp)(newWidth, colDefRef.current.minWidth, colDefRef.current.maxWidth);
341
- updateWidth(newWidth);
342
- const params = {
343
- element: columnHeaderElementRef.current,
344
- colDef: colDefRef.current,
345
- width: newWidth
346
- };
347
- apiRef.current.publishEvent('columnResize', params, nativeEvent);
348
- });
349
- const handleTouchStart = (0, _utils.unstable_useEventCallback)(event => {
350
- const cellSeparator = (0, _internals.findParentElementFromClassName)(event.target, _xDataGrid.gridClasses['columnSeparator--resizable']);
351
- // Let the event bubble if the target is not a col separator
352
- if (!cellSeparator) {
353
- return;
354
- }
355
- // If touch-action: none; is not supported we need to prevent the scroll manually.
356
- if (!doesSupportTouchActionNone()) {
357
- event.preventDefault();
358
- }
359
- const touch = event.changedTouches[0];
360
- if (touch != null) {
361
- // A number that uniquely identifies the current finger in the touch session.
362
- touchId.current = touch.identifier;
363
- }
364
- const columnHeaderElement = (0, _internals.findParentElementFromClassName)(event.target, _xDataGrid.gridClasses.columnHeader);
365
- const field = (0, _domUtils.getFieldFromHeaderElem)(columnHeaderElement);
366
- const colDef = apiRef.current.getColumn(field);
367
- logger.debug(`Start Resize on col ${colDef.field}`);
368
- apiRef.current.publishEvent('columnResizeStart', {
369
- field
370
- }, event);
371
- storeReferences(colDef, cellSeparator, touch.clientX);
372
- const doc = (0, _utils.unstable_ownerDocument)(event.currentTarget);
373
- doc.addEventListener('touchmove', handleTouchMove);
374
- doc.addEventListener('touchend', handleTouchEnd);
375
- });
376
- const stopListening = React.useCallback(() => {
377
- const doc = (0, _utils.unstable_ownerDocument)(apiRef.current.rootElementRef.current);
378
- doc.body.style.removeProperty('cursor');
379
- doc.removeEventListener('mousemove', handleResizeMouseMove);
380
- doc.removeEventListener('mouseup', handleResizeMouseUp);
381
- doc.removeEventListener('touchmove', handleTouchMove);
382
- doc.removeEventListener('touchend', handleTouchEnd);
383
- // The click event runs right after the mouseup event, we want to wait until it
384
- // has been canceled before removing our handler.
385
- setTimeout(() => {
386
- doc.removeEventListener('click', preventClick, true);
387
- }, 100);
388
- if (columnHeaderElementRef.current) {
389
- columnHeaderElementRef.current.style.pointerEvents = 'unset';
390
- }
391
- }, [apiRef, columnHeaderElementRef, handleResizeMouseMove, handleResizeMouseUp, handleTouchMove, handleTouchEnd]);
392
- const handleResizeStart = React.useCallback(({
393
- field
394
- }) => {
395
- apiRef.current.setState(state => (0, _extends2.default)({}, state, {
396
- columnResize: (0, _extends2.default)({}, state.columnResize, {
397
- resizingColumnField: field
398
- })
399
- }));
400
- apiRef.current.forceUpdate();
401
- }, [apiRef]);
402
- const handleResizeStop = React.useCallback(() => {
403
- apiRef.current.setState(state => (0, _extends2.default)({}, state, {
404
- columnResize: (0, _extends2.default)({}, state.columnResize, {
405
- resizingColumnField: ''
406
- })
407
- }));
408
- apiRef.current.forceUpdate();
409
- }, [apiRef]);
410
- const handleColumnResizeMouseDown = (0, _utils.unstable_useEventCallback)(({
411
- colDef
412
- }, event) => {
413
- // Only handle left clicks
414
- if (event.button !== 0) {
415
- return;
416
- }
417
-
418
- // Skip if the column isn't resizable
419
- if (!event.currentTarget.classList.contains(_xDataGrid.gridClasses['columnSeparator--resizable'])) {
420
- return;
421
- }
422
-
423
- // Avoid text selection
424
- event.preventDefault();
425
- logger.debug(`Start Resize on col ${colDef.field}`);
426
- apiRef.current.publishEvent('columnResizeStart', {
427
- field: colDef.field
428
- }, event);
429
- storeReferences(colDef, event.currentTarget, event.clientX);
430
- const doc = (0, _utils.unstable_ownerDocument)(apiRef.current.rootElementRef.current);
431
- doc.body.style.cursor = 'col-resize';
432
- previousMouseClickEvent.current = event.nativeEvent;
433
- doc.addEventListener('mousemove', handleResizeMouseMove);
434
- doc.addEventListener('mouseup', handleResizeMouseUp);
435
-
436
- // Prevent the click event if we have resized the column.
437
- // Fixes https://github.com/mui/mui-x/issues/4777
438
- doc.addEventListener('click', preventClick, true);
439
- });
440
- const handleColumnSeparatorDoubleClick = (0, _utils.unstable_useEventCallback)((params, event) => {
441
- if (props.disableAutosize) {
442
- return;
443
- }
444
-
445
- // Only handle left clicks
446
- if (event.button !== 0) {
447
- return;
448
- }
449
- const column = apiRef.current.state.columns.lookup[params.field];
450
- if (column.resizable === false) {
451
- return;
452
- }
453
- apiRef.current.autosizeColumns((0, _extends2.default)({}, props.autosizeOptions, {
454
- columns: [column.field]
455
- }));
456
- });
457
-
458
- /**
459
- * API METHODS
460
- */
461
-
462
- const columnVirtualizationDisabled = useColumnVirtualizationDisabled(apiRef);
463
- const isAutosizingRef = React.useRef(false);
464
- const autosizeColumns = React.useCallback(async userOptions => {
465
- const root = apiRef.current.rootElementRef?.current;
466
- if (!root) {
467
- return;
468
- }
469
- if (isAutosizingRef.current) {
470
- return;
471
- }
472
- isAutosizingRef.current = true;
473
- const state = (0, _internals.gridColumnsStateSelector)(apiRef.current.state);
474
- const options = (0, _extends2.default)({}, _gridColumnResizeApi.DEFAULT_GRID_AUTOSIZE_OPTIONS, userOptions, {
475
- columns: userOptions?.columns ?? state.orderedFields
476
- });
477
- options.columns = options.columns.filter(c => state.columnVisibilityModel[c] !== false);
478
- const columns = options.columns.map(c => apiRef.current.state.columns.lookup[c]);
479
- try {
480
- apiRef.current.unstable_setColumnVirtualization(false);
481
- await columnVirtualizationDisabled();
482
- const widthByField = extractColumnWidths(apiRef, options, columns);
483
- const newColumns = columns.map(column => (0, _extends2.default)({}, column, {
484
- width: widthByField[column.field],
485
- computedWidth: widthByField[column.field]
486
- }));
487
- if (options.expand) {
488
- const visibleColumns = state.orderedFields.map(field => state.lookup[field]).filter(c => state.columnVisibilityModel[c.field] !== false);
489
- const totalWidth = visibleColumns.reduce((total, column) => total + (widthByField[column.field] ?? column.computedWidth ?? column.width), 0);
490
- const availableWidth = apiRef.current.getRootDimensions().viewportInnerSize.width;
491
- const remainingWidth = availableWidth - totalWidth;
492
- if (remainingWidth > 0) {
493
- const widthPerColumn = remainingWidth / (newColumns.length || 1);
494
- newColumns.forEach(column => {
495
- column.width += widthPerColumn;
496
- column.computedWidth += widthPerColumn;
497
- });
498
- }
499
- }
500
- apiRef.current.updateColumns(newColumns);
501
- newColumns.forEach((newColumn, index) => {
502
- if (newColumn.width !== columns[index].width) {
503
- const width = newColumn.width;
504
- apiRef.current.publishEvent('columnWidthChange', {
505
- element: apiRef.current.getColumnHeaderElement(newColumn.field),
506
- colDef: newColumn,
507
- width
508
- });
509
- }
510
- });
511
- } finally {
512
- apiRef.current.unstable_setColumnVirtualization(true);
513
- isAutosizingRef.current = false;
514
- }
515
- }, [apiRef, columnVirtualizationDisabled]);
516
-
517
- /**
518
- * EFFECTS
519
- */
520
-
521
- React.useEffect(() => stopListening, [stopListening]);
522
- (0, _internals.useOnMount)(() => {
523
- if (props.autosizeOnMount) {
524
- Promise.resolve().then(() => {
525
- apiRef.current.autosizeColumns(props.autosizeOptions);
526
- });
527
- }
528
- });
529
- (0, _xDataGrid.useGridNativeEventListener)(apiRef, () => apiRef.current.columnHeadersElementRef?.current, 'touchstart', handleTouchStart, {
530
- passive: doesSupportTouchActionNone()
531
- });
532
- (0, _xDataGrid.useGridApiMethod)(apiRef, {
533
- autosizeColumns
534
- }, 'public');
535
- (0, _xDataGrid.useGridApiEventHandler)(apiRef, 'columnResizeStop', handleResizeStop);
536
- (0, _xDataGrid.useGridApiEventHandler)(apiRef, 'columnResizeStart', handleResizeStart);
537
- (0, _xDataGrid.useGridApiEventHandler)(apiRef, 'columnSeparatorMouseDown', handleColumnResizeMouseDown);
538
- (0, _xDataGrid.useGridApiEventHandler)(apiRef, 'columnSeparatorDoubleClick', handleColumnSeparatorDoubleClick);
539
- (0, _xDataGrid.useGridApiOptionHandler)(apiRef, 'columnResize', props.onColumnResize);
540
- (0, _xDataGrid.useGridApiOptionHandler)(apiRef, 'columnWidthChange', props.onColumnWidthChange);
541
- };
542
- exports.useGridColumnResize = useGridColumnResize;
543
- function updateProperty(element, property, delta) {
544
- if (!element) {
545
- return;
546
- }
547
- element.style[property] = `${parseInt(element.style[property], 10) + delta}px`;
548
- }