react-pdf icon indicating copy to clipboard operation
react-pdf copied to clipboard

How to let parent break with it's children?

Open asgerhallas opened this issue 3 years ago • 15 comments

Given a view with a header text and a view with a body text - when the body is moved fully to the next page, it's parent is kept on the previous page. That makes it look like the header is now orphaned.

Example here in the REPL

I'd like to be able to avoid this, and have a few alternative ideas:

  1. Maybe a parent that is emptied of it's children on one page should always break to next page (or alternatively worded: a parent is always linked to it's first child, so it breaks with the first child, if this is pushed to next page).
  2. Maybe the orphan attribute should be available on View components with a point value (instead of lines), so a View is never split into pieces smaller than this value, but rather pushed to next page.
  3. Maybe two siblings and/or parent-child elements should be linkable, so that they always break to next page together

Does any of these solutions sound like they would be possible and a good fit for the API?

I think 1 and 2 would go great together for solving the problem and when making table-like setups where you want all cells in a row break to next page together - while still allowing the row to wrap.

Would you like a PR for any of them? :)

And if there are any current solutions, that I haven't thought of, I'd like to hear those as well of course.

asgerhallas avatar Oct 14 '21 08:10 asgerhallas

You can use minPresenceAhead to achive that

here fixed repl

and here the video, how the text with minPresenceAhead moved to two pages

https://user-images.githubusercontent.com/6726016/137293058-876cbea6-9bdb-4671-8d07-bfe0acf5a30a.mp4

jeetiss avatar Oct 14 '21 09:10 jeetiss

Thanks! I was just about to post this workaround for orphaned views:

const ViewWithOrphans = (props) => (
	<>
    	<View minPresenceAhead={props.orphans}></View>  
    	<View {...props}>{props.children}</View>  
  	</>	
);

I'm not sure I understand the { bottom: -minPresenceAhead, height: minPresenceAhead} part. Can you explain?

But both of these solutions only solves the problem partly. If the text is shorter and should not break, this solution will make it break anyway, like: REPL

Do you have another good idea for this too? :)

asgerhallas avatar Oct 14 '21 10:10 asgerhallas

Ok, I undertand { bottom: -minPresenceAhead, height: minPresenceAhead} part now :)

asgerhallas avatar Oct 14 '21 10:10 asgerhallas

{ bottom: -minPresenceAhead, height: minPresenceAhead}

this is just a helper that shows size of minPresenceAhead , because you can't see it in other way (debug prop doesn't show it)

But both of these solutions only solves the problem partly.

You should specify orphans and minPresenceAhead together: like this

Do you have another good idea for this too? :)

no, @react-pdf supports only minPresenceAhead, orphans, and windows for manage content between pages now.

I agree that this is not the best api, because it's hard to calculate right values for minPresenceAhead and it works with orphans in pair, if you specify one of them wrong it breaks the layout. and you can't debug the minPresenceAhead anyhow now. but it works 🤪

two siblings and/or parent-child elements should be linkable, so that they always break to next page together

it would be nice to have something like that in future without all this manual math with minPresenceAhead

jeetiss avatar Oct 14 '21 10:10 jeetiss

const ViewWithOrphans = (props) => (
	<>
    	<View minPresenceAhead={props.orphans}></View>  
    	<View {...props}>{props.children}</View>  
  	</>	
);

You can't do that because minPresenceAhead should be in pixels and orphans in lines

jeetiss avatar Oct 14 '21 10:10 jeetiss

You should specify orphans and minPresenceAhead together: like this

Yes, but that requires me to know how many lines will be printed, and I can't know that.

You can't do that because minPresenceAhead should be in pixels and orphans in lines

Maybe bad naming, but the orphans-prop is meant to be in points here (as a suggestion for future api, an orphans property on View should be in points). Essentially the same solution as yours and with the same shortcomings.

asgerhallas avatar Oct 14 '21 10:10 asgerhallas

I will make a more real-life like example and post it to show what I mean.

BTW how did you make that video? :)

asgerhallas avatar Oct 14 '21 10:10 asgerhallas

Here's a sample of what I'm trying to achieve. It's essentially a table with two columns, and with the following "rules":

  1. The texts are user input, hence we don't know their size
  2. The header should always stay with the text
  3. The comment should always stay with the header
  4. The comment can't wrap (as it's a setup of some graphical elements, but we know it will not be larger than a page)

Sample

I must admit I can't see how to do this with the current available tools... but I might be missing something?

asgerhallas avatar Oct 14 '21 11:10 asgerhallas

Here's an updated sample that fixed a small error (header was not long enough to wrap): REPL

asgerhallas avatar Oct 14 '21 12:10 asgerhallas

I must admit I can't see how to do this with the current available tools.

Ow, yes you right! :(

BTW how did you make that video? :)

i generate hundreds pictures, and concatenate them to video with ffmpeg. here the script if you interested in

jeetiss avatar Oct 15 '21 07:10 jeetiss

Nice, thanks for the script. That's a really good idea for showing these kind of problems! 👍

I would like to try to make the "Two siblings and/or parent-child elements should be linkable, so that they always break to next page together" feature if you guys think it would be a good fit (and if it's possible)?

@diegomura @jeetiss ?

asgerhallas avatar Oct 21 '21 12:10 asgerhallas

ofc, but it should be hard to implement this well

Let discuss the API first, should it set via CSS, or via react prop? How it should behave with absolute elements?

I found a CSS spec related to page/columns breaks

Is that api solve your issue? I prefer implement api like that, because other people can be familiar with it, but i'm not sure that it helps

jeetiss avatar Oct 22 '21 07:10 jeetiss

Sorry for the delay. I will look into those and see if that api can solve the problem! :)

asgerhallas avatar Nov 15 '21 12:11 asgerhallas

Any update on this? It would be great to be able to link elements like a header and textarea without having to know the size of the textarea which is not constant and will change depending on data.

OliverLeighC avatar Aug 22 '23 20:08 OliverLeighC

Bumping this. It's probably really difficult to implement, but it would be very useful to have. Some kind of 'link elements' functionality would be great maybe via some kind of param. Or an option to have a 'wrap up to here' element that could be inserted into a view, so it could look like:

<View>
    <Text></Text>
    <WrapUpToHere></WrapUpToHere>
    <Text></Text>
</View>

pinkpigeonltd avatar Feb 15 '24 10:02 pinkpigeonltd