fix(home): contain app category scroller on mobile (#3281)

Constrain the mobile app-category strip to the available content width while preserving internal horizontal scrolling. Scope the CSS regression contract to the exact nested mobile rule.
This commit is contained in:
Vyctor H. Brzezowski
2026-08-03 13:51:44 -03:00
committed by GitHub
parent 4ae518011a
commit dc7a0f4de1
2 changed files with 31 additions and 2 deletions
+29 -2
View File
@@ -19,8 +19,7 @@ function cssRule(css: string, selector: string) {
function cssMediaContaining(css: string, query: string, required: readonly string[]) {
let start = css.indexOf(`@media ${query}`);
while (start >= 0) {
const nextMedia = css.indexOf("@media ", start + 1);
const block = css.slice(start, nextMedia === -1 ? undefined : nextMedia);
const block = balancedCssBlock(css, start, `@media ${query}`);
if (required.every((snippet) => block.includes(snippet))) return block;
start = css.indexOf(`@media ${query}`, start + 1);
}
@@ -36,6 +35,22 @@ function cssBlock(css: string, selector: string) {
return css.slice(start, end + 2);
}
function balancedCssBlock(css: string, start: number, label: string) {
const open = css.indexOf("{", start);
expect(open, `Missing opening brace for ${label}`).toBeGreaterThanOrEqual(0);
let depth = 0;
for (let index = open; index < css.length; index += 1) {
if (css[index] === "{") depth += 1;
if (css[index] !== "}") continue;
depth -= 1;
if (depth === 0) return css.slice(start, index + 1);
}
throw new Error(`Unclosed CSS block for ${label}`);
}
function tokenValue(css: string, selector: string, token: string) {
const block = cssBlock(css, selector);
const match = block.match(new RegExp(`${token}:\\s*(#[0-9a-fA-F]{6})`));
@@ -385,6 +400,18 @@ describe("restored UI design contract", () => {
expect(cssRule(css, ".home-v2-listing-row::before")).toContain("border-radius: 0");
});
it("keeps the mobile app-category scroller within the page width", () => {
const mobileBlock = cssMediaContaining(styles(), "(max-width: 760px)", [
".home-v2-apps-categories {",
]);
const scroller = mobileBlock.match(/\.home-v2-apps-categories \{([^}]*)\}/)?.[1];
expect(scroller, "Missing .home-v2-apps-categories rule").toBeTruthy();
expect(scroller).toMatch(/width:\s*100%/);
expect(scroller).toMatch(/min-width:\s*0/);
expect(scroller).toMatch(/overflow-x:\s*auto/);
});
it("requires the restored footer columns and mobile section toggles", () => {
const footerSource = footer();
const navSource = navItems();
+2
View File
@@ -27851,6 +27851,8 @@ a.home-v2-apps-see-all:focus-visible svg {
}
.home-v2-apps-categories {
width: 100%;
min-width: 0;
flex-wrap: nowrap;
overflow-x: auto;
overflow-y: hidden;