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

Table layout is broken with long text #1018

Open
mtdvlpr opened this issue Dec 27, 2023 · 11 comments
Open

Table layout is broken with long text #1018

mtdvlpr opened this issue Dec 27, 2023 · 11 comments
Assignees

Comments

@mtdvlpr
Copy link

mtdvlpr commented Dec 27, 2023

When I have one cell with a very long text, the table layout breaks. See reproduction or example output.

I expect the long cell to break the text and increase its height to fit the long text.

The layout is also broken for styles: { overflow: 'ellipsize' }. See example output with ellipsize

@mmghv
Copy link
Collaborator

mmghv commented Dec 27, 2023

Please reproduce the issue in a codepen with a minimal example.

@mtdvlpr
Copy link
Author

mtdvlpr commented Dec 27, 2023

@mmghv
Copy link
Collaborator

mmghv commented Dec 27, 2023

This behavior is due to the algorithm used to distribute the size on the table columns which is inspired by HTML table algorithm, each column will get a minimum width proportional to its longest word compared to the other columns, since you have a column with a very long text with no spaces in it, other columns with short words will get a tiny share of the table width.

If I add the same content to an HTML table with the proper size and a word-break: break-word; rule to respect the the maximum width, you will see a very similar behavior as seen in this codepen.
In this case the small columns have a bit more width, nonetheless it still breaks in the middle of words.

So we're actually on par with the HTML behavior here.

You have two options to solve your issue :
1- Add spaces in the long text to give the algorithm a more reasonable breaking points (longest word shouldn't exceed the desired column width).
2- Set cellWidth: 'wrap' style on the small columns to prevent them from breaking if you know the content is small, or assign a minCellWidth to them.

@mmghv
Copy link
Collaborator

mmghv commented Dec 27, 2023

See this example with a very long text but with spaces between the words and an email column with no spaces.

@mtdvlpr
Copy link
Author

mtdvlpr commented Dec 28, 2023

Okay, thanks! Is there no way to apply word-break: break-all; then?

@mmghv
Copy link
Collaborator

mmghv commented Dec 28, 2023

That's not what you want, maybe a word-break: normal; (don't break words) rule on the columns with short words would be a better solution than cellWidth: 'wrap' or minCellWidth, I think this could be added.

@Lazydd
Copy link

Lazydd commented Mar 29, 2024

好的谢谢!那就没办法申请了吗word-break: break-all;

styles: {
  minCellWidth: (doc.internal.pageSize.width) / 4
},

image

@mmghv mmghv self-assigned this Mar 29, 2024
@mmghv mmghv added the v4 label Mar 29, 2024
@mmghv
Copy link
Collaborator

mmghv commented Mar 30, 2024

I'm currently rewriting the width options for v4 to give more control to fix situations like this, the new API will look like this:

  cellWidth: 'auto' | 'min-content' | 'max-content' | number
  minCellWidth: 'auto' | 'min-content' | 'max-content' | number
  maxCellWidth: 'auto' | 'min-content' | 'max-content' | number

min-content : The minimum width required to fit the content in a readable manner (with no word-breaking).
max-content : The full-width required to fit the content without introducing new line-breaks.

Using this, you could do one of the following :

1- Set minCellWidth: 'min-content' on small columns to prevent work-breaking (equivalent to CSS word-break: normal;)

  // ...
  styles: {
    minCellWidth: 'min-content',
  },
  columnStyles: {
    2: {minCellWidth: 'auto'},
  },
  // ...
  
  // Or

  // ...
  styles: {
  },
  columnStyles: {
    0: {minCellWidth: 'min-content'},
    1: {minCellWidth: 'min-content'},
    3: {minCellWidth: 'min-content'},
  },
  // ...

1

2- Set cellWidth: 'max-content' (previously 'wrap') on short columns to prevent wrapping altogether if you're sure columns content is always one or two words

  // ...
  styles: {
  },
  columnStyles: {
    0: {cellWidth: 'max-content'},
    1: {cellWidth: 'max-content'},
    3: {cellWidth: 'max-content'},
  },
  // ...

2

3- Set maxCellWidth on the long column :

  // ...
  styles: {
  },
  columnStyles: {
    2: {maxCellWidth: 100},
  },
  // ...

For reference, this is how it looks like with auto width:

0

But it could be improved to minimize word-breaking by default in this scenario by prioritizing shrinking the longest columns so the short ones don't break, I'll work on that next.

@mtdvlpr @simonbengtsson Any suggestions/feedback ?

@mmghv mmghv changed the title [Bug] Table layout is broken with long text Table layout is broken with long text Mar 30, 2024
@mtdvlpr
Copy link
Author

mtdvlpr commented Mar 30, 2024

@mmghv, sound great!

@simonbengtsson
Copy link
Owner

simonbengtsson commented Mar 30, 2024

If possible to solve without introducing additional API I agree that would be ideal but otherwise suggested API sounds great 👍

@mmghv
Copy link
Collaborator

mmghv commented Mar 30, 2024

@simonbengtsson This specific scenario will be solved with the improved algorithm, but the new API gives more control in general for adjusting the table layout in many scenarios without resulting to hard-coded values which is not ideal with dynamic content.

We already had 'wrap' with cellWidth but it's a misleading name as it does the opposite, which is prevent wrapping, I though of changing it to unwrap or nowrap like in CSS, but it could be confusing with the old name, Then I found that CSS actually has values for width that include min-content and max-content which makes more sense, beside it's always good to align with HTML/CSS, it makes it easier and intuitive for new users and for CSS parsing if we decided to take width styles into account.

So the only breaking change here is changing 'wrap' to 'max-content', and we add 'min-content' and support these options with minCellWidth too, and we add maxCellWidth which allows you do thing that cannot be achieved with cellWidth and minCellWidth and was requested a couple of times here :
#832, #669 (comment), #749

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants