Reputation: 13283
I'm using the MUI DataGrid
component, and the behavior I hope to have is that:
flex: 1
) and the extra rows scroll inside the table.I can achieve each of these behaviors, but only one at a time.
If I use the autoHeight
property on the DataGrid
, then the table will be as small as it can be. BUT it will also be as big as it can be, so with a large number of rows the container scrolls the entire table, rather than the rows scrolling within the table.
If I don't use autoHeight
, and wrap the DataGrid
in a container with flex: 1
, then the table will grow to fill the available space and the rows will scroll within the table. BUT a table with only a few rows will also grow to fill its container, so that there is empty space under the rows (above the footer, "Table rows: #")
You can see the situation in this screenshot, showing the exact same page, with different data.
I've tried what feels like every permutation of heights and flexes under the sun. For example:
maxHeight
(and .MuiDataGrid-main { overflow: scroll; }
) allows few-rows to be small, and many-rows to be not too small, but obviously any discrete maxHeight
, be it px or %, is not the flex
ible layout I'm going for.flex-grow: 0
on the rows container within the table (.MuiDataGrid-main
) just makes the rows disappear since they then shrink to a height of 0.The code for the component:
const S = {
Wrapper: styled.div`
width: 100%;
display: flex;
flex: 1;
background: white;
border: solid thick red;
`,
DataGrid: styled(DataGridPro)`
&& {
.MuiDataGrid-main {
//overflow: scroll;
//flex-grow: 0;
}
background: lightgreen;
font-size: 14px;
}
`,
};
type Props = {
columns: ReadonlyColumns;
rows: AnyObject[];
filterModel?: GridFilterModel;
} & Omit<DataGridProps, 'columns'>;
const DataTable: React.FC<Props> = ({
columns = [],
rows = [],
filterModel,
className,
...props
}) => {
const memoizedColumns = useMemo(
() =>
columns.map(col => ({
headerClassName: 'columnHeader',
flex: 1, // all columns expand to fill width
...col, // but could override that behavior
})),
[columns],
);
return (
<S.Wrapper className={className}>
<S.DataGrid
// autoHeight
rows={rows}
columns={memoizedColumns}
filterModel={filterModel}
{...props}
/>
</S.Wrapper>
);
};
Upvotes: 10
Views: 24173
Reputation: 27485
Below solved the issue:
<DataGrid getRowHeight={() => 'auto'} />
Source:
https://mui.com/x/react-data-grid/row-height/#dynamic-row-height
Upvotes: 3
Reputation: 111
Using a combination of autoHeight
and pageSize
will create a table whose height is only as big as needed for the current number of rows as long as the number of rows is <= pageSize
. Additional rows will be added to a new page.
<DataGrid
rows={rows}
columns={columns}
pageSize={20} //integer value representing max number of rows
autoHeight={true}
/>
Upvotes: 11
Reputation: 1674
I had a similar issue days ago and I solved recalculating the row height every time a new item was added to my row.
getRowHeight={(props: GridRowHeightParams) => {
const serviceRowHeight = 45 // <-- default height, if I have no data for the row
const addServiceBtnHeight = 45 // <-- a component that's always on the row
const height = props.model?.services // services is each dynamic item for my row, so you should access like props.yourObj
? props.model.services.length * serviceRowHeight + addServiceBtnHeight
: 115
return height < 115 ? 115 : height // final height to be returned
}}
Upvotes: 0