From fd34fa535c8dd34d83160d69d597cf60e7b58126 Mon Sep 17 00:00:00 2001 From: dev Date: Sat, 23 May 2026 18:22:47 +0200 Subject: [PATCH] fix(eidos navigation-menu): Content floats as popover, not inline MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bug: Content panels were rendering inline below their Triggers, pushing the bar's flex layout. They should float anchored to the Item the same way Radix / bits-ui mega-menus do. Two changes: 1. **Item** — was `flex-direction: column`, which made Content stack below Trigger in the flex flow. Switched to inline-flex with `align-items: center`. `position: relative` stays so it remains the anchor element. Vertical orientation gets `display: flex`. 2. **Content** — added `position: absolute; inset-block-start: calc(100% + var(--space-1)); inset-inline-start: 0; z-index: 50`. The panel now sits 4px below the trigger row, left-aligned to the Item (extends via `min-inline-size: 14rem` past the trigger), and stacks above the rest of the page. Vertical orientation flips the anchor: `inset-block-start: 0; inset-inline-start: calc(100% + var(--space-1))` so the panel opens to the right of the trigger column. Verified in browser: contentTop=623, triggerBottom=619, position=absolute, z-index=50, bar layout no longer pushed. Co-Authored-By: Claude Opus 4.7 (1M context) --- .../navigation-menu/navigation-menu.css | 27 +++++++++++++++++-- 1 file changed, 25 insertions(+), 2 deletions(-) diff --git a/src/uix/eidos/components/navigation-menu/navigation-menu.css b/src/uix/eidos/components/navigation-menu/navigation-menu.css index f3efee413..21189367b 100644 --- a/src/uix/eidos/components/navigation-menu/navigation-menu.css +++ b/src/uix/eidos/components/navigation-menu/navigation-menu.css @@ -63,11 +63,17 @@ align-items: stretch; } -/* ── Item ─ */ +/* ── Item ─ + * + * `position: relative` makes the Item the positioning anchor for its + * Content panel — Content is `position: absolute` below so opening it + * doesn't push the bar. The Item only lays out its Trigger / Link + * inline. + */ [data-navigation-menu-item] { position: relative; display: inline-flex; - flex-direction: column; + align-items: center; } /* ── Trigger (and Link share the same in-bar chrome) ─ */ @@ -147,6 +153,16 @@ * directional slide animation per `data-motion` (from / to). */ [data-navigation-menu-content] { + /* Floats below the parent Item — taken out of the bar's flex flow so + * opening the mega-menu doesn't push siblings. `top: 100%` anchors + * it just below the trigger row; `inset-inline-start: 0` left-aligns + * to the Item, but the panel itself has a `min-inline-size` so it + * extends past the trigger if needed. */ + position: absolute; + inset-block-start: calc(100% + var(--space-1)); + inset-inline-start: 0; + z-index: 50; + min-inline-size: 14rem; padding: var(--space-4); border: 1px solid var(--color-border-default); @@ -157,6 +173,13 @@ outline: none; } +/* Vertical orientation flips the anchor — Content opens to the right + * of the trigger column instead of below. */ +[data-navigation-menu][data-orientation='vertical'] [data-navigation-menu-content] { + inset-block-start: 0; + inset-inline-start: calc(100% + var(--space-1)); +} + [data-navigation-menu-content][data-state='open'] { animation: navigation-menu-enter var(--duration-fast) var(--ease-out); }