Skip to content

Commit

Permalink
refactor: use ResizeObserver properly
Browse files Browse the repository at this point in the history
  • Loading branch information
romgrk committed Oct 12, 2024
1 parent 4bc5acc commit b4083c4
Show file tree
Hide file tree
Showing 2 changed files with 41 additions and 2 deletions.
39 changes: 37 additions & 2 deletions packages/x-data-grid/src/hooks/features/rows/useGridRowsMeta.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import * as React from 'react';
import { unstable_debounce as debounce } from '@mui/utils';
import useLazyRef from '@mui/utils/useLazyRef';
import { GridPrivateApiCommunity } from '../../../models/api/gridApiCommunity';
import { GridRowsMetaApi, GridRowsMetaPrivateApi } from '../../../models/api/gridRowsMetaApi';
import { DataGridProcessedProps } from '../../../models/props/DataGridProps';
Expand All @@ -18,6 +19,16 @@ import { DATA_GRID_PROPS_DEFAULT_VALUES } from '../../../DataGrid/useDataGridPro

// TODO: I think the row heights can now be encoded as a single `size` instead of `sizes.baseXxxx`

// HACK: Minimal shim to get jsdom to work.
const ResizeObserverImpl = (
typeof ResizeObserver !== 'undefined'
? ResizeObserver
: class ResizeObserver {
observe() {}
unobserve() {}
}
) as typeof ResizeObserver;

export const rowsMetaStateInitializer: GridStateInitializer = (state) => ({
...state,
rowsMeta: {
Expand Down Expand Up @@ -100,6 +111,29 @@ export const useGridRowsMeta = (
);
const rowHeight = Math.floor(validRowHeight * densityFactor);

const resizeObserver = useLazyRef(
() =>
new ResizeObserverImpl((entries) => {
for (let i = 0; i < entries.length; i++) {
const entry = entries[i];
const height =
entry.borderBoxSize && entry.borderBoxSize.length > 0
? entry.borderBoxSize[0].blockSize
: entry.contentRect.height;
const rowId = (entry.target as any).__mui_id;
apiRef.current.unstable_storeRowHeightMeasurement(rowId, height);
}
}),
).current;

const observeRow: GridRowsMetaPrivateApi['observeRow'] = (element, rowId) => {
(element as any).__mui_id = rowId;

resizeObserver.observe(element);

return () => resizeObserver.unobserve(element);
};

const hydrateRowsMeta = React.useCallback(() => {
hasRowWithAutoHeight.current = false;

Expand Down Expand Up @@ -257,7 +291,7 @@ export const useGridRowsMeta = (
GridRowsMetaApi['unstable_storeRowHeightMeasurement']
>(
(id, height) => {
if (!rowsHeightLookup.current[id] || !rowsHeightLookup.current[id].autoHeight) {
if (!rowsHeightLookup.current[id]?.autoHeight) {
return;
}

Expand Down Expand Up @@ -315,8 +349,9 @@ export const useGridRowsMeta = (
};

const rowsMetaPrivateApi: GridRowsMetaPrivateApi = {
getLastMeasuredRowIndex,
observeRow,
rowHasAutoHeight,
getLastMeasuredRowIndex,
};

useGridApiMethod(apiRef, rowsMetaApi, 'public');
Expand Down
4 changes: 4 additions & 0 deletions packages/x-data-grid/src/models/api/gridRowsMetaApi.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,10 @@ export interface GridRowsMetaApi {
}

export interface GridRowsMetaPrivateApi {
/**
* Observe row for 'auto' height changes.
*/
observeRow: (element: Element, rowId: GridRowId) => ReturnType<React.EffectCallback>;
/**
* Determines if the height of a row is "auto".
* @param {GridRowId} id The id of the row.
Expand Down

0 comments on commit b4083c4

Please sign in to comment.