diff --git a/packages/x-data-grid/src/hooks/core/useGridRefs.ts b/packages/x-data-grid/src/hooks/core/useGridRefs.ts index 815c7f56e328..98e266fda316 100644 --- a/packages/x-data-grid/src/hooks/core/useGridRefs.ts +++ b/packages/x-data-grid/src/hooks/core/useGridRefs.ts @@ -5,7 +5,7 @@ export const useGridRefs = ( apiRef: React.MutableRefObject, ) => { const rootElementRef = React.useRef(null); - const mainElementRef = React.useRef(null); + const mainElementRef = React.useRef(null); const virtualScrollerRef = React.useRef(null); const virtualScrollbarVerticalRef = React.useRef(null); const virtualScrollbarHorizontalRef = React.useRef(null); diff --git a/packages/x-data-grid/src/hooks/features/virtualization/useGridVirtualScroller.tsx b/packages/x-data-grid/src/hooks/features/virtualization/useGridVirtualScroller.tsx index 86435660917e..bc635380def6 100644 --- a/packages/x-data-grid/src/hooks/features/virtualization/useGridVirtualScroller.tsx +++ b/packages/x-data-grid/src/hooks/features/virtualization/useGridVirtualScroller.tsx @@ -6,8 +6,8 @@ import { } from '@mui/utils'; import useLazyRef from '@mui/utils/useLazyRef'; import useTimeout from '@mui/utils/useTimeout'; -import { useResizeObserver } from '@mui/x-internals/useResizeObserver'; import { useRtl } from '@mui/system/RtlProvider'; +import reactMajor from '@mui/x-internals/reactMajor'; import type { GridPrivateApiCommunity } from '../../../models/api/gridApiCommunity'; import { useGridPrivateApiContext } from '../../utils/useGridPrivateApiContext'; import { useGridRootProps } from '../../utils/useGridRootProps'; @@ -135,7 +135,57 @@ export const useGridVirtualScroller = () => { const columnsTotalWidth = dimensions.columnsTotalWidth; const hasColSpan = useGridSelector(apiRef, gridHasColSpanSelector); - useResizeObserver(mainRef, () => apiRef.current.resize()); + const mainRefCallback = React.useCallback( + (node: HTMLDivElement | null) => { + mainRef.current = node; + + if (!node) { + return undefined; + } + + const initialRect = node.getBoundingClientRect(); + let lastSize = { + width: initialRect.width, + height: initialRect.height, + }; + + apiRef.current.publishEvent('resize', lastSize); + + if (typeof ResizeObserver === 'undefined') { + return undefined; + } + + const observer = new ResizeObserver((entries) => { + const entry = entries[0]; + if (!entry) { + return; + } + + const newSize = { + width: entry.contentRect.width, + height: entry.contentRect.height, + }; + + if (newSize.width === lastSize.width && newSize.height === lastSize.height) { + return; + } + + apiRef.current.publishEvent('resize', newSize); + lastSize = newSize; + }); + + observer.observe(node); + + if (reactMajor >= 19) { + return () => { + mainRef.current = null; + observer.disconnect(); + }; + } + return undefined; + }, + [apiRef, mainRef], + ); /* * Scroll context logic @@ -549,11 +599,6 @@ export const useGridVirtualScroller = () => { apiRef.current.publishEvent('virtualScrollerContentSizeChange'); }, [apiRef, contentSize]); - useEnhancedEffect(() => { - // FIXME: Is this really necessary? - apiRef.current.resize(); - }, [apiRef, rowsMeta.currentPageTotalHeight]); - useEnhancedEffect(() => { // TODO a scroll reset should not be necessary if (enabledForColumns) { @@ -596,7 +641,7 @@ export const useGridVirtualScroller = () => { setPanels, getRows, getContainerProps: () => ({ - ref: mainRef, + ref: mainRefCallback, }), getScrollerProps: () => ({ ref: scrollerRef, diff --git a/packages/x-data-grid/src/models/api/gridCoreApi.ts b/packages/x-data-grid/src/models/api/gridCoreApi.ts index 1dfaf2834b59..c5d7be49b1fd 100644 --- a/packages/x-data-grid/src/models/api/gridCoreApi.ts +++ b/packages/x-data-grid/src/models/api/gridCoreApi.ts @@ -67,7 +67,7 @@ export interface GridCorePrivateApi< /** * The React ref of the grid main container div element. */ - mainElementRef: React.RefObject; + mainElementRef: React.MutableRefObject; /** * The React ref of the grid's virtual scroller container element. */ diff --git a/packages/x-internals/src/reactMajor.ts b/packages/x-internals/src/reactMajor.ts new file mode 100644 index 000000000000..2028b806152d --- /dev/null +++ b/packages/x-internals/src/reactMajor.ts @@ -0,0 +1,3 @@ +import * as React from 'react'; + +export default parseInt(React.version, 10);