diegomura / react-pdf

📄 Create PDF files using React
https://react-pdf.org
MIT License
14.91k stars 1.18k forks source link

Vertical Compression of Components when using wrap={false} #2763

Open chrissyalbert opened 5 months ago

chrissyalbert commented 5 months ago

Describe the bug When using wrap={false} on a View Component used for a table, the desired effect was to prevent breaking short tables if they appeared to far down to the edge of a page. This behavior worked on 3/5/24. The current behavior is a vertical compression of components to try to fit in one page instead of starting a new page, then breaking towards the last part of the parent component with the wrap={false} property.

To Reproduce

  1. Set parent View component with wrap={false} property
  2. Add 70+ children Text components
  3. See the pdf trying to compress all 70+ children into one page making the text illegible

REPL 3.3.5 REPL 2.3.0

Expected behavior The parent component using wrap={false} starts on a new page if it can't fit in the space left on a page. If it its total height is greater than the height of a page, it starts on a new page and breaks at the page length and goes on to a new page.

Screenshots 3/5/24 working wrap={false} short tables start on a new page when they are close to the bottom of a page instead of being broken, long tables greater than a page height start on a new page and only break at the last part of the rows image-20240304-232032

current behavior: wrap={false} tables of various heights "compress" rows in order to fit a page, rather than going to the next page and breaking at the last part of the rows

layout 3 11 2

Desktop (please complete the following information):

Mudbill commented 4 months ago

+1 for this issue. I think it is the only significant problem I have that's preventing me from using React PDF in production. I was about to register an issue myself for this, but I'll tag it onto here instead. Mine is slightly different but similar enough that I suspect it's the same root cause.

PS: I'm still encountering it on latest version as of today (3.4.4) though I am using 3.4.2 due to a font regression.

Here's my reproduction:

Click to open

I'm rendering a document that has more rows than will normally fit on a single page. As a result, the rows continue on the next page as expected. However, due to the presence of a footer, all content on the first page gets compressed. It looks to me as if the size of the footer is not considered when determining how many rows will fit on the page (perhaps because it comes after?) **Sizes I've used for demonstration:** There's a flex layout with `10` as row gap. I've set `height: 100` to both the header and footer, and `30` to each row. I'm rendering 20 rows. Without the footer, the page fits 17 rows based on these sizes (screenshot 1). With the footer, the page **should** only fit 14 rows, but it still crams 17 rows in there by shrinking every element (screenshot 2). This issue gets worse the bigger the footer is. [RELP 3.3.5](https://react-pdf.org/repl?code=3187b0760ce02e00408a057025803c450298c0bc300500943807cf805030c00f0022230080b6198531165d400a02180e659a004f003619b006f091d3a700264820007113c8402e18008801998945a00d0cd93094f390ac1f4d009800331d39c0138800ee01c4792cd01191c4d28017d83d99d28a800d49031dc834ddc5c7d247478442031821364755030e473e430008c10f88b2984c525a4234c4a405ce4305d34b56c94506020404490e460f85c30588d2b384a798001ad864010c0e40184fa9bdbfaf8002ca18746c1c7eb64b63091b6a1fded028fe51454d5daf4300c9c6e6000ac11a0907485575858176d30101ad4391d42457091ca80015679b00062f94189c2cad2a001e9e12836114b13138b439c12301c46000411732484780701000747911088f060040b3198c1f1e0f0007d430c090446c290f01368ac5e26f18124521234864b2134a0cc304249121b232969942a32eab88a42ac99345a6d6d275babd7ea0c4a2204061c1329399c769a003335c653005329541a6d13c5e26ca27dbebf7fa6158ed104025cceb794d66f3458acd616ad26c76f6c7627ea909bb126138b6000943c9a0912060006a181f98258d2f179c04a96b738040236a2292b884cf2280284d75e509a1b6a26c6b355aed2b4f4fa031837204ac1e3e622c9b99b8d3ab113adb44a24180669be72bbce976f4dcfdf740ee9f4e7d3386a03f3fb81a340ad1c73009d7816bdb389dac870822c4322c3a0c3a080e8062d8b81f8a6284bb8ec09858af002342589d00c330ac3b004000dc6419065860d31405c0d0888322312cad1e054220a81c130262c4311641000000) Screenshot 1: ![Screenshot 2024-06-11 at 10 07 27](https://github.com/diegomura/react-pdf/assets/8832665/6ccd45e3-b4ca-41a8-b7cc-42bda8e6a871) Screenshot 2: ![Screenshot 2024-06-11 at 10 08 07](https://github.com/diegomura/react-pdf/assets/8832665/bd0ecf6f-2d56-44f9-a15d-96182b057961) Code: ```jsx function MyDocument() { return ( Fixed header {new Array(20).fill(null).map((_, i) => ( Row: {i + 1} ))} Fixed footer ) } ```
R-D-P commented 4 months ago

I too am having the same issue, at first, I was on 3.1.15 due to being on an older version of node. I thought it was fixed in the latest version, but I still see it in version 3.4.4.

R-D-P commented 4 months ago

@diegomura

fabiocalliari commented 4 months ago

I can also confirm this behavior.

chmtt commented 4 months ago

I had the same issue because i used height: auto at some container.

R-D-P commented 3 months ago

So I managed to fix this by rendering each page manually. I calculate the height of each element and then decide how many pages I need to render.

TrustyTechSG commented 3 months ago

I also having this issue, in my case I notice is was caused by the render function, if render a Text inside a View's render function (in order to get the pageIndex), then all content will be squeezed into a single page. By just remove the render function and put Text as children, then auto page break back to normal again.