Merge pull request 'fix(ui): measure real nav height (--fc-nav-h) — Explore fits on 1080p, no breadcrumb tuck (#1481)' (#227) from dev into main
Build images / sign-extension (push) Successful in 3s
CI / lint (push) Successful in 3s
Build images / build-agent (push) Successful in 6s
Build images / build-ml (push) Successful in 8s
Build images / build-web (push) Successful in 9s
CI / frontend-build (push) Successful in 21s
CI / backend-lint-and-test (push) Successful in 32s
CI / integration (push) Successful in 3m50s
Build images / sign-extension (push) Successful in 3s
CI / lint (push) Successful in 3s
Build images / build-agent (push) Successful in 6s
Build images / build-ml (push) Successful in 8s
Build images / build-web (push) Successful in 9s
CI / frontend-build (push) Successful in 21s
CI / backend-lint-and-test (push) Successful in 32s
CI / integration (push) Successful in 3m50s
This commit was merged in pull request #227.
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<header class="fc-topnav" :class="{ 'fc-topnav--chrome': hasStickyChrome }">
|
||||
<header ref="navEl" class="fc-topnav" :class="{ 'fc-topnav--chrome': hasStickyChrome }">
|
||||
<div class="fc-nav-left">
|
||||
<RouterLink :to="FRONT_DOOR" class="fc-brand" aria-label="FabledCurator home">
|
||||
<img src="/favicon.svg" alt="" class="fc-brand__glyph" width="22" height="22" />
|
||||
@@ -64,14 +64,32 @@
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { computed, onMounted } from 'vue'
|
||||
import { computed, onBeforeUnmount, onMounted, ref } from 'vue'
|
||||
import { useRoute } from 'vue-router'
|
||||
import router, { FRONT_DOOR } from '../router.js'
|
||||
import { useSystemStore } from '../stores/system.js'
|
||||
import PipelineStatusChip from './PipelineStatusChip.vue'
|
||||
|
||||
const system = useSystemStore()
|
||||
onMounted(() => system.refreshHealth())
|
||||
|
||||
// Publish the nav's REAL height as --fc-nav-h so full-height workspaces
|
||||
// (Explore/Subscriptions) and sticky sub-headers pin to it exactly instead of a
|
||||
// hardcoded 64px that Vuetify 4's MD3 sizing broke — the Explore breadcrumb was
|
||||
// tucking under a taller nav (#1481). ResizeObserver keeps it live as the nav
|
||||
// reflows (per-view teleported actions, mobile breakpoint, chip state changes).
|
||||
const navEl = ref(null)
|
||||
let navRO = null
|
||||
onMounted(() => {
|
||||
system.refreshHealth()
|
||||
if (navEl.value && 'ResizeObserver' in window) {
|
||||
navRO = new ResizeObserver(() => {
|
||||
const h = navEl.value?.offsetHeight
|
||||
if (h) document.documentElement.style.setProperty('--fc-nav-h', `${h}px`)
|
||||
})
|
||||
navRO.observe(navEl.value)
|
||||
}
|
||||
})
|
||||
onBeforeUnmount(() => { navRO?.disconnect() })
|
||||
|
||||
// Views that pin a sticky sub-header (filter bar / tabs) directly under the nav
|
||||
// declare `meta.stickyChrome`. On those, the nav doesn't fade to transparent at
|
||||
|
||||
@@ -306,7 +306,7 @@ function pushFilter(mutate) {
|
||||
frosted block pinned directly under the 64px TopNav and continuous with it. */
|
||||
.fc-filterbar-wrap {
|
||||
position: sticky;
|
||||
top: 64px;
|
||||
top: var(--fc-nav-h, 64px); /* pins at the nav's real measured bottom (#1481) */
|
||||
z-index: 5;
|
||||
/* Attach to the TopNav: cancel the v-container's top padding (pt-2 = 8px)
|
||||
so the bar sits flush at 64px even at scroll 0 — without this it detaches
|
||||
|
||||
@@ -78,6 +78,13 @@
|
||||
:root {
|
||||
--fc-chrome-rgb: 20, 23, 26; /* obsidian #14171A — matches the TopNav */
|
||||
--fc-chrome-seam: 0.46; /* alpha where the nav hands off to the sub-header */
|
||||
/* Actual TopNav height, measured live (ResizeObserver in TopNav.vue) and used
|
||||
by full-height workspaces (Explore/Subscriptions: calc(100vh - var)) and by
|
||||
every sticky sub-header pinned beneath the nav (top: var). This was a
|
||||
hardcoded 64px in ~6 places; Vuetify 4's MD3 sizing made the real nav a
|
||||
different height, so the Explore workspace overflowed and its breadcrumb
|
||||
tucked under the nav (#1481). This fallback is only used pre-measure. */
|
||||
--fc-nav-h: 64px;
|
||||
}
|
||||
/* Applied to a sticky sub-header so it continues the nav's fade instead of
|
||||
restarting it. Percentage stops so the fade always spans the element's height
|
||||
|
||||
@@ -154,7 +154,7 @@ function clearFilter(key) {
|
||||
<style scoped>
|
||||
.fc-browse__head {
|
||||
position: sticky;
|
||||
top: 64px; /* directly under AppShell's 64px sticky TopNav */
|
||||
top: var(--fc-nav-h, 64px); /* pins at the nav's real measured bottom (#1481) */
|
||||
z-index: 4;
|
||||
/* Background is the shared .fc-chrome-continues fade — it continues the nav's
|
||||
gradient instead of a solid surface band (operator 2026-07-13). */
|
||||
|
||||
@@ -286,10 +286,13 @@ onUnmounted(() => {
|
||||
<style scoped>
|
||||
.fc-muted { color: rgb(var(--v-theme-on-surface-variant)); }
|
||||
|
||||
/* Full-height workspace under the sticky top nav. */
|
||||
/* Full-height workspace under the sticky top nav. --fc-nav-h is the nav's REAL
|
||||
measured height (set by TopNav) — a hardcoded 64px here overflowed the
|
||||
viewport under Vuetify 4's taller nav and tucked the breadcrumb under it
|
||||
(#1481). Panes scroll internally, so an exact fit keeps everything on screen. */
|
||||
.fc-ex {
|
||||
display: flex; flex-direction: column;
|
||||
height: calc(100vh - 64px);
|
||||
height: calc(100vh - var(--fc-nav-h, 64px));
|
||||
min-height: 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -299,7 +299,7 @@ onMounted(() => {
|
||||
band (operator 2026-07-13). */
|
||||
.fc-series__head {
|
||||
position: sticky;
|
||||
top: 64px;
|
||||
top: var(--fc-nav-h, 64px); /* pins at the nav's real measured bottom (#1481) */
|
||||
z-index: 4;
|
||||
padding-bottom: 12px;
|
||||
}
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
continues the nav's gradient across the strip (operator 2026-07-13). -->
|
||||
<v-tabs
|
||||
v-model="tab" color="accent" class="mb-4 fc-chrome-continues"
|
||||
style="position: sticky; top: 64px; z-index: 4;"
|
||||
style="position: sticky; top: var(--fc-nav-h, 64px); z-index: 4;"
|
||||
>
|
||||
<v-tab value="overview">Overview</v-tab>
|
||||
<v-tab value="activity">Activity</v-tab>
|
||||
|
||||
@@ -55,8 +55,8 @@ const { tab } = useTabQuery(VALID_TABS, 'subscriptions')
|
||||
/* Fixed-height hub: the tabs (and each tab's sticky control bar) stay
|
||||
put while ONLY the tab content scrolls — previously the whole view
|
||||
scrolled instead of just the subscription list (operator-flagged
|
||||
2026-05-28). 64px = the TopNav height (AppShell .fc-content pad-top). */
|
||||
height: calc(100vh - 64px);
|
||||
2026-05-28). --fc-nav-h = the TopNav's real measured height (#1481). */
|
||||
height: calc(100vh - var(--fc-nav-h, 64px));
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
overflow: hidden;
|
||||
|
||||
Reference in New Issue
Block a user