diff --git a/packages/core/src/Renderable.ts b/packages/core/src/Renderable.ts index 9db08215..9c6e8bc9 100644 --- a/packages/core/src/Renderable.ts +++ b/packages/core/src/Renderable.ts @@ -1109,8 +1109,10 @@ export abstract class Renderable extends BaseRenderable { this._screenX = parentScreenX + this._x + this._translateX this._screenY = parentScreenY + this._y + this._translateY - const newWidth = Math.max(layout.width, 1) - const newHeight = Math.max(layout.height, 1) + // Yoga reports NaN for a node attached after this frame's layout pass. + // Keep the last size until the next pass lays the node out. + const newWidth = Number.isNaN(layout.width) ? oldWidth : Math.max(layout.width, 1) + const newHeight = Number.isNaN(layout.height) ? oldHeight : Math.max(layout.height, 1) const sizeChanged = oldWidth !== newWidth || oldHeight !== newHeight this._widthValue = newWidth diff --git a/packages/core/src/tests/renderable.test.ts b/packages/core/src/tests/renderable.test.ts index 6fdfca8a..5765b34a 100644 --- a/packages/core/src/tests/renderable.test.ts +++ b/packages/core/src/tests/renderable.test.ts @@ -890,6 +890,18 @@ describe("Renderable - Child Management", () => { expect(grandchild.height).toBeGreaterThan(0) }) + test("child added during the layout pass is sized by the next pass", async () => { + const sizes: number[][] = [] + const child = new TestRenderable(testRenderer, { flexGrow: 1, onSizeChange: () => sizes.push([child.width]) }) + const parent = new TestRenderable(testRenderer, { width: "100%", onSizeChange: () => parent.add(child) }) + testRenderer.root.add(parent) + + await renderOnce() + await renderOnce() + + expect(sizes).toEqual([[testRenderer.width]]) + }) + test("children added via insertBefore receive correct layout on first render", async () => { const parent = new TestRenderable(testRenderer, { id: "parent",