From 6f0d1bb35f121ec69b64d136901e60416a339a05 Mon Sep 17 00:00:00 2001 From: Sameh Khamis Date: Wed, 14 Oct 2026 11:07:18 -0700 Subject: [PATCH] fix(ui): keep panels the right rail hides itself in its layout Exclusive presentation hides collapsed right-rail panels with display: none. Skipping every display: none panel also skipped those, so panels the rail had auto-collapsed stayed collapsed after the HUD was hidden or left Tactical. Only panels hidden by other CSS are skipped now. Adds the changelog and current-state notes. --- CHANGELOG.md | 4 ++++ docs/CURRENT-STATE.md | 3 +++ src/ui/panelRails.test.mjs | 26 ++++++++++++++++++++++++++ src/ui/rightPanelRail.js | 9 +++++++-- 4 files changed, 40 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7acdedf6b..7c7ada1b8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # Changelog +- The right rail ignores panels that other CSS hides, such as during an event + view, so they no longer force one-panel-at-a-time layout or collapse visible + panels. Panels the rail collapses itself are still restored. + - Bing Aerial and Bing Labels request HTTPS tiles on HTTP localhost through their ion-backed providers, retaining ion and per-tile attribution without widening the Content Security Policy. diff --git a/docs/CURRENT-STATE.md b/docs/CURRENT-STATE.md index c77d1d8e3..59ba91202 100644 --- a/docs/CURRENT-STATE.md +++ b/docs/CURRENT-STATE.md @@ -1047,6 +1047,9 @@ Automatic collapse remains presentation only, prioritizes the latest explicit panel, and honors keyboard focus on the right. Mobile layout still releases desktop allocation styles. Stable Display allocation avoids unnecessary style writes. This extraction does not change panel positions or layout defaults. +The right rail skips panels hidden by other CSS (computed `display: none`), but +keeps the collapsed panels its own exclusive presentation hides, so automatic +collapse can still be undone. ## Surface keyboard lifecycle diff --git a/src/ui/panelRails.test.mjs b/src/ui/panelRails.test.mjs index de5b3997b..7015c89e2 100644 --- a/src/ui/panelRails.test.mjs +++ b/src/ui/panelRails.test.mjs @@ -723,6 +723,32 @@ test('right layout ignores a CSS-hidden expanded panel when deciding exclusivity ); }); +test('right layout still restores panels that exclusive presentation hides', () => { + const f = fixture('right'); + // Model layers.css: an exclusive rail hides its collapsed panels. + f.options.windowRef.getComputedStyle = (node) => ({ + ...node.computed, + display: + f.stack.classList.contains('layout-exclusive') && + node.classList.contains('collapsed') + ? 'none' + : node.computed.display, + }); + f.expand(f.first, 250); + f.second.classList.add('layout-auto-collapsed'); + f.stack.classList.add('layout-exclusive'); + + f.run(); + assert.equal(f.stack.classList.contains('layout-exclusive'), true); + assert.equal(f.second.getAttribute('aria-hidden'), 'true'); + + f.options.hud.visible = false; + f.run(); + assert.equal(f.second.classList.contains('collapsed'), false); + assert.equal(f.second.classList.contains('layout-auto-collapsed'), false); + assert.deepEqual(f.collapsed, ['second']); +}); + test('right layout ignores a hidden panel: no lane, no gap, no auto-collapse', () => { const f = fixture('right'); const imagery = element('recent-imagery-panel', { height: 0 }); diff --git a/src/ui/rightPanelRail.js b/src/ui/rightPanelRail.js index b62be511c..be49999fd 100644 --- a/src/ui/rightPanelRail.js +++ b/src/ui/rightPanelRail.js @@ -69,12 +69,17 @@ export function layoutRightPanelRail({ // A collapse may schedule one follow-up, which only measures and allocates. const isCollapseRetry = pendingCollapseRetries.delete(stack); - // A floating (lifted-out) panel is not laid out by the rail. + // A floating (lifted-out) panel is not laid out by the rail. Neither is one + // that other CSS hides, such as an event view. Exclusive presentation hides + // collapsed panels itself; those stay in the rail so they can be restored. + const hiddenByRail = (panel) => + stack.classList.contains('layout-exclusive') && + panel.classList.contains('collapsed'); const panels = [...stack.children].filter( (panel) => panel.matches('[data-panel-id]:not(.panel-floating)') && !panel.hidden && - getComputedStyle(panel).display !== 'none', + (hiddenByRail(panel) || getComputedStyle(panel).display !== 'none'), ); if (!hud.visible || hud.variant !== 'tactical') { for (const panel of panels.filter((item) =>