Skip to content

Commit ffaa476

Browse files
committed
fix: adjust box.top for remaining siblings when breaking pages without relayout
When a node triggers a split in splitNodes, the remaining siblings (via nodes.slice(i+1)) were pushed to nextChildren with their original box.top values. Previously relayout on nextPage corrected these positions, but after the relayout removal optimization, nodes like footers with marginTop:'auto' retained large top values and were incorrectly classified as "outside" the next page, causing them to appear alone on a separate page.
1 parent 23d9070 commit ffaa476

1 file changed

Lines changed: 14 additions & 4 deletions

File tree

packages/layout/src/steps/resolvePagination.ts

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,16 @@ const splitNodes = (height: number, contentArea: number, nodes: SafeNode[]) => {
9797
}
9898
};
9999

100+
// Adjust box.top for remaining nodes that are pushed to nextChildren without relayout.
101+
// Fixed nodes keep their positions (absolute positioning).
102+
const adjustRemaining = (fromIndex: number): SafeNode[] =>
103+
nodes.slice(fromIndex).map((node) => {
104+
if (isFixed(node)) return node;
105+
return Object.assign({}, node, {
106+
box: Object.assign({}, node.box, { top: node.box.top - height }),
107+
});
108+
});
109+
100110
let hasNonFixedPrevious = false;
101111

102112
const length = nodes.length;
@@ -122,7 +132,7 @@ const splitNodes = (height: number, contentArea: number, nodes: SafeNode[]) => {
122132
const fitsInsidePage = nodeHeight <= contentArea;
123133
if (!fitsInsidePage && !canNodeWrap(child)) {
124134
currentChildren.push(child);
125-
nextChildren.push(...nodes.slice(i + 1));
135+
nextChildren.push(...adjustRemaining(i + 1));
126136
warnUnavailableSpace(child);
127137
break;
128138
}
@@ -142,7 +152,7 @@ const splitNodes = (height: number, contentArea: number, nodes: SafeNode[]) => {
142152
const next = Object.assign({}, child, { box, props });
143153

144154
pushFutureFixed(currentChildren, i);
145-
nextChildren.push(next, ...nodes.slice(i + 1));
155+
nextChildren.push(next, ...adjustRemaining(i + 1));
146156
break;
147157
}
148158

@@ -154,15 +164,15 @@ const splitNodes = (height: number, contentArea: number, nodes: SafeNode[]) => {
154164
if (currentChildren.length === 0) {
155165
currentChildren.push(child);
156166
pushFutureFixed(currentChildren, i);
157-
nextChildren.push(...nodes.slice(i + 1));
167+
nextChildren.push(...adjustRemaining(i + 1));
158168
} else {
159169
const box = Object.assign({}, child.box, {
160170
top: child.box.top - height,
161171
});
162172
const next = Object.assign({}, child, { box });
163173

164174
pushFutureFixed(currentChildren, i);
165-
nextChildren.push(next, ...nodes.slice(i + 1));
175+
nextChildren.push(next, ...adjustRemaining(i + 1));
166176
}
167177
break;
168178
}

0 commit comments

Comments
 (0)