Wrapped elements has no top padding on second page
Describe the bug When an element wraps across two pages, the new element on page 2 will get the top border of the original element, but not the top padding.
To Reproduce https://react-pdf.org/repl?code=3187b0760ce02e00408a057025803c450298c0bc300500943807cf805030c00f0022230080b6198531165d400a02180e659a004f003619b006f61622003a0046200099080beed3a72a00d490600ee1b34c00905400a8614b1a78a9514463999afa8ec738051303010f91087c3c004e304a58223c3000b23c60c000163c003461580c42203060208cf2c1583930008ec818c1593ca0c14a21cca94549ee1e308c088959507a8c000e59a558006e488300b7517e300948b5227c59e130222010694b71005e512c303cd048226215a93cb5c141cd1e715d7c08293015c0a33e006691a0304230417359d5054a103056430002a980a22043945163c5fab40087ab41954a2034bb1980213039440a9081c27a48600019ffc7b446ac7289272a494080c32d565f01be5ae2b258722008f929c56c90c668c4ac0c000ac294c9830dca388809ce6002f9f0f4e1b924115610047d38cc10c128a4b018c757cce582ce281204c71b93565002aac55c14c2ad16100414caa7a302d4419e1103c9c5005a3322304b70002369801332e6ca22d068c90a6152589116d5d4350c2101302741a292f3d340299698c211dd7041bc398b65bc75a4808230f19cd778cb330163db0418461c4a2102c025c0fade787c015a9686814835b2d298de2ce441963038dbb3e77786f613086ec0725067e6f713fac7218211efdcbe7e21c81f2ea9e23606d92ca1c304109c1a3949f56a69f2f83e2b61b086bbaf45917c3d2445b2a46f9eca32362c0400724413a320f3d0cf24ead8c0c180e139867d2d4e13ea2080062c13363c111db2916b1800cb4015236d32ccf324efe25eea83037aec9abf2ddbea6b280bd1882812064a06c0120f730e1f22c58b04b280a2d2702c28a083066b0542c480003737cfa881a7304811f2a117c3c31a9c7d6511625b082881e8050f8e12c9a13a2ea6509806edb0061023e6e6e4f91608b0b9e2ad43016488138a7144781be3b10659124d65ccf7a364a1202f3942c2c9db371ab0f0da5024e31ee1506e91ec59138c0351f20b00409c7e1be7d3048da5aa2860501ea149267a68cc68c831955e296e7e5919558d4b24447a45839193d2e2ddb402023648241ce9447d07c5113141854e1832ac219302f2a58cd3b18610b04faac9d25280025c064530e319c2170f9c07e67e0e9f64ce3529c7e8f8930044128480ec4f112474ba408264ef9e4053bec7ab995354673d468d343f5b41d3e1dd1f43370c633ee530cc5f781868449b115bb3ec9fb1cbb19cdf4f9d7120b73dc8f0e16f1545077cd4e4ef746080b026081e50986b0bc28c12252aa295575d8ae2f8a12c4b49912acf2d52f4024b49840ca4a2c8326c99dab24adcaf28099a3f70a9838a96dfeae6a9bb22acaaaac686a580f0da8e5f4889869aa6029a6a4f996bba8c346dafe10ea9ece8556e87a492c92c2fa303fa81bad693425c64608346b186d3f626c9a27699c2999ac49a1cb996405bacab3164199653bba55ab035ad39ca36c68b66da1a9d9ac3daa3c380e0787da3980e3839edc7ab5f2cd442e592ebcbbaa201ae2c26e3b0ee58812c0544365a2278aa04b9e1125e771b9502de87cc6c173eaf89e4527edf91fed8ce00460a91de20480605448d9126d0560bdc042100908fd142685688052c24f07c1894e8b90e07ac7ccca14e3941e0945a8b9f42cdd818a2c43afa4d8953784e59252c9788a756f809212d8344ae4182560a48f8028855f106045235454ad2642600b48032c07a5ed39d3e02655a1990b2e2c808d92e634c1c8f0272f00ca1b93489e5958fd3f23bd02b05160a1551845640515212a8f8ad149289e14a39dd2bbb5b8109b2ae57caf10e496e4fea55833c737ce11a00d520a6b41a92026a6005aaec36aa7c811757003d4fabea644b892048d0aa1f5c204d1ece9dca0cd0fad0816898a5af9956aa54dadb4e85ed4a8d919898893a3d9cea5d3a1c95c93641080f4d858457a68c3e8123982f87ea4c1e8ff514503522a0d7e8431080b8a20c3448f7094a232c839051a147e86a3319026c63fd71af49f204d471137ec24cdf1934dc931d8b0b0bc5d9221802d8ee2f61746666d812b9c6d9ea539b73548bcd5e3bc4163f138bfc3164084138248479d65a715d68acb116888eaac59b74a24a496d25277c348e511b4641c94d860736c199daac6b67c8ed8f9076628250bb19486cbe92a53ccb1bdb813f63a903afe57421cc3b44ab4d1ce213738e1549d0ba3583b953b7a0ce59c1d308bce118a3172e2ed95b32440aebb83305232e75cf323758e2dd4b2ac72c1dd4f1775ac9724b8ece6cad95210f655581479f609e4384718e3413aa17ace65e178970fd15c9bc603ae1dedb83d3ef7dc47c8f3b533c3092fb6aebe3797fbdf20a4f91c4fd37cafcc43bf5d89fdff08a28d93140b812c4904808c1651e024f221011a85a106100c9f3708a0c2204248960f22300a88d13a28434e2312a9ac47e99c8a1538a86f15a147d049a2c614a5984493691c2e49709e1bb8f8512f529a4caae91586228c848ae503894399208b23acad92198e4706a8d723b03c9202f20c91b0e8f8131a4292cb588b5a2ac5662095f0234b5a3a4ec57d2caa5d9c5b942aee325278f2aab07c7555dc013eaa3566aad4c03b52893f5baaf57ea09286b24fc5e348a94d2c96f8727cd2888b42132d229eb44a475329f402a490ea97c4ce9197a927d2d534bbaad29e874f7a820be8bc968fd30664ce1920d339837f0164a19d3188710667c313a48d16585346a5031aec2c6751366346e31e1766746262b28608c1393e1bb5d930d933ae4333b9684d5ab3108ecd5e6b02e67703e7612f902c80afcbf840801202c9620a65afb3960ac51142ef230af85c28d688bb9442ea406cd17d20c5cc92a8e28e456c79212f0eea44953b54daed2947b1a521de97fb5d441ceb2b2fe4ecaa38c70a4bd8ab2272ec82abd3a723da2b52ae730c92b0bb4a9e07194b9ca94c9b3d3357155010d548442ccdc4b2df6d5f3d3b9f50352bcfb89ac1e75987a2c2b56346d6cd69eb3cb8b4e45e738579ba9f21eab7bf97717bcf73df63e334cf9a08b9275af2b03bef781fac68d3c601347e24d6839957f74d40533400ecdc0305be6b823358b740c80b03cb4209c2c83f0aa096d75ac891ea6df83d058b36dc423b51af524663cf1570cfdbf89fb06122547789561d25277c96e120ee74659688bb845617d26bb2466eedd964e47eefe387b9c9a8d3ddc3cf742f52d7bbb1e8b0a7268c56047d662e28124b1efadad7ecca71a7c8e53caffadc4dd0e4c07bc49e5f198020dd508041242584d2a7072267544331390fc4a062b18681c14998726a648bd7d8e68ddc233c188f1d6293f4b6b91dda94653751e3ab47833d1bb98c700c1d1695e8d8dbd2c85d2b8e365e3675f8e0d522e68a80007a4b0d61d80984a0c5f7401823095e8bef00104618bdd0060cc1583b0020064c81900a2e00a02c80287c19b26060878024070178f22441080005c300003900079080fa0e112879fe1c2030460073fe7c242805007a04019f45e8bcbc3ef720f82962e8c016418922f1008bcac55f22094117c180011800331178009a001f5cc0001a5b40000d840000038001d4401061e41410940bfd181ffc0003400138780001053036400fc5e1e7cc815413bdbbd2386c01c146970000195c823012820d97a8efc0a0781300c7c381140540e7dc7d340550940729439cc04007a0e7cbfc0015999c782f82f8000085d00088e7d402c439a02424d000024e70c099ec441843143281541c385c0a013839a11406a1ca00428426000009999c4c2c89cc200184a1081177c01037c9434e1243cc2e7d2c20001999dcfd581282900360300e7c3fc0005999c0c3302440b98c0177cb49f605e0840dc3340022a00288a7d67c17dcc0b689c00016800095504c00083743083882c810a2300aa0a00b8068028807dbdcf00a805c8d014dc8bd88188280000
Expected behavior I think the most useful behavior would be if it was configurable what to do with "top and bottom styles" on wrap. Sometimes you would want to keep both top padding and border on the next page, sometimes not. And sometimes you would want to end the wrapped element with a border and a padding on the previous page, sometimes not.
But I suggest that the default is that both top border and top padding is derived to the element on next page. When you have text in boxes (or pseudo-tables) it looks "weird" when the text has no padding.
Suggested API Though the naming is not very explanatory, maybe an API like this could be introduced:
<View wrapStyle={['paddingTop', 'borderTop', 'paddingBottom', 'borderBottom']} />
What do you think?
I'd also like to see this, at the minute I'm adding a fixed header to create the required padding for each additional page.
I need support padding bottom on the next page
From the looks of it, it seems like the wrapped view is treated as a single view, but just spanning across multiple page. So the margin / padding on top, only applies to the top on the first page, likewise for the margin / padding on the bottom, it's only applied on the bottom of the last page.
Using a fixed header like @mrmadhat suggested also did the trick for me.
EDIT: For anyone struggling with this, make sure to enable the debug flag, you'll get a better understanding of the margin and padding within your view.
I'm trying to do a 2 columns layout and also encounter this problem and now have to implement a fixed header to manage my top padding. For the bottom padding I try with minAbsenceAhead but couldn't find a solution yet.
A fixed footer doesn't work as the content goes behind it. (I can't use padding on the page as it breaks my layout)
An API as suggested by asgerhallas would be quite nice indeed
From the looks of it, it seems like the wrapped view is treated as a single view, but just spanning across multiple page. So the margin / padding on top, only applies to the top on the first page, likewise for the margin / padding on the bottom, it's only applied on the bottom of the last page.
That's correct! I do agree in some cases it would be needed to have the paddings repeated throughout pages, although I do not think it should be the default behaviour. Unfortunately there's no support for that, but an API such as the open proposed could work and I'm open to add it. PRs are always welcomed!
Does anybody have a workaround? We are trying to conditionally display a "border" by using absolute positioned line... but it's hacky at best.
<View
style={{
backgroundColor: '#000',
width: '100%',
height: 1,
bottom: 14,
left: 14,
position: 'absolute',
}}
fixed
/>
To be fair, this does work and you can wrap it in a conditional render based on page number, but it would be nice to have a wrapping style API!
I also would like to see this. Is there anyone working on it right now?
Any updates on this?
Is there any progress on this one?
A workaround that worked for me is by creating a fixed element and using it inside the container of the page:
type Props = ReactPDF.ViewProps &
PropsWithChildren & {
padding?: number
}
export default function PDFPaddingElement({ children, padding = 20, ...rest }: Props): JSX.Element {
return (
<View
fixed
style={{
border: '1pt solid red',
height: padding,
width: '100%',
...rest.style,
}}
{...rest}
/>
)
}
Thanks Gustavo for the code! I updated it so that the first page does not have the top padding.
import type ReactPDF from "@react-pdf/renderer";
import { View } from "@react-pdf/renderer";
type Props = ReactPDF.ViewProps &
React.PropsWithChildren & {
padding?: number;
};
export default function PDFPaddingElement({
children,
padding = 20,
...rest
}: Props): JSX.Element {
return (
<View
fixed
render={({ pageNumber }) => {
if (pageNumber === 1) {
return null;
} else {
return (
<View
style={{
border: "1pt solid red",
height: padding,
width: "100%",
...rest.style,
}}
>
{children}
</View>
);
}
}}
/>
);
}
@diegomura how is this issue not fixed so far? It seems critical the vertical padding is not respected in between wrapped pages.
Also the label of this issue should be bug, not a new feature
If you're still facing this issue, you can fix it by adding a new <View> component with a fixed height for padding. You can use the method shared by @GustavoMelloGit (thanks to him), or apply it directly like this:
Static:
<View fixed style={{ height: 20 }}></View>
Dynamic:
<View fixed style={{ ...layoutCustomizations.vertical }}></View>
I insist in not using workarounds like this.
First, it's a dirty approach, and second, I have used it in my production app having instabilities with the implementation such as making the app enter an unknown loop which makes it unresponsive.
I understand. I also tried many other methods, but this was the only one that worked for me.
In my case, the issue happened when using 2 columns in the PDF. Adding a fixed <View> solved it.
I didn’t have any loop or performance problems, even in production