Home > Software design >  How to have a free width column based on the row width in the table?
How to have a free width column based on the row width in the table?

Time:09-28

and I have the following code:

return (
  <Box sx={{ height: 400 }}>
    <DataGrid columns={columns} rows={rows} />
  </Box>
)

and I am having the table getting rendered as: enter image description here

I want the column of the email to take the width of the widest row cell automatically, so I want the table to render as follows:

enter image description here

My colums and rows look simply as follows:

const columns = [ { field: "firstName" }, { field: "lastName" }, ...etc ]
const rows = [ 
   { firstName: "Camil Pasa Sokak", lastName: "In The Village", ...etc },
   ... etc
]

How to do it in MUI x (community table, the free one)?

I want the column of the email to take the width of the widest row cell automatically

  • please note: since the table is wide, it will automatically show you a scrollbar (x and y scrollbars). I want to keep this functionality, I want to keep these scrollbars (from the x and y) I don't want to disable them.

Here's a sandbox instnce: https://codesandbox.io/s/strange-newton-z6pwj4?file=/src/App.js

CodePudding user response:

Looking at the docs for the datatable component you are using, it's not super clear the best way to go about it. The crux of the problem is that this is a div flexbox table and not a true html table. As such, cells within a single column are not really "bound" to each other the same way as a regular html table.

There is a page which addresses column dimensions, but I could not find a satisfactory solution there. I was particularly disappointed that maxWidth seems to do nothing. The closest I got was setting a fixed column width, but I don't think that's what you want:

const columns = [{
  field: "email", width: 300,
}]

So then I moved on to their styling cells page, which allows you to have much more control over styling, but this still doesn't work because one flex cell does not affect the size of all flex cells in a column - each row has a different sized cell based on the size of the email address.

const columns = [{
  field: "email", cellClassName: "foobar",
}]

<DataGrid columns={columns} rows={rows} sx={{
  "& .foobar": {
    maxWidth: "300px !important"
  }
}} />

So, my best suggestion is to loop over the data, find the longest email address, and set the fixed width based on that. This kinda sucks, but I don't see another way to properly set dimensions for a flexbox-based table:

const longestEmail = rows.reduce((longest, row) => {
    return row.email.length > longest.length ? row.email : longest
}, '');

const columns = [{
  // play around with the multiplier until you find a suitable width
  field: "email", width: longestEmail.length * 9,
}]

CodePudding user response:

This is from the Documentation..Number Signature

<DataGrid
  columns={[
    { field: 'username', colSpan: 2, hideable: false },
    {
      field: 'organization',
      sortable: false,
      filterable: false,
      hideable: false,
    },
    { field: 'age', hideable: false },
  ]}
  rows={rows}
  {...other}
/>

you can use colspan but it sets all cells in the column to span a given number of columns.

const columns = [{
  field: "email",colSpan:2,
},]

  • Related