[fix](trx-frontend-http): drop the tabs to icons when the bar runs out of room
CI put the tab strip 9px into the controls at 1440px on a run that passed locally: its system font is wider, and the bar had no move left to make. Controls are moved into the overflow menu until the bar fits, but once all of them were in the menu nothing else gave — the nav may shrink below its content, so the tabs kept full width and ran under the controls, leaving the destinations nearest them unclickable. Labels dropping to icons was the other half of the answer, but it hung off a max-width:1360px media query and so was unavailable at 1440px. That class now goes on by measurement, as the last step after the menu is exhausted, which is the same reasoning the controls' own fit test already uses: how much fits depends on the rig name and on how wide the platform draws the labels, not on the viewport. The class is cleared before measuring so the decision cannot ratchet, and icon widths are fixed, so it always buys back the labels' width. Labels now stay put between 1100px and 1360px while they fit, with the style picker and theme toggle behind the overflow menu instead. The suite could not have caught this: it passed on the fonts of the machine that wrote it. The layout section now repeats its fit check with the bar's text scaled up, which reproduces a wider system font anywhere — with this fix reverted it fails on macOS too. Signed-off-by: Stan Grams <sjg@haxx.space>
This commit is contained in:
@@ -818,6 +818,8 @@ function elementById(id) {
|
||||
return needed <= bar.clientWidth;
|
||||
};
|
||||
const reflowOverflow = () => {
|
||||
const nav = document.querySelector(".tab-bar-nav");
|
||||
nav?.classList.remove("nav-icons-only");
|
||||
overflowOrder.forEach((selector) => {
|
||||
const element = menu.querySelector(selector);
|
||||
if (element) actions.insertBefore(element, wrap);
|
||||
@@ -830,6 +832,7 @@ function elementById(id) {
|
||||
wrap.hidden = false;
|
||||
menu.appendChild(element);
|
||||
}
|
||||
if (nav && !barFits()) nav.classList.add("nav-icons-only");
|
||||
wrap.hidden = menu.children.length === 0;
|
||||
if (wrap.hidden) closeMenu();
|
||||
};
|
||||
|
||||
@@ -1562,11 +1562,17 @@ small { color: var(--text-muted); }
|
||||
}
|
||||
.tab-bar-nav .tab { flex: 0 0 auto; }
|
||||
/* Icons before scrolling: every tab already carries one, and four icons plus
|
||||
* More always fit, so the strip never has to hide a destination. */
|
||||
@media (max-width: 1360px) and (min-width: 701px) {
|
||||
.tab-bar-nav .tab .tab-label { display: none; }
|
||||
.tab-bar-nav .tab .tab-icon, .tab-bar-nav .tab .tab-more-icon { display: block; }
|
||||
.tab-bar-nav .tab { padding: 0.5rem 0.6rem; }
|
||||
* More always fit, so the strip never has to hide a destination. Applied by
|
||||
* measurement (ui-core's reflowOverflow) rather than at a viewport width: how
|
||||
* much fits depends on the rig name and on how wide the platform renders the
|
||||
* labels, so the same width fits on one machine and clips on another.
|
||||
* Bounded below 761px, where the strip becomes the bottom nav and keeps its
|
||||
* labels under the icons. */
|
||||
@media (min-width: 761px) {
|
||||
.tab-bar-nav.nav-icons-only .tab .tab-label { display: none; }
|
||||
.tab-bar-nav.nav-icons-only .tab .tab-icon,
|
||||
.tab-bar-nav.nav-icons-only .tab .tab-more-icon { display: block; }
|
||||
.tab-bar-nav.nav-icons-only .tab { padding: 0.45rem 0.55rem; }
|
||||
}
|
||||
/* The selected destination is boxed, not underlined — the same treatment the
|
||||
mobile bottom nav already used, so one navigation model reads the same at
|
||||
|
||||
Reference in New Issue
Block a user