UNPKG

@mui/x-data-grid-pro

Version:

The Pro plan edition of the MUI X Data Grid components.

105 lines (101 loc) 4.46 kB
"use strict"; 'use client'; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault").default; var _interopRequireWildcard = require("@babel/runtime/helpers/interopRequireWildcard").default; Object.defineProperty(exports, "__esModule", { value: true }); exports.useGridInfiniteLoadingIntersection = void 0; var React = _interopRequireWildcard(require("react")); var _xDataGrid = require("@mui/x-data-grid"); var _internals = require("@mui/x-data-grid/internals"); var _useEventCallback = _interopRequireDefault(require("@mui/utils/useEventCallback")); var _system = require("@mui/system"); var _jsxRuntime = require("react/jsx-runtime"); const InfiniteLoadingTriggerElement = (0, _system.styled)('div')({ position: 'sticky', left: 0, width: 0, height: 0 }); /** * @requires useGridDimensions (method) - can be after */ const useGridInfiniteLoadingIntersection = (apiRef, props) => { const isReady = (0, _xDataGrid.useGridSelector)(apiRef, _xDataGrid.gridDimensionsSelector).isReady; const observer = React.useRef(null); const updateTargetTimeout = (0, _internals.useTimeout)(); const triggerElement = React.useRef(null); const isEnabledClientSide = props.rowsLoadingMode === 'client' && !!props.onRowsScrollEnd; const isEnabledServerSide = props.dataSource && props.lazyLoading; const isEnabled = isEnabledClientSide || isEnabledServerSide; const handleIntersectionChange = (0, _useEventCallback.default)(([entry]) => { const currentRatio = entry.intersectionRatio; const isIntersecting = entry.isIntersecting; if (isIntersecting && currentRatio === 1) { observer.current?.disconnect(); // do not observe this node anymore triggerElement.current = null; apiRef.current.publishEvent('rowsScrollEndIntersection'); } }); React.useEffect(() => { const virtualScroller = apiRef.current.virtualScrollerRef.current; if (!isEnabled || !isReady || !virtualScroller) { return; } observer.current?.disconnect(); const horizontalScrollbarHeight = (0, _internals.gridHorizontalScrollbarHeightSelector)(apiRef); const marginBottom = props.scrollEndThreshold - horizontalScrollbarHeight; observer.current = new IntersectionObserver(handleIntersectionChange, { threshold: 1, root: virtualScroller, rootMargin: `0px 0px ${marginBottom}px 0px` }); if (triggerElement.current) { observer.current.observe(triggerElement.current); } }, [apiRef, isReady, handleIntersectionChange, isEnabled, props.scrollEndThreshold]); const updateTarget = node => { if (triggerElement.current !== node) { observer.current?.disconnect(); triggerElement.current = node; if (triggerElement.current) { observer.current?.observe(triggerElement.current); } } }; const triggerRef = React.useCallback(node => { // Prevent the infite loading working in combination with lazy loading if (!isEnabled) { return; } // If the user scrolls through the grid too fast it might happen that the observer is connected to the trigger element // that will be intersecting the root inside the same render cycle (but not intersecting at the time of the connection). // This will cause the observer to not call the callback with `isIntersecting` set to `true`. // https://www.w3.org/TR/intersection-observer/#event-loop // Delaying the connection to the next cycle helps since the observer will always call the callback the first time it is connected. // https://developer.mozilla.org/en-US/docs/Web/API/IntersectionObserver/observe // Related to // https://github.com/mui/mui-x/issues/14116 updateTargetTimeout.start(0, () => updateTarget(node)); }, [isEnabled, updateTargetTimeout]); const getInfiniteLoadingTriggerElement = React.useCallback(({ lastRowId }) => { if (!isEnabled) { return null; } return /*#__PURE__*/(0, _jsxRuntime.jsx)(InfiniteLoadingTriggerElement, { ref: triggerRef // Force rerender on last row change to start observing the new trigger , role: "presentation" }, `trigger-${lastRowId}`); }, [isEnabled, triggerRef]); const infiniteLoaderPrivateApi = { getInfiniteLoadingTriggerElement }; (0, _xDataGrid.useGridApiMethod)(apiRef, infiniteLoaderPrivateApi, 'private'); }; exports.useGridInfiniteLoadingIntersection = useGridInfiniteLoadingIntersection;