@mui/x-data-grid
Version:
The Community plan edition of the MUI X Data Grid components.
231 lines (223 loc) • 11.1 kB
JavaScript
var _interopRequireWildcard = require("@babel/runtime/helpers/interopRequireWildcard").default;
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault").default;
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.useGridVirtualizer = useGridVirtualizer;
var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends"));
var React = _interopRequireWildcard(require("react"));
var _useEventCallback = _interopRequireDefault(require("@mui/utils/useEventCallback"));
var _RtlProvider = require("@mui/system/RtlProvider");
var _math = require("@mui/x-internals/math");
var _store = require("@mui/x-internals/store");
var _xVirtualizer = require("@mui/x-virtualizer");
var _useFirstRender = require("../utils/useFirstRender");
var _createSelector = require("../../utils/createSelector");
var _useGridSelector = require("../utils/useGridSelector");
var _gridDimensionsSelectors = require("../features/dimensions/gridDimensionsSelectors");
var _density = require("../features/density");
var _gridColumnsSelector = require("../features/columns/gridColumnsSelector");
var _gridRowsSelector = require("../features/rows/gridRowsSelector");
var _useGridVisibleRows = require("../utils/useGridVisibleRows");
var _pagination = require("../features/pagination");
var _gridFocusedVirtualCellSelector = require("../features/virtualization/gridFocusedVirtualCellSelector");
var _rowSelection = require("../features/rowSelection");
var _dataGridPropsDefaultValues = require("../../constants/dataGridPropsDefaultValues");
var _gridRowsUtils = require("../features/rows/gridRowsUtils");
var _gridColumnsUtils = require("../features/columns/gridColumnsUtils");
var _jsxRuntime = require("react/jsx-runtime");
function identity(x) {
return x;
}
const columnsTotalWidthSelector = (0, _createSelector.createSelector)(_gridColumnsSelector.gridVisibleColumnDefinitionsSelector, _gridColumnsSelector.gridColumnPositionsSelector, (visibleColumns, positions) => {
const colCount = visibleColumns.length;
if (colCount === 0) {
return 0;
}
return (0, _math.roundToDecimalPlaces)(positions[colCount - 1] + visibleColumns[colCount - 1].computedWidth, 1);
});
/**
* Virtualizer setup
*/
function useGridVirtualizer(apiRef, rootProps) {
const isRtl = (0, _RtlProvider.useRtl)();
const {
listView
} = rootProps;
const visibleColumns = (0, _useGridSelector.useGridSelector)(apiRef, _gridColumnsSelector.gridVisibleColumnDefinitionsSelector);
const pinnedRows = (0, _useGridSelector.useGridSelector)(apiRef, _gridRowsSelector.gridPinnedRowsSelector);
const pinnedColumns = (0, _gridColumnsSelector.gridVisiblePinnedColumnDefinitionsSelector)(apiRef);
const rowSelectionManager = (0, _useGridSelector.useGridSelector)(apiRef, _rowSelection.gridRowSelectionManagerSelector);
const isRowSelected = id => rowSelectionManager.has(id) && apiRef.current.isRowSelectable(id);
const currentPage = (0, _useGridVisibleRows.useGridVisibleRows)(apiRef);
const hasColSpan = (0, _useGridSelector.useGridSelector)(apiRef, _gridColumnsSelector.gridHasColSpanSelector);
/* TODO: extract dimensions code */
const contentHeight = (0, _useGridSelector.useGridSelector)(apiRef, _gridDimensionsSelectors.gridContentHeightSelector);
const verticalScrollbarWidth = (0, _useGridSelector.useGridSelector)(apiRef, _gridDimensionsSelectors.gridVerticalScrollbarWidthSelector);
const hasFiller = (0, _useGridSelector.useGridSelector)(apiRef, _gridDimensionsSelectors.gridHasFillerSelector);
const {
autoHeight
} = rootProps;
const scrollReset = listView;
// <DIMENSIONS>
const density = (0, _useGridSelector.useGridSelector)(apiRef, _density.gridDensityFactorSelector);
const baseRowHeight = (0, _gridRowsUtils.getValidRowHeight)(rootProps.rowHeight, _dataGridPropsDefaultValues.DATA_GRID_PROPS_DEFAULT_VALUES.rowHeight, _gridRowsUtils.rowHeightWarning);
const rowHeight = Math.floor(baseRowHeight * density);
const headerHeight = Math.floor(rootProps.columnHeaderHeight * density);
const groupHeaderHeight = Math.floor((rootProps.columnGroupHeaderHeight ?? rootProps.columnHeaderHeight) * density);
const headerFilterHeight = Math.floor((rootProps.headerFilterHeight ?? rootProps.columnHeaderHeight) * density);
const columnsTotalWidth = (0, _useGridSelector.useGridSelector)(apiRef, columnsTotalWidthSelector);
const headersTotalHeight = (0, _gridColumnsUtils.getTotalHeaderHeight)(apiRef, rootProps);
const leftPinnedWidth = pinnedColumns.left.reduce((w, col) => w + col.computedWidth, 0);
const rightPinnedWidth = pinnedColumns.right.reduce((w, col) => w + col.computedWidth, 0);
const dimensions = {
rowHeight,
headerHeight,
groupHeaderHeight,
headerFilterHeight,
columnsTotalWidth,
headersTotalHeight,
leftPinnedWidth,
rightPinnedWidth
};
// </DIMENSIONS>
// <ROWS_META>
const dataRowCount = (0, _useGridSelector.useGridSelector)(apiRef, _gridRowsSelector.gridRowCountSelector);
const pagination = (0, _useGridSelector.useGridSelector)(apiRef, _pagination.gridPaginationSelector);
const rowCount = Math.min(pagination.enabled ? pagination.paginationModel.pageSize : dataRowCount, dataRowCount);
const {
getRowHeight,
getEstimatedRowHeight,
getRowSpacing
} = rootProps;
// </ROWS_META>
const focusedVirtualCell = (0, _useGridSelector.useGridSelector)(apiRef, _gridFocusedVirtualCellSelector.gridFocusedVirtualCellSelector);
const virtualizer = (0, _xVirtualizer.useVirtualizer)({
scrollbarSize: rootProps.scrollbarSize,
dimensions,
initialState: {
scroll: rootProps.initialState?.scroll,
dimensions: apiRef.current.state.dimensions,
rowSpanning: apiRef.current.state.rowSpanning,
virtualization: apiRef.current.state.virtualization
},
isRtl,
rows: currentPage.rows,
range: currentPage.range,
rowIdToIndexMap: currentPage.rowIdToIndexMap,
rowCount,
columns: visibleColumns,
pinnedRows,
pinnedColumns,
refs: {
container: apiRef.current.mainElementRef,
scroller: apiRef.current.virtualScrollerRef,
scrollbarVertical: apiRef.current.virtualScrollbarVerticalRef,
scrollbarHorizontal: apiRef.current.virtualScrollbarHorizontalRef
},
hasColSpan,
contentHeight,
minimalContentHeight: _gridRowsUtils.minimalContentHeight,
autoHeight,
getRowHeight: React.useMemo(() => {
if (!getRowHeight) {
return undefined;
}
return rowEntry => getRowHeight((0, _extends2.default)({}, rowEntry, {
densityFactor: density
}));
}, [getRowHeight, density]),
getEstimatedRowHeight: React.useMemo(() => getEstimatedRowHeight ? rowEntry => getEstimatedRowHeight((0, _extends2.default)({}, rowEntry, {
densityFactor: density
})) : undefined, [getEstimatedRowHeight, density]),
getRowSpacing: React.useMemo(() => getRowSpacing ? (rowEntry, visibility) => getRowSpacing((0, _extends2.default)({}, rowEntry, visibility, {
indexRelativeToCurrentPage: apiRef.current.getRowIndexRelativeToVisibleRows(rowEntry.id)
})) : undefined, [apiRef, getRowSpacing]),
applyRowHeight: (0, _useEventCallback.default)((entry, row) => apiRef.current.unstable_applyPipeProcessors('rowHeight', entry, row)),
virtualizeColumnsWithAutoRowHeight: rootProps.virtualizeColumnsWithAutoRowHeight,
focusedVirtualCell: (0, _useEventCallback.default)(() => focusedVirtualCell),
rowBufferPx: rootProps.rowBufferPx,
columnBufferPx: rootProps.columnBufferPx,
resizeThrottleMs: rootProps.resizeThrottleMs,
onResize: (0, _useEventCallback.default)(size => apiRef.current.publishEvent('resize', size)),
onWheel: (0, _useEventCallback.default)(event => {
apiRef.current.publishEvent('virtualScrollerWheel', {}, event);
}),
onTouchMove: (0, _useEventCallback.default)(event => {
apiRef.current.publishEvent('virtualScrollerTouchMove', {}, event);
}),
onRenderContextChange: (0, _useEventCallback.default)(nextRenderContext => {
apiRef.current.publishEvent('renderedRowsIntervalChange', nextRenderContext);
}),
onScrollChange: (scrollPosition, nextRenderContext) => {
apiRef.current.publishEvent('scrollPositionChange', {
top: scrollPosition.top,
left: scrollPosition.left,
renderContext: nextRenderContext
});
},
scrollReset,
getColspan: (rowId, column) => {
if (typeof column.colSpan === 'function') {
const row = apiRef.current.getRow(rowId);
const value = apiRef.current.getRowValue(row, column);
return column.colSpan(value, row, column, apiRef) ?? 0;
}
return column.colSpan ?? 0;
},
renderRow: params => /*#__PURE__*/(0, _jsxRuntime.jsx)(rootProps.slots.row, (0, _extends2.default)({
row: params.model,
rowId: params.id,
index: params.rowIndex,
selected: isRowSelected(params.id),
offsetLeft: params.offsetLeft,
columnsTotalWidth: columnsTotalWidth,
rowHeight: params.baseRowHeight,
pinnedColumns: pinnedColumns,
visibleColumns: params.columns,
firstColumnIndex: params.firstColumnIndex,
lastColumnIndex: params.lastColumnIndex,
focusedColumnIndex: params.focusedColumnIndex,
isFirstVisible: params.isFirstVisible,
isLastVisible: params.isLastVisible,
isNotVisible: params.isVirtualFocusRow,
showBottomBorder: params.showBottomBorder,
scrollbarWidth: verticalScrollbarWidth,
gridHasFiller: hasFiller
}, rootProps.slotProps?.row), params.id),
renderInfiniteLoadingTrigger: id => apiRef.current.getInfiniteLoadingTriggerElement?.({
lastRowId: id
})
});
// HACK: Keep the grid's store in sync with the virtualizer store. We set up the
// subscription in the render phase rather than in an effect because other grid
// initialization code runs between those two moments.
//
// TODO(v9): Remove this
(0, _useFirstRender.useFirstRender)(() => {
apiRef.current.store.state.dimensions = virtualizer.store.state.dimensions;
apiRef.current.store.state.rowsMeta = virtualizer.store.state.rowsMeta;
apiRef.current.store.state.virtualization = virtualizer.store.state.virtualization;
});
(0, _store.useStoreEffect)(virtualizer.store, identity, (_, state) => {
if (state.dimensions !== apiRef.current.state.dimensions) {
apiRef.current.setState(gridState => (0, _extends2.default)({}, gridState, {
dimensions: state.dimensions
}));
}
if (state.rowsMeta !== apiRef.current.state.rowsMeta) {
apiRef.current.setState(gridState => (0, _extends2.default)({}, gridState, {
rowsMeta: state.rowsMeta
}));
}
if (state.virtualization !== apiRef.current.state.virtualization) {
apiRef.current.setState(gridState => (0, _extends2.default)({}, gridState, {
virtualization: state.virtualization
}));
}
});
apiRef.current.register('private', {
virtualizer
});
}
;