Closed ronnyroeller closed 2 years ago
@ronnyroeller thanks for the feature request. It's definitely something we were expecting. We are happy to see it surface :). For the virtualization to work, the grid needs to know the size of all the rows.
Thanks a lot for the quick reply, @oliviertassinari Very helpful!
Virtualization is indeed a good point. I was wondering if setting the maximal row height could help with this. For example, if one knows that a row can be max twice the "normal height" -> it might still be possible to do the required calculations (although with a bit more slack).
Background:
We're currently exploring if we should move from <Table>
to <XGrid>
because the API feels so much nicer and it comes with great (upcoming) features. Hence, I'd really appreciate your guidance where you expect to move with this, considering that dynamic row height is a hard requirement for us.
Hence, is your stance more that dynamic row height isn't going to come - or more that it's coming but we might not be able to use virtualization then (or might pay a heavy performance penalty when using virtualization with dynamic row height).
@ronnyroeller We will definitely implement variable and dynamic row heights. There are two standard use cases (probably not even advanced). A max-height
could work with dynamic row height.
We have no plans to implement a data grid without virtualization.
We managed to implement this with css and it works for us. No need to set row height on the react datagrid element after this:
".MuiDataGrid-row, .MuiDataGrid-root .MuiDataGrid-cell, .rendering-zone": { "max-height": "none !important", }, ".MuiDataGrid-root .MuiDataGrid-window": { position: "relative !important", }, ".MuiDataGrid-root .MuiDataGrid-viewport": { "max-height": "none !important", }, ".MuiDataGrid-root": { height: "auto !important", },
Issue was positioning and max-height. After this, everything is dynamic for row height
I have used react-virtuoso for virtualization with dynamic row heights. It supports dynamic row heights out-of-the-box. It is a less-popular package than react-virtualized or react-window, which as far as I know don't support dynamic heights. It does the job pretty well.
cc @petyosi 🙃
@balihoo-wwilkins Thanks a lot for sharing your workaround! I tried it out but it seems to confuse the scrolling. If there are items that are higher than rowHeight
, it's no longer possible to scroll to the last items on the page.
We will migrate back to <Table>
for now and then try again <XGrid>
/<DataGrid>
once there is progress on this ticket.
For the virtualization to work, the grid needs to know the size of all the rows.
@oliviertassinari You could use the approach Apple does with UIKit, and provide an estimated row height. Then you can continuously update the estimated full height of the table to a more correct value as the user scrolls to reveal more rows (which then report their actual heights). That way you don't need to know the size of all rows up front.
A possible workaround, a popup shown on hover: https://codesandbox.io/s/expandcelldemo-forked-2owvu?file=/src/renderCellExpand.tsx
I have tried to improve the first version built by @dtassone
the only workaround found is that: https://stackoverflow.com/questions/63761910/material-ui-tablecell-cant-force-a-string-to-display-in-a-new-line-like-list-it
i found the workaround with CSS as
MuiDataGrid-viewport,.MuiDataGrid-row,.MuiDataGrid-renderingZone{ max-height: fit-content!important; } .MuiDataGrid-cell{ max-height:fit-content!important; overflow:auto; max-height: inherit; white-space: initial!important; line-height:16px!important; display:flex!important; align-items: center; padding-top: 10px!important; padding-bottom: 10px!important;
div{ //this is for renderCell component wrapped in div max-height: inherit; width: 100%; white-space: initial; line-height:16px; } }
And virtualization works as well as usual.
A possible workaround, a popup shown on hover: https://codesandbox.io/s/expandcelldemo-forked-2owvu?file=/src/renderCellExpand.tsx
I have tried to improve the first version built by @dtassone
Thanks @oliviertassinari - I forked your approach for another UX - https://codesandbox.io/s/expandcelldemo-forked-rs0hx?file=/src/renderCellExpand.tsx - maybe it's helping someone ( https://rs0hx.csb.app/# )
A possible workaround, a popup shown on hover: https://codesandbox.io/s/expandcelldemo-forked-2owvu?file=/src/renderCellExpand.tsx
I have tried to improve the first version built by @dtassone
I feel like this should be part of the API for the DataGrid
A possible workaround, a popup shown on hover: https://codesandbox.io/s/expandcelldemo-forked-2owvu?file=/src/renderCellExpand.tsx
I have tried to improve the first version built by @dtassone
Is there a way to edit that component the same way you edit a normal string cell? Currently you can't edit the cell once it reaches the popup state.
Is there a way to edit that component the same way you edit a normal string cell? Currently you can't edit the cell once it reaches the popup state.
@rafacepsa Yes, you can create a custom edit component based on the Popover: https://material-ui.com/components/data-grid/editing/#custom-edit-component
However, double-clicking the expandable cell doesn't switch to the edit mode because it's rendered inside a Portal. There're two ways to overcome this problem:
Has this been implemented or is there a workaround for this?
Has this been implemented or is there a workaround for this?
Hey @vincent-paing, I was able to successfully work around the limitation with the following code (excerpted for brevity):
import React, { Component } from 'react';
import { withStyles } from '@material-ui/styles';
import { XGrid, LicenseInfo } from '@material-ui/x-grid';
...
const styles = theme => ({
dataGrid: {
minHeight: '132px',
'& .MuiDataGrid-dataContainer, & .MuiDataGrid-viewport': {
minWidth: 'auto!important'
},
'& .MuiDataGrid-viewport': {
width: 'fit-content',
maxWidth: 'none!important',
minWidth: '100%!important'
},
'& .MuiDataGrid-viewport, & .MuiDataGrid-renderingZone, & .MuiDataGrid-row': {
maxHeight: 'fit-content!important',
},
'& .MuiDataGrid-renderingZone': {
transform: 'none!important',
marginRight: '-16px'
},
'& .MuiDataGrid-columnHeaderTitle, & .MuiDataGrid-cell': {
textOverflow: 'unset',
whiteSpace: 'normal',
lineHeight: '1.2!important',
maxHeight: 'fit-content!important',
minHeight: 'auto!important',
height: 'auto',
display: 'flex',
alignItems: 'center',
alignSelf: 'stretch',
'& > div': {
maxHeight: 'inherit',
width: '100%',
whiteSpace: 'initial',
lineHeight: '1'
}
},
'& .MuiDataGrid-columnHeader > div': {
height: '100%'
},
'& .MuiDataGrid-columnHeaderWrapper': {
maxHeight: 'none!important',
flex: '1 0 auto',
},
'& .MuiDataGrid-row .MuiDataGrid-columnsContainer': {
maxHeight: 'none!important'
},
'& .MuiDataGrid-cell': {
overflowWrap: 'anywhere',
padding: '0',
'&--textRight div': {
textAlign: 'right',
justifyContent: 'flex-end'
},
'&:last-of-type > div': {
paddingRight: theme.spacing(3)
},
'& > div': {
padding: '0.75em',
display: 'flex',
alignSelf: 'stretch',
alignItems: 'center'
}
}
}
});
...
class DataGridComponent extends Component {
constructor(props) {
super(props);
}
...
render() {
const { classes } = this.props;
return (
<XGrid
className={classes.dataGrid}
rows={this.state.tableRows}
columns={this.state.tableColumns}
columnBuffer={this.state.tableColumns.length || 5}
autoHeight={false}
rowHeight={0}
headerHeight={100}
scrollbarSize={16}
disableExtendRowFullWidth={false}
disableColumnMenu={true}
disableColumnResize={true}
disableColumnReorder={true}
hideFooter={true}
pagination={false}
hideFooterPagination={true}
autoPageSize={false}
/>
);
}
}
export default withStyles(styles, {withTheme: true})(DataGridComponent);
NOTE: There may be some unnecessary styles in there (I was modifying the table in a couple different ways, like width), but this should be good enough to get you pointed in the right direction.
Hope this helps! 🌞
@gnowland autoHeight
is in the MIT version, I assume all the developers can rely on this workaround. Thanks for sharing.
A possible workaround, a popup shown on hover: https://codesandbox.io/s/expandcelldemo-forked-2owvu?file=/src/renderCellExpand.tsx
I have tried to improve the first version built by @dtassone
I am trying to implement the workaround provided @oliviertassinari, however I am getting an error saying that 'isOverflown' is not exported from "@material-ui/data-grid"
@cristianocaon https://mui.com/components/data-grid/columns/#render-cell for the updated demo.
@cristianocaon https://mui.com/components/data-grid/columns/#render-cell for the updated demo.
still can't see the isOverflown
property in the demo. How can we access this property in datagrid-pro?
@kguptaaa You have to scroll to "Expand cell renderer".
We got the cell to grow in height when required to. But, in any case Table height seems to be automatically hard-coded and calculated by the number of shown rows. So, only adding an scrollbar to the table works.
Is it possible to change this behaviour?
Table height seems to be automatically hard-coded and calculated by the number of shown rows
If you have autoHeight: true
yes, the Table takes the height needed to render all the rows
But by default it is the other way around. The Table takes the size of its parent and we deduce the amount of row to render based on that height.
Hard coding the height of the Table allows us to virtualize the rendering. Making the virtualization works with dynamic row height is a complicated task. We have planned to spend time on it (thus this issue) but it will probably not be any time soon.
First, we want to achieve #438 where the height of each row can be different, but will not change in time. This is needed for #211 and probably other features and should be easier to achieve.
Thanks @oliviertassinari - I forked your approach for another UX - https://codesandbox.io/s/expandcelldemo-forked-rs0hx?file=/src/renderCellExpand.tsx - maybe it's helping someone ( https://rs0hx.csb.app/# )
@hmaack thank you. Certainly helped me. Enhanced it a bit further by removing the Link and replacing with:
<IconButton aria-label="expand" color="primary" onClick={handleClick}>
<ExpandMoreIcon />
</IconButton>
for a clean UI:
'.MuiDataGrid-cell': { wordBreak: 'break-all', maxHeight: 'fit-content!important', overflow: 'auto', whiteSpace: 'initial!important', lineHeight: '16px!important', display: 'flex!important', alignItems: 'center', paddingTop: '10px!important', paddingBottom: '10px!important' }, '.MuiDataGrid-cell div': { maxHeight: 'inherit', width: '100%', whiteSpace: 'initial', lineHeight: '16px' }
i used the following CSS it works for the work with underscore and spaces
I have the same problem and I'd like to make the things clear.
Dear @oliviertassinari, @flaviendelangle - are there any plans to fix this issue and if yes, when can we expect resolving this issue?
@DanailH should be able to release #3218 soon.
What is your use-case for dynamic row height ? (= rows with non-predictable height)
@flaviendelangle I'm also waiting for this fix, my use case is that the data in the cell for a particular column is variable in length. It can have 20 words or 100 words and so I want the row's height to adjust such that the whole text can be viewed (and ideally edited) easily. Right now I'm using the popover solution recommended above, but its really hard to make it work for when editing on the cell is enabled.
I have applied this solution, and It worked for me:
You need to set rowHeight to show the sroll bar:
Hi bro, I have not encountered this case, do you have any solution?
Best Regard!
*Tho Pham (Thomas Pham) Phạm Kim Thọ GIS Application Developement Mobile phone: 0907095100 Email: tho.phamkim@ @.**>gmail.com http://gmail.com
Vào Th 5, 6 thg 1, 2022 vào lúc 03:33 kguptaaa @.***> đã viết:
@phamkimtho https://github.com/phamkimtho your solution works. However, do you know how I can maintain the styling when its in edit mode (onCellEditStart) ? I notice that in edit mode the text < span > changes to an < input > and so the styling for the text is lost. As a result, its hard to see the full text at once.
Here's a gif showing the issue: [image: ezgif com-gif-maker] https://user-images.githubusercontent.com/80909021/148285194-4b9e80c6-e9b8-48b5-b6d8-1fa7e97312da.gif
— Reply to this email directly, view it on GitHub https://github.com/mui-org/material-ui-x/issues/417#issuecomment-1006056984, or unsubscribe https://github.com/notifications/unsubscribe-auth/AJF5ITIOLOA5KI226XCUSI3UUSTJZANCNFSM4SKQZIAA . Triage notifications on the go with GitHub Mobile for iOS https://apps.apple.com/app/apple-store/id1477376905?ct=notification-email&mt=8&pt=524675 or Android https://play.google.com/store/apps/details?id=com.github.android&referrer=utm_campaign%3Dnotification-email%26utm_medium%3Demail%26utm_source%3Dgithub.
You are receiving this because you were mentioned.Message ID: @.***>
.MuiDataGrid-viewport,
.MuiDataGrid-row,
.MuiDataGrid-renderingZone {
max-height: fit-content !important;
}
.MuiDataGrid-cell {
max-height: fit-content !important;
overflow: auto;
white-space: initial !important;
line-height: 16px !important;
display: flex !important;
align-items: center;
padding-top: 10px !important;
padding-bottom: 10px !important;
}
Adding this CSS to index.css
worked for me, without using any other configuration.
Thanks @oliviertassinari - I forked your approach for another UX - https://codesandbox.io/s/expandcelldemo-forked-rs0hx?file=/src/renderCellExpand.tsx - maybe it's helping someone ( https://rs0hx.csb.app/# )
@hmaack thank you. Certainly helped me. Enhanced it a bit further by removing the Link and replacing with:
<IconButton aria-label="expand" color="primary" onClick={handleClick}> <ExpandMoreIcon /> </IconButton>
for a clean UI:
Could you please provide a codesnabox
.MuiDataGrid-viewport, .MuiDataGrid-row, .MuiDataGrid-renderingZone { max-height: fit-content !important; }
The CSS fix doesn't seem to work on Safari (iPhone or Mac). The rows end up broken, with different cells somehow getting different height. Works well for Chrome and Firefox... max-heght: none seems to work on Chrome, Firefox and Safari.
.MuiDataGrid-viewport,
.MuiDataGrid-row,
.MuiDataGrid-renderingZone {
max-height: none !important;
}
.MuiDataGrid-cell {
max-height: none !important;
overflow: auto;
white-space: initial !important;
line-height: 16px !important;
display: flex !important;
align-items: center;
padding-top: 10px !important;
padding-bottom: 10px !important;
}
Just wanted to mention that this CSS from above *mostly works for me. But doesn't work with Column Pinning. The cells in the Pinned Column take on their own height which breaks the whole grid
/* Allows the MUI grid rows to expand to child height */
.MuiDataGrid-viewport,
.MuiDataGrid-row,
.MuiDataGrid-renderingZone {
max-height: fit-content !important;
}
/* Allows the MUI grid rows to expand to child height */
.MuiDataGrid-cell {
max-height: fit-content !important;
overflow: auto;
white-space: initial !important;
line-height: 16px !important;
display: flex !important;
align-items: center;
padding-top: 10px !important;
padding-bottom: 10px !important;
}
@blazinaj Did you find any workaround for pinned columns?
Hey all, we're working in adding support for row height based on the content in #4859. We would love to have feedback from the community on how to make this feature perfect.
Documentation: https://deploy-preview-4859--material-ui-x.netlify.app/x/react-data-grid/rows/#dynamic-row-height
I am getting this error Type '() => string' is not assignable to type '(params: GridRowHeightParams) => GridRowHeightReturnValue'. Type 'string' is not assignable to type 'GridRowHeightReturnValue'.
with my code and the default code.
My code :
import * as React from "react";
import { DataGrid, GridColDef } from "@mui/x-data-grid";
import { TypographyColor } from "../../utils/constants";
interface CustomizedDataGridProps {
rows: { id: number, name: string, to: string, calldata: any }[];
columns: GridColDef[]
rowHeight: number
}
export function CustomizedDataGrid(props: CustomizedDataGridProps) {
return (
<span onClick={(event: any) => event.stopPropagation()} style={{ width: "100%" }}>
<DataGrid
rows={props.rows}
columns={props.columns}
disableSelectionOnClick
sx={{ color: TypographyColor }}
autoHeight
hideFooter
rowHeight={props.rowHeight}
getRowHeight={() => 'auto'}
/>
</span>
);
}
Default code: https://deploy-preview-4859--material-ui-x.netlify.app/x/react-data-grid/rows/#dynamic-row-height
@d-s-i are you able to reproduce it in a codesandbox with your TS config ?
The following should work, but I would have expected TS to work without the explicit casting
getRowHeight={() => 'auto' as const}
I'm trying to use the new dynamic row height functionality in Material UI. When I add the line "getRowHeight={() => 'auto'}" as mentioned here, I get the warning in the console and grid is not displayed properly. There are missing rows and dynamic row height does not work. I understand that I'm passing a string where there should be a number but I can't find where or how. If I comment the line "getRowHeight={() => 'auto'}", no warnings and works normally but no dynamic row height of course. My code and warnings are below.
Failed prop type: Invalid prop rowHeight
of type string
supplied to GridRow
, expected number
.
Failed prop type: Invalid prop height
of type string
supplied to GridCell
, expected number
.
NaN
is an invalid value for the height
css style property.
My code is:
`import {useState} from 'react'
import React from 'react'
import { DataGrid, GridToolbarExport, GridToolbarContainer } from '@mui/x-data-grid'
function ExportButton() { //CSV Export button
return (
<GridToolbarContainer>
<GridToolbarExport />
</GridToolbarContainer>
);
}
export default function projectsPage() {
const [projects, setProjects] = useState([])
const fetchProjects = async () =>{
const response = await fetch('/api/projects')
const data = await response.json()
setProjects(data)
// console.log(data) just to check we receive the data correctly.
}
const columns = [
{field: "id", headerName: "Project ID", width:100},
{field: "owner", headerName:"Owner ID", width: 100},
{field: "projectname", headerName:"Project Name", width: 100}
];
const rows = projects.map((project)=>({
id: project._id,
owner: project.owner,
projectname: project.projectname
}))
return (
<>
<button onClick={fetchProjects}> Load Projects </button>
{
<div style={{ height:400, width: 900}}>
<DataGrid // Creating datagrid.
rows={rows}
columns={columns}
getRowHeight={() => "auto"}
sx={{
'& .MuiDataGrid-cell': {
py: '8px',
},
}}
components={{
Toolbar: GridToolbarExport}}
options={{ //Adding filtering features
filtering:true}}
/>
</div>
}
</>
)
}`
My test data is very basic like this https://i.stack.imgur.com/R6HC3.jpg
@AhenkEU The dynamic row height was not released in the NPM package yet. To experiment with it, you need to use the preview package available by clicking the "Open in CodeSandbox" button in any demo in https://deploy-preview-4859--material-ui-x.netlify.app/x/react-data-grid/rows/#dynamic-row-height
@AhenkEU The dynamic row height was not released in the NPM package yet. To experiment with it, you need to use the preview package available by clicking the "Open in CodeSandbox" button in any demo in https://deploy-preview-4859--material-ui-x.netlify.app/x/react-data-grid/rows/#dynamic-row-height
Oh, I thought it is live and useable already. Thank you :)
Is it possible to maintain the dynamic row height when editable
is enabled on the column. Right now, it compresses to single line input field.
@krishnagupta21 By default, no. The dynamic row height always uses the row content so it will reduce the height to the height of the <input>
. You can try to create a custom edit component using a textarea
and add rows=5
to make it taller. However, if you want a built-in solution please upvote https://github.com/mui/mui-x/issues/2851
Will this support a tree view with pinned columns? Scrolling on expanded grouped rows is a bit janky. The mouse is not always positioned over the scroll bar and it studders a bit when dragging the scroll bar up.
<DataGridPro treeData disableColumnMenu getRowId={(row) => row.Id} rows={rows} columns={columns} getRowHeight={() => "auto"} getTreeDataPath={getTreeDataPath} initialState={{ pinnedColumns: { left: ["__tree_data_group__"] } }} />
Here is another example using the premium grid and grouping. Try expanding a few nodes and scroll down and up. https://codesandbox.io/s/dynamicrowheightgrid-material-demo-forked-tctdic
Indeed there is something wrong with the scrolling there, it stops scrolling from time to time ...
@masull The dynamic row height uses a lazy approach, so it only knows the true height after rendering the row. To calculate the size of the scrollbar, before a row is rendered, we use an estimation. The inconsistency might be explained because the true height is too different from the estimation. You can try to tweak the getEstimatedRowHeight
prop to be closer to the final content. The studders is from https://github.com/mui/mui-x/issues/5006
@masull The dynamic row height uses a lazy approach, so it only knows the true height after rendering the row. To calculate the size of the scrollbar, before a row is rendered, we use an estimation. The inconsistency might be explained because the true height is too different from the estimation. You can try to tweak the
getEstimatedRowHeight
prop to be closer to the final content. The studders is from #5006
Okay, thanks, I'll give it a try.
I have tried various methods, the new, getRowHeight={() => 'auto'} works with pinned columns, but there is a performance penalty when vertically scrolling on say, 30+ treeData rows. The css posted above is promising (performance is fine) except it does not work for pinned columns.
I have applied this solution, and It worked for me:
You need to set rowHeight to show the sroll bar:
Fixed . Thanks man
Summary 💡
I want to show text in one of the cells. Text can have different length and might span multiple lines. Today, data-grid seem to allow only a fixed
rowHeight
. I'd like to set this to dynamic - so the row is as high as the content requires. Alternatively, for my use case also something likemaxRowHeight
would work: I would define the maximal height of a row and the grid uses up to themaxRowHeight
- but less if there is less content.Examples 🌈
Motivation 🔦
I want to show in one of the columns text that the user entered (or a snippet of it).