From ebee1bfb01f3cd0a2e3d68c0f8a6023bcaab4f8a Mon Sep 17 00:00:00 2001 From: tintinthong Date: Wed, 9 Sep 2026 23:22:33 +0800 Subject: [PATCH] Let a fill-height isolated template fill the host-mode top card instead of collapsing to its padding MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Since #3934 the top card of the host-mode stack is content-sized (`height: auto`) with an 80cqh floor, so a published page scrolls as a page. Operator mode hands its stack item a definite height instead. The same isolated template therefore meets two sizing contracts, and one of them silently breaks it: a percentage height never resolves against `min-height`, so a root that fills its container (`height: 100%`, `container-type: size`, cqh units) has nothing to fill in host mode and collapses to its padding — a ~150px strip showing whatever overflowed. Make the stack item a single-row grid. A grid area is definite for its item even when the grid's own height is auto, so the `1fr` row hands `.stack-item-card` the floor when content is short and still grows when content is tall. Every layer below already passes `height: 100%` down (`.boxel-card-container`, `.field-component-card.isolated-format`), so the fix is the one missing link; `height: auto` and the page-scroll behaviour stay as they are. Co-Authored-By: Claude Opus 5 (1M context) --- .../app/components/host-mode/stack-item.gts | 10 ++++++ .../host/tests/acceptance/host-mode-test.gts | 36 +++++++++++++++++++ 2 files changed, 46 insertions(+) diff --git a/packages/host/app/components/host-mode/stack-item.gts b/packages/host/app/components/host-mode/stack-item.gts index f9ec2e060ff..5b1fbdcf43e 100644 --- a/packages/host/app/components/host-mode/stack-item.gts +++ b/packages/host/app/components/host-mode/stack-item.gts @@ -216,6 +216,16 @@ export default class HostModeStackItem extends Component { padding-top: var(--boxel-sp-2xl); z-index: 0; pointer-events: none; + /* The top card is content-sized (height: auto, see + styleForStackedCard) with an 80cqh floor so the page scrolls as a + page. But a percentage height never resolves against min-height, so + an isolated template that fills its container (height: 100%, + container-type: size, cqh units) had nothing to fill and collapsed + to its padding. A grid area IS definite for its item even when the + grid's own height is auto: the single 1fr row hands the card the + floor when content is short and still grows when it is tall. */ + display: grid; + grid-template-rows: minmax(0, 1fr); } .host-mode-stack-item:not(.buried) { diff --git a/packages/host/tests/acceptance/host-mode-test.gts b/packages/host/tests/acceptance/host-mode-test.gts index 78d9c57d3ae..4a9e0e77843 100644 --- a/packages/host/tests/acceptance/host-mode-test.gts +++ b/packages/host/tests/acceptance/host-mode-test.gts @@ -686,6 +686,42 @@ module('Acceptance | host mode tests', function (hooks) { assert.dom('[data-test-pet-isolated="Mango"]').exists(); }); + test('a fill-height isolated template fills the top stack card instead of collapsing to its content', async function (assert) { + // Pet's isolated root is `height: 100%`. The top card is content-sized + // (height: auto) with a min-height floor, and a percentage height never + // resolves against min-height — so without a definite box handed down by + // the stack item, the root collapsed to the height of its

. + await visit('/test'); + await click('[data-test-boxel-filter-list-button="All Cards"]'); + await waitFor('[data-test-cards-grid-item]'); + await click( + `[data-test-cards-grid-item="${testHostModeRealmURL}Pet/mango"]`, + ); + await waitFor('[data-test-pet-isolated="Mango"]'); + + let item = document.querySelector( + `[data-test-host-mode-stack-item="${testHostModeRealmURL}Pet/mango"]`, + )!; + let root = document.querySelector( + '[data-test-pet-isolated="Mango"]', + )!.parentElement!; + let itemStyle = getComputedStyle(item); + let offered = + item.getBoundingClientRect().height - + parseFloat(itemStyle.paddingTop) - + parseFloat(itemStyle.paddingBottom); + let filled = root.getBoundingClientRect().height; + + assert.ok( + filled >= offered - 1, + `isolated root fills the stack item (root ${filled}px, item offers ${offered}px)`, + ); + assert.ok( + filled > root.querySelector('h2')!.getBoundingClientRect().height, + 'root is taller than its own content', + ); + }); + test('viewCard tabs persist after stacking and closing cards in host mode', async function (assert) { let primaryCardId = `${testHostModeRealmURL}ViewCardDemo/index`; let firstStackCardId = `${testHostModeRealmURL}ViewCardDemo/secondary`;