UNPKG

@mui/x-data-grid-pro

Version:

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

203 lines (200 loc) 8.62 kB
"use strict"; 'use client'; var _interopRequireWildcard = require("@babel/runtime/helpers/interopRequireWildcard").default; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault").default; Object.defineProperty(exports, "__esModule", { value: true }); exports.useGridDetailPanel = exports.detailPanelStateInitializer = void 0; var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends")); var React = _interopRequireWildcard(require("react")); var _xDataGrid = require("@mui/x-data-grid"); var _internals = require("@mui/x-data-grid/internals"); var _gridDetailPanelToggleColDef = require("./gridDetailPanelToggleColDef"); var _gridDetailPanelSelector = require("./gridDetailPanelSelector"); const emptySet = new Set(); const detailPanelStateInitializer = (state, props) => { return (0, _extends2.default)({}, state, { detailPanel: { heightCache: {}, expandedRowIds: props.detailPanelExpandedRowIds ?? props.initialState?.detailPanel?.expandedRowIds ?? emptySet } }); }; exports.detailPanelStateInitializer = detailPanelStateInitializer; function cacheContentAndHeight(apiRef, getDetailPanelContent, getDetailPanelHeight, previousHeightCache) { if (typeof getDetailPanelContent !== 'function') { return {}; } // TODO change to lazy approach using a Proxy // only call getDetailPanelContent when asked for an id const rowIds = (0, _xDataGrid.gridDataRowIdsSelector)(apiRef); const contentCache = {}; const heightCache = {}; for (let i = 0; i < rowIds.length; i += 1) { const id = rowIds[i]; const params = apiRef.current.getRowParams(id); const content = getDetailPanelContent(params); contentCache[id] = content; if (content == null) { continue; } const height = getDetailPanelHeight(params); const autoHeight = height === 'auto'; heightCache[id] = { autoHeight, height: autoHeight ? previousHeightCache[id]?.height : height }; } return { contentCache, heightCache }; } const useGridDetailPanel = (apiRef, props) => { const contentCache = (0, _xDataGrid.useGridSelector)(apiRef, _gridDetailPanelSelector.gridDetailPanelExpandedRowsContentCacheSelector); const handleCellClick = React.useCallback((params, event) => { if (params.field !== _gridDetailPanelToggleColDef.GRID_DETAIL_PANEL_TOGGLE_FIELD || props.getDetailPanelContent == null) { return; } const content = contentCache[params.id]; if (! /*#__PURE__*/React.isValidElement(content)) { return; } // Ignore if the user didn't click specifically in the "i" button if (event.target === event.currentTarget) { return; } apiRef.current.toggleDetailPanel(params.id); }, [apiRef, contentCache, props.getDetailPanelContent]); const handleCellKeyDown = React.useCallback((params, event) => { if (props.getDetailPanelContent == null) { return; } if (params.field === _gridDetailPanelToggleColDef.GRID_DETAIL_PANEL_TOGGLE_FIELD && event.key === ' ') { apiRef.current.toggleDetailPanel(params.id); } }, [apiRef, props.getDetailPanelContent]); (0, _xDataGrid.useGridEvent)(apiRef, 'cellClick', handleCellClick); (0, _xDataGrid.useGridEvent)(apiRef, 'cellKeyDown', handleCellKeyDown); apiRef.current.registerControlState({ stateId: 'detailPanels', propModel: props.detailPanelExpandedRowIds, propOnChange: props.onDetailPanelExpandedRowIdsChange, stateSelector: _gridDetailPanelSelector.gridDetailPanelExpandedRowIdsSelector, changeEvent: 'detailPanelsExpandedRowIdsChange' }); const toggleDetailPanel = React.useCallback(id => { if (props.getDetailPanelContent == null) { return; } const content = contentCache[id]; if (! /*#__PURE__*/React.isValidElement(content)) { return; } const ids = apiRef.current.getExpandedDetailPanels(); const newIds = new Set(ids); if (ids.has(id)) { newIds.delete(id); } else { newIds.add(id); } apiRef.current.setExpandedDetailPanels(newIds); }, [apiRef, contentCache, props.getDetailPanelContent]); const getExpandedDetailPanels = React.useCallback(() => (0, _gridDetailPanelSelector.gridDetailPanelExpandedRowIdsSelector)(apiRef), [apiRef]); const setExpandedDetailPanels = React.useCallback(ids => { apiRef.current.setState(state => { return (0, _extends2.default)({}, state, { detailPanel: (0, _extends2.default)({}, state.detailPanel, { expandedRowIds: ids }) }); }); apiRef.current.requestPipeProcessorsApplication('rowHeight'); }, [apiRef]); const storeDetailPanelHeight = React.useCallback((id, height) => { const heightCache = (0, _gridDetailPanelSelector.gridDetailPanelRawHeightCacheSelector)(apiRef); if (!heightCache[id] || heightCache[id].height === height) { return; } apiRef.current.setState(state => { return (0, _extends2.default)({}, state, { detailPanel: (0, _extends2.default)({}, state.detailPanel, { heightCache: (0, _extends2.default)({}, heightCache, { [id]: (0, _extends2.default)({}, heightCache[id], { height }) }) }) }); }); apiRef.current.requestPipeProcessorsApplication('rowHeight'); }, [apiRef]); const detailPanelPubicApi = { toggleDetailPanel, getExpandedDetailPanels, setExpandedDetailPanels }; const detailPanelPrivateApi = { storeDetailPanelHeight }; (0, _xDataGrid.useGridApiMethod)(apiRef, detailPanelPubicApi, 'public'); (0, _xDataGrid.useGridApiMethod)(apiRef, detailPanelPrivateApi, 'private'); React.useEffect(() => { if (props.detailPanelExpandedRowIds) { const currentModel = (0, _gridDetailPanelSelector.gridDetailPanelExpandedRowIdsSelector)(apiRef); if (currentModel !== props.detailPanelExpandedRowIds) { apiRef.current.setExpandedDetailPanels(props.detailPanelExpandedRowIds); } } }, [apiRef, props.detailPanelExpandedRowIds]); const updateCaches = React.useCallback(() => { if (!props.getDetailPanelContent) { return; } apiRef.current.setState(state => { return (0, _extends2.default)({}, state, { detailPanel: (0, _extends2.default)({}, state.detailPanel, cacheContentAndHeight(apiRef, props.getDetailPanelContent, props.getDetailPanelHeight, state.detailPanel.heightCache)) }); }); }, [apiRef, props.getDetailPanelContent, props.getDetailPanelHeight]); (0, _xDataGrid.useGridEvent)(apiRef, 'sortedRowsSet', updateCaches); const previousGetDetailPanelContentProp = React.useRef(undefined); const previousGetDetailPanelHeightProp = React.useRef(undefined); const updateCachesIfNeeded = React.useCallback(() => { if (props.getDetailPanelContent === previousGetDetailPanelContentProp.current && props.getDetailPanelHeight === previousGetDetailPanelHeightProp.current) { return; } apiRef.current.setState(state => { return (0, _extends2.default)({}, state, { detailPanel: (0, _extends2.default)({}, state.detailPanel, cacheContentAndHeight(apiRef, props.getDetailPanelContent, props.getDetailPanelHeight, state.detailPanel.heightCache)) }); }); previousGetDetailPanelContentProp.current = props.getDetailPanelContent; previousGetDetailPanelHeightProp.current = props.getDetailPanelHeight; }, [apiRef, props.getDetailPanelContent, props.getDetailPanelHeight]); const addDetailHeight = React.useCallback((initialValue, row) => { const expandedRowIds = (0, _gridDetailPanelSelector.gridDetailPanelExpandedRowIdsSelector)(apiRef); if (!expandedRowIds || !expandedRowIds.has(row.id)) { initialValue.detail = 0; return initialValue; } updateCachesIfNeeded(); const heightCache = (0, _gridDetailPanelSelector.gridDetailPanelRawHeightCacheSelector)(apiRef); initialValue.detail = heightCache[row.id]?.height ?? 0; // Fallback to zero because the cache might not be ready yet (for example page was changed) return initialValue; }, [apiRef, updateCachesIfNeeded]); const enabled = props.getDetailPanelContent !== undefined; (0, _internals.useGridRegisterPipeProcessor)(apiRef, 'rowHeight', addDetailHeight, enabled); const isFirstRender = React.useRef(true); if (isFirstRender.current) { updateCachesIfNeeded(); } React.useEffect(() => { if (!isFirstRender.current) { updateCachesIfNeeded(); } isFirstRender.current = false; }, [apiRef, updateCachesIfNeeded]); }; exports.useGridDetailPanel = useGridDetailPanel;