mirror of
https://github.com/AmruthPillai/Reactive-Resume.git
synced 2026-10-04 02:33:47 +10:00
fix(pdf): preserve page breaks while rewinding list companions
This commit is contained in:
@@ -163,4 +163,43 @@ describe("list marker pagination (#3344)", () => {
|
||||
expect(result.marker).toBe(0);
|
||||
expect(result.first).toBe(0);
|
||||
});
|
||||
it.each([
|
||||
[false, 0],
|
||||
[false, 180],
|
||||
[true, 0],
|
||||
[true, 180],
|
||||
] as const)(
|
||||
"consumes reordered marker page breaks and continues long content (RTL %s, margin %i)",
|
||||
async (rtl, margin) => {
|
||||
const result = await listPages(
|
||||
margin,
|
||||
30,
|
||||
"list-item-content { order: -1; } list-marker { break-before: page; }",
|
||||
{ rtl },
|
||||
);
|
||||
expect(result.first).toBe(1);
|
||||
expect(result.marker).toBe(result.first);
|
||||
expect(result.last).toBeGreaterThan(result.first);
|
||||
expect(result.pages.flat().join(" ").match(/•/g)).toHaveLength(1);
|
||||
expect(
|
||||
result.pages
|
||||
.flat()
|
||||
.join(" ")
|
||||
.match(/\bSome\b/g),
|
||||
).toHaveLength(30);
|
||||
},
|
||||
);
|
||||
it.each([false, true])("consumes marker-first page breaks without overflowing (RTL %s)", async (rtl) => {
|
||||
const result = await listPages(180, 30, "list-marker { order: -1; break-before: page; }", { rtl });
|
||||
expect(result.first).toBe(1);
|
||||
expect(result.marker).toBe(result.first);
|
||||
expect(result.last).toBeGreaterThan(result.first);
|
||||
expect(result.pages.flat().join(" ").match(/•/g)).toHaveLength(1);
|
||||
expect(
|
||||
result.pages
|
||||
.flat()
|
||||
.join(" ")
|
||||
.match(/\bSome\b/g),
|
||||
).toHaveLength(30);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,8 +1,20 @@
|
||||
diff --git a/lib/index.js b/lib/index.js
|
||||
index 18c2618f4630b3c1296c8c3cac317b8d7666bbe8..dbe7b6eaa6817e8cb0f526a68cdaa92b4ca78eb7 100644
|
||||
index 18c2618f4630b3c1296c8c3cac317b8d7666bbe8..d4471eda64ee99695bedf01f7a0098806d2fc961 100644
|
||||
--- a/lib/index.js
|
||||
+++ b/lib/index.js
|
||||
@@ -3196,7 +3196,34 @@ const splitChildren = (height, contentArea, node) => {
|
||||
@@ -3163,7 +3163,10 @@ const splitNodes = (height, contentArea, nodes) => {
|
||||
if (shouldSplit) {
|
||||
const [currentChild, nextChild] = split(child, height, contentArea);
|
||||
// All children are moved to the next page, it doesn't make sense to show the parent on the current page
|
||||
- if (child.children.length > 0 && currentChild.children.length === 0) {
|
||||
+ // Tagged list companions can intentionally rewind all their children.
|
||||
+ // Keep their empty fragment and already-consumed break state instead
|
||||
+ // of restoring the unsplit row (which can exceed a whole page).
|
||||
+ if (child.children.length > 0 && currentChild.children.length === 0 && !child.props['data-resume-list-item']) {
|
||||
// But if the current page is empty then we can just include the parent on the current page
|
||||
if (currentChildren.length === 0) {
|
||||
currentChildren.push(child, ...futureFixedNodes);
|
||||
@@ -3196,7 +3199,45 @@ const splitChildren = (height, contentArea, node) => {
|
||||
};
|
||||
const splitView = (node, height, contentArea) => {
|
||||
const [currentNode, nextNode] = splitNode(node, height);
|
||||
@@ -19,16 +31,27 @@ index 18c2618f4630b3c1296c8c3cac317b8d7666bbe8..dbe7b6eaa6817e8cb0f526a68cdaa92b
|
||||
+ const markerIndex = node.children.findIndex((child) => child.props['data-resume-list-marker']);
|
||||
+ const contentIndex = node.children.findIndex((child) => child.props['data-resume-list-content']);
|
||||
+ const hasMarker = (children) => children.some((child) => child.props['data-resume-list-marker']);
|
||||
+ const deferredMarker = nextChildren.find((child) => child.props['data-resume-list-marker']);
|
||||
+ if (markerIndex !== -1 && !hasMarker(currentChilds) && hasMarker(nextChildren) && hasText(content(currentChilds))) {
|
||||
+ // An authored presence hint can defer a marker that follows content
|
||||
+ // in RTL or semantic order. Defer the unsplit content with it.
|
||||
+ // A presence hint or page break can defer a marker after content.
|
||||
+ // Defer unsplit content while retaining the marker's consumed flags.
|
||||
+ currentChilds = currentChilds.filter((child) => !child.props['data-resume-list-content']);
|
||||
+ nextChildren = node.children.filter((child) => child.props['data-resume-list-content'] || child.props['data-resume-list-marker']);
|
||||
+ nextChildren = node.children
|
||||
+ .filter((child) => child.props['data-resume-list-content'] || child.props['data-resume-list-marker'])
|
||||
+ .map((child) => child.props['data-resume-list-marker']
|
||||
+ ? { ...child, props: deferredMarker.props }
|
||||
+ : child);
|
||||
+ } else if (markerIndex !== -1 && !hasText(content(currentChilds)) && hasText(content(nextChildren))) {
|
||||
+ // The first text did not fit. Preserve the authored marker/content
|
||||
+ // order when moving the marker to the next fragment of this row.
|
||||
+ const marker = node.children[markerIndex];
|
||||
+ const nextMarker = { ...marker, box: { ...marker.box, top: 0 } };
|
||||
+ // Preserve break: false after splitNodes has consumed an explicit
|
||||
+ // page break; restoring the original props would replay it.
|
||||
+ const nextMarker = {
|
||||
+ ...marker,
|
||||
+ props: deferredMarker?.props || marker.props,
|
||||
+ box: { ...marker.box, top: 0 },
|
||||
+ };
|
||||
+ currentChilds = currentChilds.filter((child) => !child.props['data-resume-list-marker']);
|
||||
+ nextChildren = nextChildren.filter((child) => !child.props['data-resume-list-marker']);
|
||||
+ if (markerIndex < contentIndex) nextChildren.unshift(nextMarker);
|
||||
|
||||
Generated
+3
-3
@@ -12,7 +12,7 @@ overrides:
|
||||
uuid@<11.1.1: ^11.1.1
|
||||
|
||||
patchedDependencies:
|
||||
'@react-pdf/layout@5.2.0': d1e4335e8221591bf9847f5ede5bf12fc0f1b254568b303909711e36e3f7a995
|
||||
'@react-pdf/layout@5.2.0': add03fa9efd8cf4ab004a49c4c37bdf11f6d82109bfd3f6a2c48b7473aad29ae
|
||||
'@react-pdf/textkit': 092a6fe8baf3c472a81cdf2ab52a00ec98ef3364e1b8e744005dbcf219a8a213
|
||||
|
||||
importers:
|
||||
@@ -11198,7 +11198,7 @@ snapshots:
|
||||
jay-peg: 1.1.1
|
||||
png-js: 2.0.0
|
||||
|
||||
'@react-pdf/layout@5.2.0(patch_hash=d1e4335e8221591bf9847f5ede5bf12fc0f1b254568b303909711e36e3f7a995)':
|
||||
'@react-pdf/layout@5.2.0(patch_hash=add03fa9efd8cf4ab004a49c4c37bdf11f6d82109bfd3f6a2c48b7473aad29ae)':
|
||||
dependencies:
|
||||
'@react-pdf/fns': 3.1.3
|
||||
'@react-pdf/image': 3.1.2
|
||||
@@ -11239,7 +11239,7 @@ snapshots:
|
||||
'@babel/runtime': 7.29.7
|
||||
'@react-pdf/fns': 3.1.3
|
||||
'@react-pdf/font': 4.1.2
|
||||
'@react-pdf/layout': 5.2.0(patch_hash=d1e4335e8221591bf9847f5ede5bf12fc0f1b254568b303909711e36e3f7a995)
|
||||
'@react-pdf/layout': 5.2.0(patch_hash=add03fa9efd8cf4ab004a49c4c37bdf11f6d82109bfd3f6a2c48b7473aad29ae)
|
||||
'@react-pdf/primitives': 4.4.0
|
||||
'@react-pdf/reconciler': 2.0.0(react@19.2.8)
|
||||
'@react-pdf/render': 4.7.0
|
||||
|
||||
Reference in New Issue
Block a user