Phone layout: stop the radio controls running off the side #46
@@ -4061,12 +4061,18 @@ body[data-operator-layout="broadcast"] #cw-bar-overlay {
|
||||
text-overflow: ellipsis;
|
||||
font-size: 0.75rem;
|
||||
}
|
||||
/* The long ones, smaller so they fit whole rather than ellipsised. These
|
||||
used to sit above the rule that sets the size for all of them — same
|
||||
specificity, so the later one won and nothing was ever shortened. */
|
||||
/* The long ones, sized against the screen rather than at a fixed size.
|
||||
A tab is a fifth of the viewport, so what fits in it is a function of the
|
||||
viewport — and only roughly of the font size, since how wide a platform
|
||||
renders a word varies by ten per cent or more between machines. A fixed
|
||||
0.6rem fit here with ten pixels to spare and clipped in CI.
|
||||
|
||||
(These rules also used to sit above the one that sets the size for all
|
||||
labels — identical specificity, later in the file, so nothing was ever
|
||||
shortened.) */
|
||||
.tab[data-tab="bookmarks"] .tab-label,
|
||||
.tab[data-tab="statistics"] .tab-label {
|
||||
font-size: 0.6rem;
|
||||
font-size: clamp(0.46rem, 2.2vw, 0.62rem);
|
||||
}
|
||||
/* "Digital modes" does not fit at any size worth reading, so the nav shows
|
||||
the short form and the button carries the full one as its label. */
|
||||
@@ -4077,7 +4083,7 @@ body[data-operator-layout="broadcast"] #cw-bar-overlay {
|
||||
overflow: hidden;
|
||||
white-space: nowrap;
|
||||
text-overflow: ellipsis;
|
||||
font-size: 0.6rem;
|
||||
font-size: clamp(0.46rem, 2.2vw, 0.62rem);
|
||||
}
|
||||
.decoder-tab-select {
|
||||
display: block;
|
||||
|
||||
@@ -61,8 +61,14 @@ try {
|
||||
`the rig picker is ${layout.rigSelect}px wide at ${width}px`);
|
||||
|
||||
// The bottom nav keeps its labels — that is what makes it navigation
|
||||
// rather than five glyphs — so the labels have to fit inside a tab, which
|
||||
// is a fifth of a phone. They were being cut off mid-word: "igital mode".
|
||||
// rather than five glyphs — and a label used to overflow its tab and run
|
||||
// into the next one: "Bookmarks igital mode".
|
||||
//
|
||||
// What is asserted is that a label stays inside its own tab and, if it is
|
||||
// too long for it, ends in an ellipsis. Not that it fits: how wide a
|
||||
// platform draws a word varies by more than ten per cent, so "it fits"
|
||||
// passes on the machine it was written on and fails on the next one —
|
||||
// which is what a fixed font size did here.
|
||||
const nav = await page.evaluate(() => {
|
||||
const bar = document.querySelector(".tab-bar-nav");
|
||||
return [...bar.querySelectorAll(".tab")]
|
||||
@@ -70,16 +76,28 @@ try {
|
||||
.map((tab) => {
|
||||
const label = [...tab.querySelectorAll(".tab-label, .tab-label-short")]
|
||||
.find((span) => getComputedStyle(span).display !== "none");
|
||||
const style = label ? getComputedStyle(label) : null;
|
||||
const labelBox = label?.getBoundingClientRect();
|
||||
const tabBox = tab.getBoundingClientRect();
|
||||
return {
|
||||
text: (label?.textContent ?? "").trim(),
|
||||
clipped: label ? label.scrollWidth > label.clientWidth + 1 : false,
|
||||
escapes: labelBox
|
||||
? labelBox.left < tabBox.left - 1 || labelBox.right > tabBox.right + 1
|
||||
: false,
|
||||
truncates: style?.textOverflow === "ellipsis" && style?.overflow !== "visible",
|
||||
empty: !labelBox || labelBox.width < 1,
|
||||
};
|
||||
});
|
||||
});
|
||||
assert.ok(nav.length >= 4, `the bottom nav has ${nav.length} destinations at ${width}px`);
|
||||
const clipped = nav.filter((tab) => tab.clipped).map((tab) => tab.text);
|
||||
assert.deepEqual(clipped, [],
|
||||
`labels cut off at ${width}px: ${clipped.join(", ")}`);
|
||||
const escaped = nav.filter((tab) => tab.escapes).map((tab) => tab.text);
|
||||
assert.deepEqual(escaped, [],
|
||||
`labels overflowing their tab at ${width}px: ${escaped.join(", ")}`);
|
||||
const untruncatable = nav.filter((tab) => !tab.truncates).map((tab) => tab.text);
|
||||
assert.deepEqual(untruncatable, [],
|
||||
`labels that would be cut rather than ellipsised at ${width}px: ${untruncatable.join(", ")}`);
|
||||
const blank = nav.filter((tab) => tab.empty).map((tab, index) => tab.text || `#${index}`);
|
||||
assert.deepEqual(blank, [], `destinations with no label at ${width}px: ${blank.join(", ")}`);
|
||||
}
|
||||
|
||||
// A tab whose visible label is shortened for the nav still has to say what
|
||||
|
||||
Reference in New Issue
Block a user