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.

[Enhancement Suggestion] Proper word-break (don't break in the middle of words)

See original GitHub issue

First, Thank you for such a great plugin which made our life much easier.

I’m facing a big problem when using the plugin with real-life data, when there’s even only one cell in a column with long text, the other columns cells will break in the middle of words which makes it unreadable and taking double the vertical space when it should take space from the big column.

1

This makes it unusable without defining minCellWidth for columns or preventing it from wrapping altogether, that could work for some cases but that’s not the answer, I have user-defined data in these rows which could be one word, or more, I want it to break into lines (correctly) only when needed.

So, as an attempt to solve the problem, I tried to figure out how HTML tables handle this, What I found is that each column will have a minimum width that will not get smaller than the longest word in that column.

So I used the following hook code to set minWidth for each column to the longest word :

doc.autoTable({
  // ...

  /**
   * Prevent AutoTable from breaking lines in the middle of words
   * by setting the minWidth to the longest word in the column
   * 
   * WARNING: this may cause the table to exceede the allowed width (just like in HTML)
   * and give a "can't fit page" console error, could be improved.
   */
  didParseCell({doc, cell, column}) {
    if (cell === undefined) {
      return;
    }

    const hasCustomWidth = (typeof cell.styles.cellWidth === 'number');

    if (hasCustomWidth || cell.raw == null || cell.colSpan > 1) {
      return
    }

    let text;

    if (cell.raw instanceof Node) {
      text = cell.raw.innerText;
    } else {
      if (typeof cell.raw == 'object') {
        // not implemented yet
        // when a cell contains other cells (colSpan)
        return;
      } else {
        text = '' + cell.raw;
      }
    }

    // split cell string by spaces
    const words = text.split(/\s+/);

    // calculate longest word width
    const maxWordUnitWidth = words.map(s => Math.floor(doc.getStringUnitWidth(s) * 100) / 100).reduce((a, b) => Math.max(a, b), 0);
    const maxWordWidth = maxWordUnitWidth * (cell.styles.fontSize / doc.internal.scaleFactor)

    const minWidth = cell.padding('horizontal') + maxWordWidth;

    // update minWidth for cell & column

    if (minWidth > cell.minWidth) {
      cell.minWidth = minWidth;
    }

    if (cell.minWidth > cell.wrappedWidth) {
      cell.wrappedWidth = cell.minWidth;
    }

    if (cell.minWidth > column.minWidth) {
      column.minWidth = cell.minWidth;
    }

    if (column.minWidth > column.wrappedWidth) {
      column.wrappedWidth = column.minWidth;
    }
  }
});

codepen: https://codepen.io/mmghv/pen/eYYvQqO?editors=1010

And this was the result :

2

As you can see, It fixed the problem, now the spacing makes more sense and the table actually look more like the HTML version.

I believe that this should be the default behavior.

I didn’t do a pull request because it still needs improvements and a way to handle colSpan but I’m in the middle of a project right now, so I’m leaving this here as a starting point, and as a quick fix for anyone who could be facing the same problem.

Note side effect of this, it may cause the table width to get outside of the defined boundaries if the total width of the longest words in each column is greater than the defined tableWidth.

This is actually how HTML tables behave, But I fell like it shouldn’t be that way with AutoTable, I’m not sure.

Issue Analytics

  • State:closed
  • Created 4 years ago
  • Reactions:7
  • Comments:12 (5 by maintainers)

github_iconTop GitHub Comments

3reactions
simonbengtssoncommented, Oct 24, 2019

Prioritizing not breaking words sounds like a great way to solve many of these issues!

2reactions
simonbengtssoncommented, Mar 27, 2020

Implemented on master but this feature needs some more testing before release.

Read more comments on GitHub >

github_iconTop Results From Across the Web

word-break - CSS: Cascading Style Sheets - MDN Web Docs
The word-break CSS property sets whether line breaks appear wherever the text would otherwise overflow its content box.
Read more >
Prevent word breaks - CSS-Tricks
I've tried different white-space and word-break properties. ... paragraphs to avoid hyphened word breaks and have the text center justified.
Read more >
Smarter word break in CSS? - Stack Overflow
For English and many other languages, the correct breaking means hyphenation, with a hyphen added at the end of a line when a...
Read more >
Word division in IE and other notes on the nobr markup
It treats any hyphen as a potential word break point, thus even breaking "-a" to ... after a middle dot ·; before a...
Read more >
Olivero: Ensure long words break properly when zoomed in to ...
This is split off from [#3190262] and is an Olivero stable blocker. ... word-break: break-word; to overflow-wrap: anywhere; as suggested by ...
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