Skip to content

Commit 23cd385

Browse files
committed
fix(core): set explicit dimensions on data-hf-inner-root wrapper
The prepareFlattenedInnerRoot function creates a wrapper div when inlining sub-compositions. This wrapper had no width/height, which broke CSS height:100% chains — any sub-composition using percentage heights with flexbox centering would collapse to 0px and render content at the top instead of centered. Read data-width/data-height from the inner root and set matching pixel dimensions on the wrapper's inline style. Applied in both the compiler (server-side bundling) and the runtime (browser-side composition loader). Adds a producer regression test with a centered card sub-composition that fails without this fix.
1 parent 793a240 commit 23cd385

7 files changed

Lines changed: 475 additions & 0 deletions

File tree

packages/core/src/compiler/htmlBundler.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -399,6 +399,13 @@ export function prepareFlattenedInnerRoot(innerRoot: Element): Element {
399399
prepared.setAttribute("data-hf-authored-id", authoredRootId);
400400
}
401401
prepared.setAttribute("data-hf-inner-root", "true");
402+
const w = prepared.getAttribute("data-width");
403+
const h = prepared.getAttribute("data-height");
404+
const widthVal = w ? `${w}px` : "100%";
405+
const heightVal = h ? `${h}px` : "100%";
406+
const existingStyle = (prepared.getAttribute("style") || "").trim();
407+
const fill = `width:${widthVal};height:${heightVal}`;
408+
prepared.setAttribute("style", existingStyle ? `${existingStyle};${fill}` : fill);
402409
return prepared;
403410
}
404411

packages/core/src/runtime/compositionLoader.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,10 @@ function prepareFlattenedInnerRoot(innerRoot: HTMLElement): HTMLElement {
8585
prepared.setAttribute("data-hf-authored-id", authoredRootId);
8686
}
8787
prepared.setAttribute("data-hf-inner-root", "true");
88+
const w = prepared.getAttribute("data-width");
89+
const h = prepared.getAttribute("data-height");
90+
if (w) prepared.style.width = `${w}px`;
91+
if (h) prepared.style.height = `${h}px`;
8892
return prepared;
8993
}
9094

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
{
2+
"name": "Sub-composition height:100% centering",
3+
"description": "Verifies that sub-compositions using height:100% + flexbox centering render content centered, not stuck at the top. Regression test for the data-hf-inner-root wrapper missing explicit dimensions.",
4+
"tags": ["sub-composition", "regression", "layout", "centering"],
5+
"minPsnr": 20,
6+
"maxFrameFailures": 10,
7+
"minAudioCorrelation": 0.0,
8+
"maxAudioLagWindows": 120,
9+
"renderConfig": {
10+
"fps": 24
11+
}
12+
}

packages/producer/tests/sub-comp-height-percent/output/compiled.html

Lines changed: 368 additions & 0 deletions
Large diffs are not rendered by default.
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
version https://git-lfs.github.com/spec/v1
2+
oid sha256:86b9674608f35094c3cadd2c72f7c51f535f565f477b6275aef5314a0fe17847
3+
size 68603
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
<template>
2+
<div data-composition-id="centered-card" data-width="1920" data-height="1080">
3+
<style>
4+
[data-composition-id="centered-card"] {
5+
width: 1920px;
6+
height: 1080px;
7+
overflow: hidden;
8+
position: relative;
9+
background: #ffffff;
10+
}
11+
[data-composition-id="centered-card"] .wrapper {
12+
width: 100%;
13+
height: 100%;
14+
position: relative;
15+
}
16+
[data-composition-id="centered-card"] .center-box {
17+
position: absolute;
18+
top: 0;
19+
left: 0;
20+
width: 100%;
21+
height: 100%;
22+
display: flex;
23+
align-items: center;
24+
justify-content: center;
25+
}
26+
[data-composition-id="centered-card"] .card {
27+
width: 600px;
28+
height: 200px;
29+
background: #ea4c89;
30+
border-radius: 24px;
31+
display: flex;
32+
align-items: center;
33+
justify-content: center;
34+
}
35+
[data-composition-id="centered-card"] .card-text {
36+
font-family: sans-serif;
37+
font-size: 64px;
38+
font-weight: 700;
39+
color: #ffffff;
40+
}
41+
</style>
42+
43+
<div class="wrapper">
44+
<div class="center-box">
45+
<div class="card">
46+
<span class="card-text">Centered</span>
47+
</div>
48+
</div>
49+
</div>
50+
51+
<script src="https://cdn.jsdelivr.net/npm/gsap@3.14.2/dist/gsap.min.js"></script>
52+
<script>
53+
(function () {
54+
window.__timelines = window.__timelines || {};
55+
var tl = gsap.timeline({ paused: true });
56+
var S = '[data-composition-id="centered-card"] ';
57+
tl.fromTo(S + '.card', { scale: 0.8, opacity: 0 }, { scale: 1, opacity: 1, duration: 0.5, ease: 'power2.out' }, 0);
58+
window.__timelines['centered-card'] = tl;
59+
})();
60+
</script>
61+
</div>
62+
</template>
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
<!doctype html>
2+
<html lang="en">
3+
<head>
4+
<meta charset="UTF-8" />
5+
<script src="https://cdn.jsdelivr.net/npm/gsap@3.14.2/dist/gsap.min.js"></script>
6+
<style>
7+
body { margin: 0; width: 1920px; height: 1080px; overflow: hidden; background: #000; }
8+
</style>
9+
</head>
10+
<body>
11+
<div data-composition-id="main" data-start="0" data-duration="3" data-width="1920" data-height="1080">
12+
<div data-composition-id="centered-card" data-composition-src="centered-card.html" data-start="0" data-duration="3" data-track-index="0" data-width="1920" data-height="1080"></div>
13+
</div>
14+
<script>
15+
window.__timelines = window.__timelines || {};
16+
window.__timelines["main"] = gsap.timeline({ paused: true });
17+
</script>
18+
</body>
19+
</html>

0 commit comments

Comments
 (0)