Min width fit content MUI Data Grid flex column

Viewed 109

I'm using the MUI Data Grid (MIT licensed version).

I have my columns set to flex, as I want them to fill up the available width. However, I'd like the table to overflow (requiring scrolling) if it's resized too small.

For example, for the email column, I'd like it to never be of less width than the longest email (so the text never has ...), but have it expand its width so that it fills available space.

I know I can set a number minWidth for columns, but can't set auto or anything similar. Is there some way I can make it so, if there is some data in a column that is too large, the Data Grid will overflow?

4 Answers

This is an open issue with MUI, Though you can use a wrapper to make it work.

From community answers (credits to @alxndrsn) on this issue, you can use something like this to implement the desired functionality.

import React, { Component } from 'react';
import _ from 'lodash';

import { DataGrid } from '@mui/x-data-grid';
import CircularProgress from '@material-ui/core/CircularProgress';
import Grid from '@material-ui/core/Grid';

export default class StretchyDataGrid extends Component {
  constructor(props) {
    super(props);

    this.ref = React.createRef();

    const { columns } = props;
    this.state = { mappedColumns:_.clone(columns) };
  }

  autoSizeColumns = () => {
    const domRows = [ ...this.ref.current?.querySelectorAll('.MuiDataGrid-row') ];
    const domReady = (this.props.rows?.length === 0) || domRows.length;

    if(!domReady) {
      setTimeout(this.autoSizeColumns);
      return;
    }

    this.setState(previousState => {
      const mappedColumns = _.clone(previousState.mappedColumns);

      mappedColumns
        .forEach((col, idx) => {
          const maxContentWidth = domRows
              .reduce((previousMax, dR) => Math.max(previousMax, dR.childNodes[idx].scrollWidth), 0);
          if(maxContentWidth < this.ref.current.clientWidth / mappedColumns.length) {
            col.width = maxContentWidth;
            delete col.flex;
          } else {
            delete col.width;
            col.flex = 1;
          }
        });

      return { mappedColumns, resized:true };
    });
  }

  render() {
    const { mappedColumns, resized } = this.state;
    const { columns, ...props } = this.props;

    return (
      <>
        {!resized &&
          <Grid container alignItems="center" justifyContent="center" style={{height:'100%', position:'absolute', opacity:0.8, backgroundColor:'white', textAlign:'center', zIndex:1}}>
            <Grid item xs={12}>
              <CircularProgress/>
            </Grid>
          </Grid>
        }
        <DataGrid
          ref={this.ref}
          onResize={this.autoSizeColumns}
          columns={mappedColumns}
          {...props /* eslint-disable-line react/jsx-props-no-spreading */}
        />
      </>
    );
  }
}
const columns = [
  {
    field: "firstName",
    headerName: "First name",
    width: "max-content",
    editable: true
  }
]

u need to set width:"max-content" ,its working properly .

but i am not sure , because i dont know your exact table structure and style properties.

According to this github thread, it is still in their development roadmap. But there are some community code in the replies which you might want to check out such as this one.

to show full text without using min-width and also avoid ... think just add two CSS line then it will work properly

flex: 1 0 auto; // flex gro 1 and item teks its space full
white-space: pre; // text will never break into 2 line

for more details please add some photos or more details it will be better for us to understand.

Related