@mui/x-data-grid-pro
Version:
The Pro plan edition of the MUI X Data Grid components.
91 lines (88 loc) • 3.79 kB
JavaScript
;
'use client';
var _interopRequireWildcard = require("@babel/runtime/helpers/interopRequireWildcard").default;
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.GridMultiSelectMeasurer = GridMultiSelectMeasurer;
var React = _interopRequireWildcard(require("react"));
var _useResizeObserver = require("@mui/x-internals/useResizeObserver");
var _xDataGrid = require("@mui/x-data-grid");
var _useGridPrivateApiContext = require("../../hooks/utils/useGridPrivateApiContext");
var _GridMultiSelectChips = require("./GridMultiSelectChips");
var _gridMultiSelectCache = require("../../hooks/features/multiSelect/gridMultiSelectCache");
var _multiSelectCellUtils = require("../../utils/multiSelectCellUtils");
var _jsxRuntime = require("react/jsx-runtime");
const SAMPLE_LABELS = ['+9', '+99', '+999'];
const HIDDEN_STYLE = {
position: 'absolute',
top: 0,
left: 0,
width: 'auto',
height: 'auto',
visibility: 'hidden',
pointerEvents: 'none'
};
/**
* Hidden helper mounted once per grid (inside `<GridRoot>`) that publishes the measured `+N`
* overflow chip widths and row gap to `apiRef.caches.multiSelect`. The measured chip comes from
* the grid-level `baseChip` slot and the shared chip-row styling, so the metrics are identical
* for every multiSelect column — one measurement per grid is enough. Renders nothing when the
* grid has no multiSelect column. `ResizeObserver` re-fires when font / chip styles shift; the
* cache dedupes equal metrics so subscribed cells only re-render on real change.
*/
function GridMultiSelectMeasurer() {
const rootProps = (0, _xDataGrid.useGridRootProps)();
const apiRef = (0, _useGridPrivateApiContext.useGridPrivateApiContext)();
const columns = (0, _xDataGrid.useGridSelector)(apiRef, _xDataGrid.gridColumnDefinitionsSelector);
const hasMultiSelectColumn = columns.some(column => column.type === 'multiSelect');
const ownerState = rootProps;
const containerRef = React.useRef(null);
const chipsRef = React.useRef([]);
// The measurer is the sole writer of the overflow metrics, so it owns the cache lifecycle.
if (!apiRef.current.caches.multiSelect) {
apiRef.current.caches.multiSelect = new _gridMultiSelectCache.GridMultiSelectCache();
}
React.useEffect(() => {
const api = apiRef.current;
return () => {
api.caches.multiSelect?.teardown();
};
}, [apiRef]);
const measure = React.useCallback(() => {
const container = containerRef.current;
const cache = apiRef.current.caches.multiSelect;
if (!container || !cache || chipsRef.current.some(el => !el)) {
return;
}
const overflowChipWidths = chipsRef.current.map(el => el.getBoundingClientRect().width);
const computedGap = parseFloat(window.getComputedStyle(container).gap);
const gap = Number.isFinite(computedGap) ? computedGap : _multiSelectCellUtils.DEFAULT_GAP;
cache.setOverflowMetrics({
overflowChipWidths,
gap
});
}, [apiRef]);
React.useLayoutEffect(measure, [measure]);
// The flex container resizes whenever any chip resizes, so observing the container
// catches font/theme shifts without registering a listener per chip.
(0, _useResizeObserver.useResizeObserver)(containerRef, measure);
const BaseChip = rootProps.slots.baseChip;
if (!hasMultiSelectColumn) {
return null;
}
return /*#__PURE__*/(0, _jsxRuntime.jsx)(_GridMultiSelectChips.MultiSelectChipsRoot, {
ref: containerRef,
ownerState: ownerState,
"aria-hidden": true,
style: HIDDEN_STYLE,
children: SAMPLE_LABELS.map((label, index) => /*#__PURE__*/(0, _jsxRuntime.jsx)(BaseChip, {
ref: el => {
chipsRef.current[index] = el;
},
label: label,
size: "small",
variant: "outlined"
}, label))
});
}