Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[data grid] Easily allow header text to wrap #898

Open
iccube-real opened this issue Jan 22, 2021 · 19 comments
Open

[data grid] Easily allow header text to wrap #898

iccube-real opened this issue Jan 22, 2021 · 19 comments
Labels
component: data grid This is the name of the generic UI component, not the React module! new feature New feature or request

Comments

@iccube-real
Copy link

Summary 💡

Sometimes header titles are too big to fit in one line and we would like to have them in multiple lines.

Ideally, we could have a kind of outfit that is based more on the columns cells width, like Excel, but this one is not trivial. And as the answer might depend on some end users input we do not know in advance either how many rows or size we will get.

Examples 🌈

A very simple example : https://codesandbox.io/s/material-demo-forked-g6ibb

Motivation 🔦

  1. Multiple lines for header are sometimes a visually better idea
  2. Have a smart resizing that removes the need to manually calculate for each tables column widths and number of lines.
@oliviertassinari oliviertassinari transferred this issue from mui/material-ui Jan 22, 2021
@oliviertassinari oliviertassinari added components: XGrid status: waiting for maintainer These issues haven't been looked at yet by a maintainer labels Jan 22, 2021
@DanailH
Copy link
Member

DanailH commented Jan 22, 2021

@iccube-real @oliviertassinari this looks like a duplicate of #417 as both are related to multiplies support in cells and since table headers are just a special type of cell it would be appropriate to have that functionality for both when we pick it up.

@iccube-real
Copy link
Author

iccube-real commented Jan 22, 2021

@DanailH , it's the same 'family' yes. You want to fix the maximum number of lines you want manually (height in px is not the point).

Imagine a column that calculates a ranking (it's a small number) but with a bigger title (e.g. 'Developers month ranking'). You don't want your column take too much width but still want to see the whole text of the header -> two lines might look better. After you want ellipsis...

Ideally, it's a competition between the width and the title height to better fit the table that depends on perception (so some users might like more agressive algos than others). Looks for know as a stick in the moon..

Two questions :

  • can we manually set the header with multilines (e.g. 2) for a table ?

  • is there a way to calculate the width of column before rendering

_hope it helps.

PS : I'll try to add some images so it's clear

image

@oliviertassinari oliviertassinari removed the status: waiting for maintainer These issues haven't been looked at yet by a maintainer label Jan 26, 2021
@oliviertassinari
Copy link
Member

oliviertassinari commented Jan 26, 2021

I'm not sure that we should treat this issue as a duplicate of #417. The problem surfaced by @iccube-real seems related be can be solved independently. There is a tension between the width of the columns and the height of the header. It sounds like he should expose the tool required for him to implement his tradeoff.

can we manually set the header with multilines (e.g. 2) for a table?

We don't support it easily right now. I think that it requires simplifying the CSS of the header first, e.g. duplicated white-space: nowrap;. It seems there is quite some noise in the styles. It's should be as straightforward as disabling the no-wrap, if we do such, right now, it's broken: https://codesandbox.io/s/material-demo-forked-y0chb?file=/demo.tsx

Capture d’écran 2021-01-27 à 00 37 19

is there a way to calculate the width of column before rendering

The width can be defined for each column definitions. So you can force a specific value. Otherwise, you can listen to update with this private API:

      <DataGrid
        onStateChange={({ state }) => {
          console.log("state", state.columns.lookup.id.width);
        }}

I have renamed the issue to focus on the text wrapping problem. We can only focus on one problem at a time and it seems to be the most relevant one.

@oliviertassinari oliviertassinari changed the title Data Grid / Table - Header text in multiple lines - fit to space [DataGrid] Easily allow header text to wrap in lines Jan 26, 2021
@oliviertassinari oliviertassinari changed the title [DataGrid] Easily allow header text to wrap in lines [DataGrid] Easily allow header text to wrap Jan 26, 2021
@oliviertassinari oliviertassinari added the new feature New feature or request label Jan 26, 2021
@giq-re
Copy link

giq-re commented Feb 24, 2021

The same issue applies on rows as well. I was able to jerry rig it but it was not pretty. This may be a bigger discussion about being able to more easily override certain styles.

@oliviertassinari oliviertassinari added component: data grid This is the name of the generic UI component, not the React module! and removed components: XGrid labels Feb 24, 2021
@oliviertassinari
Copy link
Member

@giq-re For cells, please see this issue: #417

@dtassone
Copy link
Member

dtassone commented Feb 24, 2021

One way to do it is to apply a css class on the header and override the MuiDataGrid-colCellTitle

const useStyle = makeStyles({
  root: {
    "& .wrapHeader .MuiDataGrid-colCellTitle": {
      overflow: "hidden",
      lineHeight: "20px",
      whiteSpace: "normal"
    }
  }
});

Check out the full demo https://codesandbox.io/s/header-wrap-text-xzscx?file=/demo.tsx

You can also increase the size of the header row using the headerHeight prop

@oliviertassinari
Copy link
Member

oliviertassinari commented Feb 24, 2021

@dtassone I think that we should remove the need for using lineHeight: "20px",. Conceptually, I don't see anything that would justify it. It would improve the DX. Also, can't we remove overflow: "hidden", from the codeandbox, the style is already present?

@caotrinh
Copy link

How can I just hide the headerName if it is too big to avoid the displaying "Us..." for "User Name"? It looks ugly in the table.
Thank you!

@Curti-s
Copy link

Curti-s commented Oct 15, 2021

In ref to this #898 (comment)

One way to do it is to apply a css class on the header and override the MuiDataGrid-colCellTitle

const useStyle = makeStyles({
  root: {
    "& .wrapHeader .MuiDataGrid-colCellTitle": {
      overflow: "hidden",
      lineHeight: "20px",
      whiteSpace: "normal"
    }
  }
});

Check out the full demo https://codesandbox.io/s/header-wrap-text-xzscx?file=/demo.tsx

You can also increase the size of the header row using the headerHeight prop

This was how I was able to do it

const useStyles = makeStyles({
  root: {
    "& .MuiDataGrid-columnHeaderTitle": {
      overflow: "visible",
      lineHeight: "1.43rem",
      whiteSpace: "normal",
    }
  }
});

@iggyzap
Copy link

iggyzap commented Dec 24, 2021

I was able to find that in @mui/x-data-grid version 5.2.0 result of header being blown out of proportion (#898 (comment)) is due to lineHeight (translates into line-height css ) being set to 56px which really sets height of the box relative to number of lines text is being broken to. So 56 px with 3 lines of text would be 168 pixels, which blows it out of proportion.
Fix? Below:

<DataGrid columns={cols} rows={...} autoHeight={true} headerHeight={80} disableColumnMenu={true} sx={{
            '& .MuiDataGrid-columnHeaderTitle': {
                textOverflow: "clip",
                whiteSpace: "break-spaces",
                lineHeight: 1
            }
        }}>

@flaviendelangle flaviendelangle changed the title [DataGrid] Easily allow header text to wrap [data grid] Easily allow header text to wrap Oct 17, 2022
@stamahto
Copy link

Would be great to have auto-height header adjustment if text overflows actual width. I would appreciate it in v6 #3287

@john1625b
Copy link

@iggyzap
That works for me for most headers but some that are too long get cut off like so:
Screenshot 2023-04-05 at 1 05 00 PM

I tried setting headerHeight to be higher but that doesn't fix it.

@ryancogswell
Copy link

ryancogswell commented Apr 5, 2023

This came up in StackOverflow: https://stackoverflow.com/questions/75943264/how-to-word-wrap-the-column-from-material-ui-datagrid/75944212#75944212.

Here's the styling I put in my solution there:

      <DataGrid
        sx={{
          "& .MuiDataGrid-columnHeaderTitle": {
            whiteSpace: "normal",
            lineHeight: "normal"
          },
          "& .MuiDataGrid-columnHeader": {
            // Forced to use important since overriding inline styles
            height: "unset !important"
          },
          "& .MuiDataGrid-columnHeaders": {
            // Forced to use important since overriding inline styles
            maxHeight: "168px !important"
          }
        }}

This is similar to what @iggyzap has but also dealing with allowing the height to handle more than 3 rows of text (though after trying this out in my own project, I'm finding issues with the height and maxHeight overrides when using "auto" row height for the data).

@rafaelrpd
Copy link

This came up in StackOverflow: https://stackoverflow.com/questions/75943264/how-to-word-wrap-the-column-from-material-ui-datagrid/75944212#75944212.

Here's the styling I put in my solution there:

      <DataGrid
        sx={{
          "& .MuiDataGrid-columnHeaderTitle": {
            whiteSpace: "normal",
            lineHeight: "normal"
          },
          "& .MuiDataGrid-columnHeader": {
            // Forced to use important since overriding inline styles
            height: "unset !important"
          },
          "& .MuiDataGrid-columnHeaders": {
            // Forced to use important since overriding inline styles
            maxHeight: "168px !important"
          }
        }}

This is similar to what @iggyzap has but also dealing with allowing the height to handle more than 3 rows of text.

Yep! It was helping me. Thanks again, @ryancogswell !

We need some kind of feature to do this easily

@managervcf
Copy link

managervcf commented Jun 20, 2023

Thanks @iggyzap!

However, if I remove the disableColumnMenu={true} prop, left padding of the header is messed up.

To counteract this, I added pl: 1 on the .MuiDataGrid-columnHeader--alignRight .MuiDataGrid-columnHeaderTitleContainer and removed the textOverflow: 'clip'.

<DataGrid
  columns={columns}
  rows={rows}
  autoHeight
  sx={{
    '& .MuiDataGrid-columnHeaderTitle': {
      whiteSpace: 'break-spaces',
      lineHeight: 1,
    },
    '&.MuiDataGrid-root .MuiDataGrid-columnHeader--alignRight .MuiDataGrid-columnHeaderTitleContainer': {
      pl: 1,
    },
  }}
/>;

@githorse
Copy link

githorse commented Dec 22, 2023

Baking this feature in would be really helpful. It's really hard to get this right in a way that doesn't screw something else up:

Screen.Recording.2023-12-22.at.08.54.38.mov

For reference, note that AG Grid seems to do this wrapped header thing well.

@benosmond
Copy link

We tried implementing this, but we had difficulties getting the header height to adapt to the number of rows of text as the contents wrapped. It would be good to have a native option for this.

@scott-gmr
Copy link

The irony of the DataGrid is that for how much it's supposed to do for you with the display of the table, I end up needing to hack its styles constantly to get a reasonably intuitive interface for anything more than a handful of simple columns with short cell values and header names.

@Jimm119
Copy link

Jimm119 commented Dec 2, 2024

Just want to add my voice to this feature request. I think it would be very interesting for accessibility to have labels in the header that wraps according to the available width, so that we can always see them whatever the text zoom, page zoom and so.

I'm able to make it work by tweaking CSS, but it would be much better if the component handle it directly.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
component: data grid This is the name of the generic UI component, not the React module! new feature New feature or request
Projects
None yet
Development

No branches or pull requests