react-pdf: Hangs when unbreakable component larger than page

Describe the bug When a component e.g. View is set to unbreakable via wrap={false}, and it is also taller than a single page, then rendering seems to go into an infinite loop.

To Reproduce Steps to reproduce the behavior including code snippet (if applies):

  1. Go to https://react-pdf.org/repl?example=disable-wrapping
  2. Change the unbreakable style height from 400 to 900
  3. Notice the blank preview

Expected behavior I think in the case where a component can’t fit on a single page and has wrap={false}, it should wrap as that is better than just failing.

Desktop (please complete the following information):

  • OS: Linux
  • Browser: Chromium, Firefox
  • React-pdf version: latest (REPL) - v1.5.6

About this issue

  • Original URL
  • State: closed
  • Created 5 years ago
  • Reactions: 8
  • Comments: 25 (11 by maintainers)

Commits related to this issue

Most upvoted comments

No worries @diegomura. The work you’re doing on this project is awesome! I’ve been able to work around this in the mean time!

Yep. Agreed! This is currently a limitation of the breaking algorithm. I’ll try to fix it soon. Thanks!

Hey @diegomura, I see that https://github.com/react-pdf/page-wrapping/commit/c198f2ec1b0ba9baebe9b6a5e848dcf0acafe322 has been merged into page-wrapping but as far as I can see there was no elease of react-pdf to use it. Will there be a release including it anytime soon?

Can the OP and others who had this issue confirm that react-pdf/page-wrapping@c198f2e fixes this.

Hi @maldimirov, I don’t believe the issue should be closed yet. The fix from @asgerhallas does work except for one case, which I believe might be the problem @rmolinamir is having. The variable height is not being calculated correctly. It does not take all page padding into consideration, specifically paddingTop.

This causes elementFitsFullPageHeight = true when height > element.height > height - paddingTop which will again cause the application to hang.

I’m not sure if this should be a new issue or if the current issue just needs to be reopened for the time being, I’ll leave that up to @diegomura . 😊 Thanks to everyone who contributes to this library, it is fantastic!

Hey @asgerhallas , your fix has not been applied to react-pdf. Any plan on creating a PR?

Hi @maldimirov, thanks for letting us know. I appreciate this library a lot, it’s really amazing.

In my case, it’s still hanging. I reproduced it with big lorem ipsum so it’s a bit forced. Bear in mind that in actuality, these components receive dynamic data, it is now impossible for this issue to happen on our end because we ended up restricting the character limit of our inputs & in the backend models (or at the very least, really hard to happen), so I had to use lorem ipsum to reproduce this. Here is the component that I’m using. It’s a styled Text component, from the @react-pdf/styled-components package:

import styled, { css } from '@react-pdf/styled-components';

export const Paragraph = styled.Text`
  ${props => props.padding && css`padding: ${props.padding};`}
  margin: ${props => props.margin || '12px 0'};
  color: ${props => rgbToHex(props.color) || '#000'};
  font-size: ${props => props.fontSize || '10px'};
  text-align: ${props => props.textAlign || 'justify'};
  align-self: ${props => props.alignSelf};
  justify-self: ${props => props.justifySelf};
  opacity: 1;
  ${props => !props.block && css`width: 100%;`}
`;
<Paragraph
  margin="0 0 5px"
  wrap={false}
>
  Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aenean ac egestas lorem, at varius tellus. Pellentesque lobortis bibendum libero, nec fringilla nisi tincidunt ac. Etiam euismod vestibulum tellus, ut elementum elit commodo sed. Quisque sed augue vel neque auctor molestie. Vestibulum vestibulum pellentesque erat non congue. Integer eleifend pretium mollis. Donec mattis, urna non rhoncus cursus, lacus justo dapibus metus, sed tincidunt augue nisi vel nisi. Nulla nec neque turpis. Phasellus sodales diam ut dui accumsan, et fringilla ligula bibendum. Aliquam consectetur felis vitae est faucibus blandit. Fusce non placerat sem. Donec tincidunt at metus vel tempus. Duis eu nisi ac purus mattis venenatis. Nam aliquam suscipit nisi, id aliquam elit.
  Quisque dapibus aliquet consequat. Etiam non efficitur tellus. Maecenas pharetra maximus nulla, nec pellentesque dolor iaculis id. Aenean auctor tempus diam id hendrerit. Aliquam ultrices justo ut malesuada fermentum. Quisque dictum odio in nulla consequat, pellentesque sagittis felis sagittis. Nunc eu interdum metus. Aliquam ornare dolor in viverra mattis. Mauris odio leo, pharetra ut dictum et, fringilla nec mi. Nullam at blandit nisi. Sed viverra, eros quis elementum hendrerit, augue dolor ullamcorper nunc, at bibendum quam nisi eu nibh. Nulla in aliquet metus. Nunc vitae arcu ut ligula dignissim finibus. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Quisque leo purus, blandit in odio at, semper porttitor nisi. Nulla facilisi.
  Fusce dolor elit, ornare sed nulla a, euismod posuere urna. Aliquam venenatis molestie nunc elementum egestas. Sed massa urna, aliquet eget magna quis, rutrum sollicitudin ligula. Donec aliquam interdum ante, ac elementum velit maximus sit amet. Donec dui augue, feugiat eget iaculis vitae, tempor eget eros. Aenean accumsan est ornare elit cursus tempus. Donec ultrices enim id ante porta, eget suscipit sapien faucibus. Maecenas pharetra purus ut justo lacinia bibendum. Nullam vestibulum luctus vulputate. Pellentesque suscipit ultrices turpis vitae hendrerit. Nulla mollis eleifend erat vitae vulputate. Nunc consequat viverra eros in faucibus.
  Pellentesque luctus ex ante, at placerat risus bibendum ac. Quisque ac vehicula est. Aliquam sit amet libero nec quam rhoncus ultrices. Curabitur placerat nulla id dictum rhoncus. Etiam faucibus consequat dignissim. Aliquam facilisis fermentum nisl, id volutpat diam feugiat vel. Nulla in consectetur sem.
  Nunc et dolor orci. Interdum et malesuada fames ac ante ipsum primis in faucibus. Ut condimentum erat interdum nibh laoreet, et imperdiet dolor luctus. Maecenas condimentum urna sed tempor consectetur. Sed sed mauris ut leo porttitor condimentum ac et neque. Morbi ac imperdiet purus. Nam ut neque eu nisl semper vestibulum. Nullam eu aliquam metus, sit amet mollis neque. Pellentesque tellus mi, congue lacinia euismod sed, aliquet sit amet nisi. Phasellus elementum mi nec porta congue. Proin sit amet volutpat elit, tincidunt laoreet est. Sed bibendum diam nec vehicula rhoncus.
  Duis nec ultrices turpis. Sed eget ex ut metus suscipit ultrices quis vel magna. Phasellus hendrerit, nisl ut dapibus mollis, nisi risus ullamcorper dui, ac dignissim ipsum erat imperdiet lacus. Morbi eleifend tortor sed augue ultricies luctus. Nulla vel tincidunt nunc. Nullam odio lectus, iaculis ut tellus sed, gravida ultricies quam. Integer nec pellentesque ipsum. Duis eget erat eu nibh lobortis posuere. In ullamcorper ligula dui, sed venenatis elit malesuada ac. Praesent pulvinar posuere tempus. In hac habitasse platea dictumst. Integer nec porttitor turpis, vel malesuada sem. Curabitur semper lacinia lorem porttitor lobortis. Etiam accumsan est massa, eu porttitor mi facilisis mollis. In mauris diam, varius at purus at, semper mattis tellus. Vestibulum id viverra nulla, sed tristique tellus.
  Phasellus vel sem non velit eleifend eleifend. Ut dictum lacinia mauris sit amet vulputate. Mauris commodo mollis mauris, dictum convallis odio gravida eu. Ut a nunc felis. Vestibulum tristique tempor pulvinar. Sed ornare quis sem scelerisque tincidunt. Etiam eu venenatis nisl.
  Nulla congue suscipit metus, et interdum tortor dignissim eget. Nunc quis mi sem. Aenean ultrices, tellus vitae fringilla iaculis, turpis leo fermentum sem, a lobortis arcu lacus quis massa. Donec condimentum tellus vel tincidunt facilisis. Pellentesque at commodo arcu. Aenean id varius elit, quis tristique lectus. Praesent quis quam justo. Etiam at lobortis sapien, a sagittis turpis. Aenean auctor mauris diam, vitae imperdiet sapien rhoncus vel. Etiam eget lorem quis nunc facilisis bibendum et at velit. Quisque vitae commodo mi, eu condimentum enim. Curabitur ex ante, dignissim in vestibulum vel, lobortis non dui. Fusce et tellus blandit, egestas augue vitae, ultrices mauris. Curabitur porttitor feugiat tortor consequat ultricies. Nunc tincidunt purus eu nisi placerat, quis varius massa ornare. Curabitur a ligula libero.
  Proin vel dolor nec risus placerat pharetra. Sed gravida aliquam neque, vitae rhoncus erat. Aliquam non viverra est. Fusce interdum, enim at tempus aliquet, diam sapien semper nibh, posuere interdum tellus elit vel arcu. Proin lacinia luctus dolor, nec auctor neque. Aenean ullamcorper massa nec volutpat mattis. Etiam sit amet enim vitae libero mattis tempor. Curabitur diam eros, rutrum vel efficitur non, volutpat eu dui. Nam auctor convallis elit et hendrerit. Donec sit amet luctus ligula, sed pharetra orci. Cras in justo sit amet lectus varius molestie at in libero. Fusce sed sapien nulla. Sed eros turpis, semper sit amet ligula sit amet, molestie pharetra nibh. Etiam nec tellus cursus, mollis enim sed, facilisis sem. Donec ut lorem at urna malesuada lacinia.
  Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Sed aliquam arcu in lorem iaculis, sit amet maximus turpis vehicula. Suspendisse sollicitudin eleifend justo consectetur ultrices. Mauris ultricies quam nulla, tincidunt venenatis ante ornare sit amet. Donec ultricies cursus est, ut tempor dui venenatis quis. Etiam arcu lectus, sagittis eu sodales et, blandit nec mi. Vivamus nec gravida nulla.
</Paragraph>

Is it possible that either height or element.height might be falsy in this line?

const elementFitsFullPageHeight = element.height <= height;

It would result in elementShouldBreak being always false (assuming element.break is false) because of elementFitsFullPageHeight being falsy in the following expression:

!element.wrap && elementShouldSplit && elementFitsFullPageHeight

So it never ignores the wrap={false} prop. I’m wondering because I used the debugger and saw that height was falling back to NaN in another function, but I’m not sure if it’s the same parameter:

image

Basically, not using wrap={false} any time the content might ever exceed the page height. Not a very elegant solution but we have gotten by that way for now 🤷‍♂️

@jtart @diegomura Yeah, I completely forgot to make a PR for react-pdf too, using the new version of page-wrapping. I’ll gladly do that 😃

Sorry I couldn’t take a look at this yet. Wish the day had more hours 😅