@mui/x-data-grid 8.29.1 → 8.29.3

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 (44) hide show
  1. package/CHANGELOG.md +157 -0
  2. package/components/columnsPanel/ColumnsPanelTrigger.js +2 -2
  3. package/components/columnsPanel/ColumnsPanelTrigger.mjs +2 -2
  4. package/components/containers/GridRootStyles.js +3 -2
  5. package/components/containers/GridRootStyles.mjs +3 -2
  6. package/components/filterPanel/FilterPanelTrigger.js +2 -2
  7. package/components/filterPanel/FilterPanelTrigger.mjs +2 -2
  8. package/components/panel/GridPanelContext.d.mts +9 -3
  9. package/components/panel/GridPanelContext.d.ts +9 -3
  10. package/components/panel/GridPanelContext.js +41 -7
  11. package/components/panel/GridPanelContext.mjs +40 -7
  12. package/components/panel/GridPreferencesPanel.js +4 -6
  13. package/components/panel/GridPreferencesPanel.mjs +4 -6
  14. package/components/toolbar/GridToolbarColumnsButton.js +2 -2
  15. package/components/toolbar/GridToolbarColumnsButton.mjs +2 -2
  16. package/components/toolbar/GridToolbarFilterButton.js +2 -2
  17. package/components/toolbar/GridToolbarFilterButton.mjs +2 -2
  18. package/components/toolbarV8/Toolbar.d.mts +1 -1
  19. package/components/toolbarV8/Toolbar.d.ts +1 -1
  20. package/components/toolbarV8/Toolbar.js +2 -125
  21. package/components/toolbarV8/Toolbar.mjs +2 -125
  22. package/components/toolbarV8/ToolbarButton.d.mts +1 -1
  23. package/components/toolbarV8/ToolbarButton.d.ts +1 -1
  24. package/components/toolbarV8/ToolbarButton.js +11 -50
  25. package/components/toolbarV8/ToolbarButton.mjs +11 -50
  26. package/components/virtualization/GridVirtualScrollbar.js +9 -53
  27. package/components/virtualization/GridVirtualScrollbar.mjs +9 -53
  28. package/components/virtualization/GridVirtualScroller.js +12 -0
  29. package/components/virtualization/GridVirtualScroller.mjs +12 -0
  30. package/hooks/features/columnResize/useGridColumnResize.js +56 -2
  31. package/hooks/features/columnResize/useGridColumnResize.mjs +57 -3
  32. package/hooks/features/rows/gridRowsUtils.js +1 -1
  33. package/hooks/features/rows/gridRowsUtils.mjs +1 -1
  34. package/index.js +1 -1
  35. package/index.mjs +1 -1
  36. package/package.json +3 -3
  37. package/components/toolbarV8/ToolbarContext.d.mts +0 -11
  38. package/components/toolbarV8/ToolbarContext.d.ts +0 -11
  39. package/components/toolbarV8/ToolbarContext.js +0 -19
  40. package/components/toolbarV8/ToolbarContext.mjs +0 -12
  41. package/components/toolbarV8/utils.d.mts +0 -5
  42. package/components/toolbarV8/utils.d.ts +0 -5
  43. package/components/toolbarV8/utils.js +0 -23
  44. package/components/toolbarV8/utils.mjs +0 -17
@@ -10,6 +10,7 @@ var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends")
10
10
  var React = _interopRequireWildcard(require("react"));
11
11
  var _styles = require("@mui/material/styles");
12
12
  var _composeClasses = _interopRequireDefault(require("@mui/utils/composeClasses"));
13
+ var _platform = require("@mui/x-internals/platform");
13
14
  var _gridDimensionsSelectors = require("../../hooks/features/dimensions/gridDimensionsSelectors");
14
15
  var _rows = require("../../hooks/features/rows");
15
16
  var _GridScrollArea = require("../GridScrollArea");
@@ -64,6 +65,17 @@ const Scroller = (0, _styles.styled)('div', {
64
65
  '&::-webkit-scrollbar': {
65
66
  display: 'none' /* Safari and Chrome */
66
67
  },
68
+ // [iOS-scrollbar-swap]
69
+ // On iOS, virtual scrollbars do not show a thumb unless the user scrolls the element directly:
70
+ // https://github.com/mui/mui-x/issues/22386
71
+ // So keep this scroller's own native scrollbars and hide the ones in `GridVirtualScrollbar`
72
+ // instead to avoid a duplicate thumb.
73
+ [_platform.iOSMediaQuery]: {
74
+ scrollbarWidth: 'auto',
75
+ '&::-webkit-scrollbar': {
76
+ display: 'block'
77
+ }
78
+ },
67
79
  '@media print': {
68
80
  overflow: 'hidden'
69
81
  },
@@ -2,6 +2,7 @@ import _extends from "@babel/runtime/helpers/esm/extends";
2
2
  import * as React from 'react';
3
3
  import { styled } from '@mui/material/styles';
4
4
  import composeClasses from '@mui/utils/composeClasses';
5
+ import { iOSMediaQuery } from '@mui/x-internals/platform';
5
6
  import { gridHasBottomFillerSelector, gridHasScrollXSelector, gridHasScrollYSelector } from "../../hooks/features/dimensions/gridDimensionsSelectors.mjs";
6
7
  import { gridRowTreeSelector } from "../../hooks/features/rows/index.mjs";
7
8
  import { GridScrollArea } from "../GridScrollArea.mjs";
@@ -56,6 +57,17 @@ const Scroller = styled('div', {
56
57
  '&::-webkit-scrollbar': {
57
58
  display: 'none' /* Safari and Chrome */
58
59
  },
60
+ // [iOS-scrollbar-swap]
61
+ // On iOS, virtual scrollbars do not show a thumb unless the user scrolls the element directly:
62
+ // https://github.com/mui/mui-x/issues/22386
63
+ // So keep this scroller's own native scrollbars and hide the ones in `GridVirtualScrollbar`
64
+ // instead to avoid a duplicate thumb.
65
+ [iOSMediaQuery]: {
66
+ scrollbarWidth: 'auto',
67
+ '&::-webkit-scrollbar': {
68
+ display: 'block'
69
+ }
70
+ },
59
71
  '@media print': {
60
72
  overflow: 'hidden'
61
73
  },
@@ -25,7 +25,30 @@ var _gridColumnsInterfaces = require("../columns/gridColumnsInterfaces");
25
25
  var _columns = require("../columns");
26
26
  var _dimensions = require("../dimensions");
27
27
  var _headerFiltering = require("../headerFiltering");
28
+ var _pagination = require("../pagination");
28
29
  var _columnResizeSelector = require("./columnResizeSelector");
30
+ function isRenderContextReadyForAutosizeOnMount(apiRef) {
31
+ const dimensions = (0, _dimensions.gridDimensionsSelector)(apiRef);
32
+ if (!dimensions.isReady) {
33
+ return false;
34
+ }
35
+ const {
36
+ rows
37
+ } = (0, _pagination.gridVisibleRowsSelector)(apiRef);
38
+ if (rows.length === 0) {
39
+ return true;
40
+ }
41
+ const renderContext = (0, _virtualization.gridRenderContextSelector)(apiRef);
42
+ if (renderContext.lastRowIndex <= renderContext.firstRowIndex) {
43
+ return false;
44
+ }
45
+
46
+ // If all rows fit in the viewport, wait for them all; otherwise we can only measure the rendered rows.
47
+ if (!dimensions.hasScrollY) {
48
+ return renderContext.firstRowIndex === 0 && renderContext.lastRowIndex >= rows.length;
49
+ }
50
+ return true;
51
+ }
29
52
  function trackFinger(event, currentTouchId) {
30
53
  if (currentTouchId !== undefined && event.changedTouches) {
31
54
  for (let i = 0; i < event.changedTouches.length; i += 1) {
@@ -589,10 +612,41 @@ const useGridColumnResize = (apiRef, props) => {
589
612
  React.useEffect(() => stopListening, [stopListening]);
590
613
  (0, _utils.useOnMount)(() => {
591
614
  if (props.autosizeOnMount) {
592
- Promise.resolve().then(() => {
615
+ let frameHandle;
616
+ let unsubscribeStateChange;
617
+ let unsubscribeRenderedRowsIntervalChange;
618
+ const cleanupListeners = () => {
619
+ unsubscribeStateChange?.();
620
+ unsubscribeRenderedRowsIntervalChange?.();
621
+ unsubscribeStateChange = undefined;
622
+ unsubscribeRenderedRowsIntervalChange = undefined;
623
+ };
624
+ const runAutosize = () => {
625
+ frameHandle = undefined;
626
+ cleanupListeners();
593
627
  apiRef.current.autosizeColumns(props.autosizeOptions);
594
- });
628
+ };
629
+ const scheduleAutosize = () => {
630
+ if (frameHandle === undefined) {
631
+ frameHandle = requestAnimationFrame(runAutosize);
632
+ }
633
+ };
634
+ const checkRenderContext = () => {
635
+ if (isRenderContextReadyForAutosizeOnMount(apiRef)) {
636
+ scheduleAutosize();
637
+ }
638
+ };
639
+ unsubscribeStateChange = apiRef.current.subscribeEvent('stateChange', checkRenderContext);
640
+ unsubscribeRenderedRowsIntervalChange = apiRef.current.subscribeEvent('renderedRowsIntervalChange', checkRenderContext);
641
+ checkRenderContext();
642
+ return () => {
643
+ cleanupListeners();
644
+ if (frameHandle !== undefined) {
645
+ cancelAnimationFrame(frameHandle);
646
+ }
647
+ };
595
648
  }
649
+ return undefined;
596
650
  });
597
651
  (0, _utils.useGridNativeEventListener)(apiRef, () => apiRef.current.columnHeadersContainerRef?.current, 'touchstart', handleTouchStart, {
598
652
  passive: true
@@ -10,7 +10,7 @@ import { findGridCellElementsFromCol, findGridElement, findLeftPinnedCellsAfterC
10
10
  import { DEFAULT_GRID_AUTOSIZE_OPTIONS } from "./gridColumnResizeApi.mjs";
11
11
  import { gridClasses } from "../../../constants/gridClasses.mjs";
12
12
  import { useGridEvent, useGridApiMethod, useGridEventPriority, useGridLogger, useGridNativeEventListener, useGridSelector, useOnMount } from "../../utils/index.mjs";
13
- import { gridVirtualizationColumnEnabledSelector } from "../virtualization/index.mjs";
13
+ import { gridRenderContextSelector, gridVirtualizationColumnEnabledSelector } from "../virtualization/index.mjs";
14
14
  import { createControllablePromise } from "../../../utils/createControllablePromise.mjs";
15
15
  import { clamp } from "../../../utils/utils.mjs";
16
16
  import { useTimeout } from "../../utils/useTimeout.mjs";
@@ -18,7 +18,30 @@ import { GridPinnedColumnPosition } from "../columns/gridColumnsInterfaces.mjs";
18
18
  import { gridColumnsStateSelector } from "../columns/index.mjs";
19
19
  import { gridDimensionsSelector } from "../dimensions/index.mjs";
20
20
  import { gridHeaderFilteringEnabledSelector } from "../headerFiltering/index.mjs";
21
+ import { gridVisibleRowsSelector } from "../pagination/index.mjs";
21
22
  import { gridResizingColumnFieldSelector } from "./columnResizeSelector.mjs";
23
+ function isRenderContextReadyForAutosizeOnMount(apiRef) {
24
+ const dimensions = gridDimensionsSelector(apiRef);
25
+ if (!dimensions.isReady) {
26
+ return false;
27
+ }
28
+ const {
29
+ rows
30
+ } = gridVisibleRowsSelector(apiRef);
31
+ if (rows.length === 0) {
32
+ return true;
33
+ }
34
+ const renderContext = gridRenderContextSelector(apiRef);
35
+ if (renderContext.lastRowIndex <= renderContext.firstRowIndex) {
36
+ return false;
37
+ }
38
+
39
+ // If all rows fit in the viewport, wait for them all; otherwise we can only measure the rendered rows.
40
+ if (!dimensions.hasScrollY) {
41
+ return renderContext.firstRowIndex === 0 && renderContext.lastRowIndex >= rows.length;
42
+ }
43
+ return true;
44
+ }
22
45
  function trackFinger(event, currentTouchId) {
23
46
  if (currentTouchId !== undefined && event.changedTouches) {
24
47
  for (let i = 0; i < event.changedTouches.length; i += 1) {
@@ -581,10 +604,41 @@ export const useGridColumnResize = (apiRef, props) => {
581
604
  React.useEffect(() => stopListening, [stopListening]);
582
605
  useOnMount(() => {
583
606
  if (props.autosizeOnMount) {
584
- Promise.resolve().then(() => {
607
+ let frameHandle;
608
+ let unsubscribeStateChange;
609
+ let unsubscribeRenderedRowsIntervalChange;
610
+ const cleanupListeners = () => {
611
+ unsubscribeStateChange?.();
612
+ unsubscribeRenderedRowsIntervalChange?.();
613
+ unsubscribeStateChange = undefined;
614
+ unsubscribeRenderedRowsIntervalChange = undefined;
615
+ };
616
+ const runAutosize = () => {
617
+ frameHandle = undefined;
618
+ cleanupListeners();
585
619
  apiRef.current.autosizeColumns(props.autosizeOptions);
586
- });
620
+ };
621
+ const scheduleAutosize = () => {
622
+ if (frameHandle === undefined) {
623
+ frameHandle = requestAnimationFrame(runAutosize);
624
+ }
625
+ };
626
+ const checkRenderContext = () => {
627
+ if (isRenderContextReadyForAutosizeOnMount(apiRef)) {
628
+ scheduleAutosize();
629
+ }
630
+ };
631
+ unsubscribeStateChange = apiRef.current.subscribeEvent('stateChange', checkRenderContext);
632
+ unsubscribeRenderedRowsIntervalChange = apiRef.current.subscribeEvent('renderedRowsIntervalChange', checkRenderContext);
633
+ checkRenderContext();
634
+ return () => {
635
+ cleanupListeners();
636
+ if (frameHandle !== undefined) {
637
+ cancelAnimationFrame(frameHandle);
638
+ }
639
+ };
587
640
  }
641
+ return undefined;
588
642
  });
589
643
  useGridNativeEventListener(apiRef, () => apiRef.current.columnHeadersContainerRef?.current, 'touchstart', handleTouchStart, {
590
644
  passive: true
@@ -149,7 +149,7 @@ const isAutogeneratedRowNode = rowNode => rowNode.type === 'skeletonRow' || rowN
149
149
  exports.isAutogeneratedRowNode = isAutogeneratedRowNode;
150
150
  const getTreeNodeDescendants = (tree, parentId, skipAutoGeneratedRows, directChildrenOnly) => {
151
151
  const node = tree[parentId];
152
- if (node.type !== 'group') {
152
+ if (node?.type !== 'group') {
153
153
  return [];
154
154
  }
155
155
  const validDescendants = [];
@@ -131,7 +131,7 @@ export const isAutogeneratedRow = row => GRID_ID_AUTOGENERATED in row;
131
131
  export const isAutogeneratedRowNode = rowNode => rowNode.type === 'skeletonRow' || rowNode.type === 'footer' || rowNode.type === 'group' && rowNode.isAutoGenerated || rowNode.type === 'pinnedRow' && rowNode.isAutoGenerated;
132
132
  export const getTreeNodeDescendants = (tree, parentId, skipAutoGeneratedRows, directChildrenOnly) => {
133
133
  const node = tree[parentId];
134
- if (node.type !== 'group') {
134
+ if (node?.type !== 'group') {
135
135
  return [];
136
136
  }
137
137
  const validDescendants = [];
package/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @mui/x-data-grid v8.29.1
2
+ * @mui/x-data-grid v8.29.3
3
3
  *
4
4
  * @license MIT
5
5
  * This source code is licensed under the MIT license found in the
package/index.mjs CHANGED
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @mui/x-data-grid v8.29.1
2
+ * @mui/x-data-grid v8.29.3
3
3
  *
4
4
  * @license MIT
5
5
  * This source code is licensed under the MIT license found in the
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mui/x-data-grid",
3
- "version": "8.29.1",
3
+ "version": "8.29.3",
4
4
  "author": "MUI Team",
5
5
  "description": "The Community plan edition of the MUI X Data Grid components.",
6
6
  "license": "MIT",
@@ -42,8 +42,8 @@
42
42
  "clsx": "^2.1.1",
43
43
  "prop-types": "^15.8.1",
44
44
  "use-sync-external-store": "^1.6.0",
45
- "@mui/x-internals": "8.29.0",
46
- "@mui/x-virtualizer": "0.4.0"
45
+ "@mui/x-internals": "8.29.3",
46
+ "@mui/x-virtualizer": "0.4.2"
47
47
  },
48
48
  "peerDependencies": {
49
49
  "@emotion/react": "^11.9.0",
@@ -1,11 +0,0 @@
1
- import * as React from 'react';
2
- export interface ToolbarContextValue {
3
- focusableItemId: string | null;
4
- registerItem: (id: string, ref: React.RefObject<HTMLButtonElement | null>) => void;
5
- unregisterItem: (id: string) => void;
6
- onItemKeyDown: (event: React.KeyboardEvent<HTMLButtonElement>) => void;
7
- onItemFocus: (id: string) => void;
8
- onItemDisabled: (id: string, disabled: boolean) => void;
9
- }
10
- export declare const ToolbarContext: React.Context<ToolbarContextValue | undefined>;
11
- export declare function useToolbarContext(): ToolbarContextValue;
@@ -1,11 +0,0 @@
1
- import * as React from 'react';
2
- export interface ToolbarContextValue {
3
- focusableItemId: string | null;
4
- registerItem: (id: string, ref: React.RefObject<HTMLButtonElement | null>) => void;
5
- unregisterItem: (id: string) => void;
6
- onItemKeyDown: (event: React.KeyboardEvent<HTMLButtonElement>) => void;
7
- onItemFocus: (id: string) => void;
8
- onItemDisabled: (id: string, disabled: boolean) => void;
9
- }
10
- export declare const ToolbarContext: React.Context<ToolbarContextValue | undefined>;
11
- export declare function useToolbarContext(): ToolbarContextValue;
@@ -1,19 +0,0 @@
1
- "use strict";
2
- 'use client';
3
-
4
- var _interopRequireWildcard = require("@babel/runtime/helpers/interopRequireWildcard").default;
5
- Object.defineProperty(exports, "__esModule", {
6
- value: true
7
- });
8
- exports.ToolbarContext = void 0;
9
- exports.useToolbarContext = useToolbarContext;
10
- var React = _interopRequireWildcard(require("react"));
11
- const ToolbarContext = exports.ToolbarContext = /*#__PURE__*/React.createContext(undefined);
12
- if (process.env.NODE_ENV !== "production") ToolbarContext.displayName = "ToolbarContext";
13
- function useToolbarContext() {
14
- const context = React.useContext(ToolbarContext);
15
- if (context === undefined) {
16
- throw new Error('MUI X: Missing context. Toolbar subcomponents must be placed within a <Toolbar /> component.');
17
- }
18
- return context;
19
- }
@@ -1,12 +0,0 @@
1
- 'use client';
2
-
3
- import * as React from 'react';
4
- export const ToolbarContext = /*#__PURE__*/React.createContext(undefined);
5
- if (process.env.NODE_ENV !== "production") ToolbarContext.displayName = "ToolbarContext";
6
- export function useToolbarContext() {
7
- const context = React.useContext(ToolbarContext);
8
- if (context === undefined) {
9
- throw new Error('MUI X: Missing context. Toolbar subcomponents must be placed within a <Toolbar /> component.');
10
- }
11
- return context;
12
- }
@@ -1,5 +0,0 @@
1
- export declare function sortByDocumentPosition(a: {
2
- ref: React.RefObject<HTMLButtonElement | null>;
3
- }, b: {
4
- ref: React.RefObject<HTMLButtonElement | null>;
5
- }): 0 | 1 | -1;
@@ -1,5 +0,0 @@
1
- export declare function sortByDocumentPosition(a: {
2
- ref: React.RefObject<HTMLButtonElement | null>;
3
- }, b: {
4
- ref: React.RefObject<HTMLButtonElement | null>;
5
- }): 0 | 1 | -1;
@@ -1,23 +0,0 @@
1
- "use strict";
2
-
3
- Object.defineProperty(exports, "__esModule", {
4
- value: true
5
- });
6
- exports.sortByDocumentPosition = sortByDocumentPosition;
7
- /* eslint-disable no-bitwise */
8
- function sortByDocumentPosition(a, b) {
9
- if (!a.ref.current || !b.ref.current) {
10
- return 0;
11
- }
12
- const position = a.ref.current.compareDocumentPosition(b.ref.current);
13
- if (!position) {
14
- return 0;
15
- }
16
- if (position & Node.DOCUMENT_POSITION_FOLLOWING || position & Node.DOCUMENT_POSITION_CONTAINED_BY) {
17
- return -1;
18
- }
19
- if (position & Node.DOCUMENT_POSITION_PRECEDING || position & Node.DOCUMENT_POSITION_CONTAINS) {
20
- return 1;
21
- }
22
- return 0;
23
- }
@@ -1,17 +0,0 @@
1
- /* eslint-disable no-bitwise */
2
- export function sortByDocumentPosition(a, b) {
3
- if (!a.ref.current || !b.ref.current) {
4
- return 0;
5
- }
6
- const position = a.ref.current.compareDocumentPosition(b.ref.current);
7
- if (!position) {
8
- return 0;
9
- }
10
- if (position & Node.DOCUMENT_POSITION_FOLLOWING || position & Node.DOCUMENT_POSITION_CONTAINED_BY) {
11
- return -1;
12
- }
13
- if (position & Node.DOCUMENT_POSITION_PRECEDING || position & Node.DOCUMENT_POSITION_CONTAINS) {
14
- return 1;
15
- }
16
- return 0;
17
- }