Skip to content

Commit

Permalink
add useGridAutoHeight hook
Browse files Browse the repository at this point in the history
  • Loading branch information
cherniavskii committed Jun 8, 2023
1 parent f37aaaf commit ca1b2ef
Show file tree
Hide file tree
Showing 11 changed files with 186 additions and 3 deletions.
44 changes: 44 additions & 0 deletions docs/data/data-grid/layout/AutoHeightGridMaxHeight.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import * as React from 'react';
import Button from '@mui/material/Button';
import Box from '@mui/material/Box';
import Stack from '@mui/material/Stack';
import { DataGrid, useGridAutoHeight, useGridApiRef } from '@mui/x-data-grid';
import { useDemoData } from '@mui/x-data-grid-generator';

const maxHeight = 500;

export default function AutoHeightGridMaxHeight() {
const [nbRows, setNbRows] = React.useState(3);
const removeRow = () => setNbRows((x) => Math.max(0, x - 1));
const addRow = () => setNbRows((x) => Math.min(100, x + 1));

const { data } = useDemoData({
dataSet: 'Commodity',
rowLength: 100,
maxColumns: 6,
});

const apiRef = useGridApiRef();
const autoHeight = useGridAutoHeight(apiRef, maxHeight);

return (
<Box sx={{ width: '100%' }}>
<Stack direction="row" spacing={1} sx={{ mb: 1 }}>
<Button size="small" onClick={removeRow}>
Remove a row
</Button>
<Button size="small" onClick={addRow}>
Add a row
</Button>
</Stack>
<div style={{ height: autoHeight ? 'auto' : maxHeight }}>
<DataGrid
apiRef={apiRef}
autoHeight={autoHeight}
{...data}
rows={data.rows.slice(0, nbRows)}
/>
</div>
</Box>
);
}
44 changes: 44 additions & 0 deletions docs/data/data-grid/layout/AutoHeightGridMaxHeight.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import * as React from 'react';
import Button from '@mui/material/Button';
import Box from '@mui/material/Box';
import Stack from '@mui/material/Stack';
import { DataGrid, useGridAutoHeight, useGridApiRef } from '@mui/x-data-grid';
import { useDemoData } from '@mui/x-data-grid-generator';

const maxHeight = 500;

export default function AutoHeightGridMaxHeight() {
const [nbRows, setNbRows] = React.useState(3);
const removeRow = () => setNbRows((x) => Math.max(0, x - 1));
const addRow = () => setNbRows((x) => Math.min(100, x + 1));

const { data } = useDemoData({
dataSet: 'Commodity',
rowLength: 100,
maxColumns: 6,
});

const apiRef = useGridApiRef();
const autoHeight = useGridAutoHeight(apiRef, maxHeight);

return (
<Box sx={{ width: '100%' }}>
<Stack direction="row" spacing={1} sx={{ mb: 1 }}>
<Button size="small" onClick={removeRow}>
Remove a row
</Button>
<Button size="small" onClick={addRow}>
Add a row
</Button>
</Stack>
<div style={{ height: autoHeight ? 'auto' : maxHeight }}>
<DataGrid
apiRef={apiRef}
autoHeight={autoHeight}
{...data}
rows={data.rows.slice(0, nbRows)}
/>
</div>
</Box>
);
}
16 changes: 16 additions & 0 deletions docs/data/data-grid/layout/AutoHeightGridMaxHeight.tsx.preview
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<Stack direction="row" spacing={1} sx={{ mb: 1 }}>
<Button size="small" onClick={removeRow}>
Remove a row
</Button>
<Button size="small" onClick={addRow}>
Add a row
</Button>
</Stack>
<div style={{ height: autoHeight ? 'auto' : maxHeight }}>
<DataGrid
apiRef={apiRef}
autoHeight={autoHeight}
{...data}
rows={data.rows.slice(0, nbRows)}
/>
</div>
28 changes: 28 additions & 0 deletions docs/data/data-grid/layout/layout.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,34 @@ This is not recommended for large datasets as row virtualization will not be abl

{{"demo": "AutoHeightGrid.js", "bg": "inline"}}

### Auto height with max height limit

You can set maximum height when using `autoHeight` to limit the height of the grid.
To do so, use the `useGridAutoHeight` hook:

```tsx
const maxHeight = 500;
function Component() {
const apiRef = useGridApiRef();
const autoHeight = useGridAutoHeight(apiRef, maxHeight);

return (
<div style={{ height: autoHeight ? 'auto' : maxHeight }}>
<DataGrid apiRef={apiRef} autoHeight={autoHeight} />
</div>
);
}
```

:::warning
Note that `maxHeight` supports numeric values only.
:::

In the demo below, the `autoHeight` is enabled, but when the grid height exceeds 500 pixels,
the `autoHeight` is disabled and the grid height is limited to 500 pixels.

{{"demo": "AutoHeightGridMaxHeight.js", "bg": "inline"}}

## API

- [DataGrid](/x/api/data-grid/data-grid/)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -630,8 +630,8 @@ export const useGridVirtualScroller = (props: UseGridVirtualScrollerProps) => {
return size;
}, [rootRef, columnsTotalWidth, rowsMeta.currentPageTotalHeight, needsHorizontalScrollbar]);

React.useEffect(() => {
apiRef.current.publishEvent('virtualScrollerContentSizeChange');
useEnhancedEffect(() => {
apiRef.current.publishEvent('virtualScrollerContentSizeChange', contentSize);
}, [apiRef, contentSize]);

if (rootProps.autoHeight && currentPage.rows.length === 0) {
Expand Down
1 change: 1 addition & 0 deletions packages/grid/x-data-grid/src/hooks/utils/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,4 @@ export * from './useGridLogger';
export * from './useGridSelector';
export * from './useGridNativeEventListener';
export * from './useFirstRender';
export * from './useGridAutoHeight';
45 changes: 45 additions & 0 deletions packages/grid/x-data-grid/src/hooks/utils/useGridAutoHeight.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import * as React from 'react';
import { GridApiCommon } from '@mui/x-data-grid-pro';
import { gridClasses } from '../../constants/gridClasses';

export const useGridAutoHeight = (
apiRef: React.MutableRefObject<GridApiCommon>,
maxHeight: number,
) => {
const [autoHeight, setAutoHeight] = React.useState(true);
const autoHeightRef = React.useRef<boolean>(true);
autoHeightRef.current = autoHeight;

React.useEffect(() => {
return apiRef.current.subscribeEvent('virtualScrollerContentSizeChange', (params) => {
if (!apiRef.current) {
return;
}
const rootEl = apiRef.current.rootElementRef?.current;
const virtualScrollerEl = rootEl?.querySelector<HTMLElement>(
`.${gridClasses.virtualScroller}`,
);
if (!rootEl || !virtualScrollerEl) {
return;
}
const topPinnedRowsHeight =
virtualScrollerEl.querySelector<HTMLElement>(`:scope > .${gridClasses['pinnedRows--top']}`)
?.offsetHeight || 0;
const bottomPinnedRowsHeight =
virtualScrollerEl.querySelector<HTMLElement>(
`:scope > .${gridClasses['pinnedRows--bottom']}`,
)?.offsetHeight || 0;

const headerAndFooterHeight = rootEl.offsetHeight - virtualScrollerEl.offsetHeight;
const maxVirtualScrollerContentHeight =
maxHeight - headerAndFooterHeight - topPinnedRowsHeight - bottomPinnedRowsHeight;
if (params.height >= maxVirtualScrollerContentHeight) {
setAutoHeight(false);
} else {
setAutoHeight(true);
}
});
}, [apiRef, autoHeight, maxHeight]);

return autoHeight;
};
Original file line number Diff line number Diff line change
Expand Up @@ -517,7 +517,9 @@ export interface GridEventLookup
* Fired when the content size used by the `GridVirtualScroller` changes.
* @ignore - do not document.
*/
virtualScrollerContentSizeChange: {};
virtualScrollerContentSizeChange: {
params: { height: number; width: number | string; minHeight: string };
};
/**
* Fired when the content is scrolled by the mouse wheel.
* It's attached to the "mousewheel" event.
Expand Down
1 change: 1 addition & 0 deletions scripts/x-data-grid-premium.exports.json
Original file line number Diff line number Diff line change
Expand Up @@ -632,6 +632,7 @@
{ "name": "useGridApiMethod", "kind": "Function" },
{ "name": "useGridApiOptionHandler", "kind": "Function" },
{ "name": "useGridApiRef", "kind": "Variable" },
{ "name": "useGridAutoHeight", "kind": "Variable" },
{ "name": "useGridLogger", "kind": "Function" },
{ "name": "useGridNativeEventListener", "kind": "Variable" },
{ "name": "useGridRootProps", "kind": "Variable" },
Expand Down
1 change: 1 addition & 0 deletions scripts/x-data-grid-pro.exports.json
Original file line number Diff line number Diff line change
Expand Up @@ -583,6 +583,7 @@
{ "name": "useGridApiMethod", "kind": "Function" },
{ "name": "useGridApiOptionHandler", "kind": "Function" },
{ "name": "useGridApiRef", "kind": "Variable" },
{ "name": "useGridAutoHeight", "kind": "Variable" },
{ "name": "useGridLogger", "kind": "Function" },
{ "name": "useGridNativeEventListener", "kind": "Variable" },
{ "name": "useGridRootProps", "kind": "Variable" },
Expand Down
1 change: 1 addition & 0 deletions scripts/x-data-grid.exports.json
Original file line number Diff line number Diff line change
Expand Up @@ -536,6 +536,7 @@
{ "name": "useGridApiMethod", "kind": "Function" },
{ "name": "useGridApiOptionHandler", "kind": "Function" },
{ "name": "useGridApiRef", "kind": "Variable" },
{ "name": "useGridAutoHeight", "kind": "Variable" },
{ "name": "useGridLogger", "kind": "Function" },
{ "name": "useGridNativeEventListener", "kind": "Variable" },
{ "name": "useGridRootProps", "kind": "Variable" },
Expand Down

0 comments on commit ca1b2ef

Please sign in to comment.