question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Wrapping text with CellMeasurer

See original GitHub issue

I have the following use of CellMeasurer:

.item {
  border-bottom: 1px solid #eee;
  padding: 0.5rem;
  box-sizing: border-box;
}

.item-text {
  display: inline-block;
  vertical-align: top;
  white-space: pre-wrap;      /* CSS3 */
  white-space: -moz-pre-wrap; /* Firefox */
  white-space: -pre-wrap;     /* Opera <7 */
  white-space: -o-pre-wrap;   /* Opera 7 */
  word-wrap: break-word;      /* IE */
}

var cache = new CellMeasurerCache({
  defaultHeight: 20,
  defaultWidth: 50,
  fixedWidth: false
});

<CellMeasurer {...}>
  <div className="item" key={key} style={style}>
    <small>{datum.timestamp}</small>
    <br />
    <strong>{datum.author}</strong>: <div className="item-text">{datum.text}</div>
  </div>
</CellMeasurer>

The problem with it is when datum.text is a long sense/word. Then the rest of the text goes outside of the display area. I would like the text to be wrapped in available width of the list and the height to be adjusted to the wrapped text. Thanks in advance.

Issue Analytics

  • State:closed
  • Created 6 years ago
  • Reactions:1
  • Comments:7 (5 by maintainers)

github_iconTop GitHub Comments

1reaction
bdrobinsoncommented, Aug 8, 2018

I don’t think this relates quite to the issue you’re facing @skipjack but I was facing a similar problem to OP and found that the issue my text wasn’t wrapping in my Table cells was that the Column component automatically applies white-space: nowrap;, which was cascading down to my cell element. So in my renderCell method I just set that back to white-space: normal; and everything magically started working. See here.

1reaction
skipjackcommented, Aug 7, 2018

Might just be talking to myself here at this point, but here’s what I found…

I wasn’t able to make any change to the CellMeasurer to fix it trying to measure height while width was still equal to auto. Every attempt I made at delaying the measurement triggered an infinite loop. However, I was able to fix the issue by firing the measure callback in the component’s lifecycle returned by cellRenderer, i.e.

class Table extends React.Component {
    render() {
        return (
            <MultiGrid
                 ...
                 cellRender={ this._renderCell } />
         )
    }

    _renderCell = options => {
        return (
            <CellRenderer ...>
                 {({ measure }) => (
                      <Column
                          ...
                          measure={ measure } />
                 )}
             </CellRenderer>
        )    
    }
}

class Column extends React.Component {
    // ...
    componentDidUpdate(prevProps) {
        if ( prevProps.style.width !== this.props.style.width ) {
            this.props.measure()
        }
    }
}

Then, in order to properly handle updates (without an unmount and remount), I had to utilize the keyMapper method so the cached sizes would correspond directly to the data without the need for re-measuring. I also had to fire MultiGrid.recomputeGridSize in my Table component’s componentDidUpdate in order for the keys to be updated and the right values pulled from the cache for the cellRenderer.

@bvaughn I like this library a lot but getting this particular feature (text-wrapping in the MultiGrid) to work out of the box definitely isn’t super intuitive. I’m a little strapped for time at the moment, but if you’re open to talking through a fix for the CellMeasurer, I’d love to figure out a better fix for this in the actual library (which would also close that TODO I found in the code). If the examples I’ve shared aren’t enough, I’ll try to throw together webpackbin that demos the problem.

As for the need for a keyMapper and calling recomputeGridSize, I think those are understandable at the consumer level as we can’t know the best mapping without knowledge of the data. The only other thought I’d have is that maybe Table and Column could be re-written as wrappers around the MultiGrid. It could be written to still support all existing features with added support for fixed columns/rows and more control over cell width (with horizontal scrolling). This change would take a toll on performance though.

Read more comments on GitHub >

github_iconTop Results From Across the Web

How to get content of Column to wrap in react-virtualized
Check out the Table + CellMeasurer demo page (source here) for an example of a Column with wrapping text. Share.
Read more >
Create a Virtualized List with Auto Sizing Cells using react ...
In this lesson we'll use CellMeasurer and CellMeasurerCache to automatically calculate and cache the height of a row.
Read more >
Wrap text in a cell - Microsoft Support
Wrap text automatically · In a worksheet, select the cells that you want to format. · On the Home tab, in the Alignment...
Read more >
Rendering large lists with React Virtualized - LogRocket Blog
CellMeasurer, to dynamically measure the width and height of the rows, ... The placeholder text will be generated with the library ...
Read more >
Wrapping and breaking text - CSS: Cascading Style Sheets
What is overflowing text? In CSS, if you have an unbreakable string such as a very long word, by default it will overflow...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found