diff --git a/docs/src/window-regression-fixtures.tsx b/docs/src/window-regression-fixtures.tsx index fa31d59..c5e43da 100644 --- a/docs/src/window-regression-fixtures.tsx +++ b/docs/src/window-regression-fixtures.tsx @@ -284,6 +284,7 @@ const WINDOW_CONTAINMENT_SELECTOR = [ ".greyui-window-header", ".greyui-window-actions", ".greyui-field-action-row", + ".greyui-field-action-row-layout > *", ".greyui-statusbar", ].join(","); diff --git a/src/components-v2.css b/src/components-v2.css index 86a8652..0463e12 100644 --- a/src/components-v2.css +++ b/src/components-v2.css @@ -1440,6 +1440,7 @@ min-width: 0; max-width: 100%; box-sizing: border-box; + contain-intrinsic-inline-size: 22rem; container-type: inline-size; container-name: greyui-field-action-row; } diff --git a/src/styles.css b/src/styles.css index 3a78e98..cfbeddd 100644 --- a/src/styles.css +++ b/src/styles.css @@ -1361,7 +1361,7 @@ .greyui-window-header-layout { display: grid; min-width: 0; - grid-template-columns: minmax(0, 1fr) auto; + grid-template-columns: minmax(0, 1fr) minmax(0, max-content); align-items: start; gap: 14px; } @@ -1387,6 +1387,7 @@ .greyui-window-actions { display: flex; min-width: 0; + max-width: 100%; flex-wrap: wrap; align-items: flex-end; justify-content: flex-end; diff --git a/tests/browser/docs-geometry.spec.ts b/tests/browser/docs-geometry.spec.ts index b85d194..66a9c14 100644 --- a/tests/browser/docs-geometry.spec.ts +++ b/tests/browser/docs-geometry.spec.ts @@ -40,9 +40,15 @@ for (const viewport of viewports) { if (frame === null) continue; const frameRect = frame.getBoundingClientRect(); for (const child of frame.querySelectorAll( - "[data-regression-contained], .greyui-window-tab, .greyui-window-body, .greyui-menubar, .greyui-statusbar", + "[data-regression-contained], .greyui-window-tab, .greyui-window-body, .greyui-menubar, .greyui-field-action-row-layout > *, .greyui-statusbar", )) { - if (child.hidden || child.closest("[hidden]") !== null) continue; + if ( + child.hidden || + child.closest("[hidden]") !== null || + child.getAttribute("aria-hidden") === "true" + ) { + continue; + } const childRect = child.getBoundingClientRect(); if (childRect.left < frameRect.left - 1 || childRect.right > frameRect.right + 1) { messages.push(`${fixture.dataset.regressionWidth}px fixture escapes its frame`); @@ -54,6 +60,33 @@ for (const viewport of viewports) { expect(failures).toEqual([]); + const windowSurfaceFailures = await page.evaluate(() => { + const messages: string[] = []; + for (const windowRoot of document.querySelectorAll(".greyui-window")) { + const windowRect = windowRoot.getBoundingClientRect(); + for (const child of windowRoot.querySelectorAll( + ".greyui-window-frame, .greyui-window-tab, .greyui-window-body, .greyui-window-content, .greyui-window-header, .greyui-window-actions, .greyui-field-action-row-layout > *, .greyui-menubar, .greyui-statusbar", + )) { + if ( + child.hidden || + child.closest("[hidden]") !== null || + child.getAttribute("aria-hidden") === "true" + ) { + continue; + } + const childRect = child.getBoundingClientRect(); + if (childRect.left < windowRect.left - 1 || childRect.right > windowRect.right + 1) { + messages.push( + `${child.getAttribute("data-greyui-component") ?? child.className} escapes ${windowRoot.textContent?.slice(0, 32) ?? "window"}`, + ); + } + } + } + return messages; + }); + + expect(windowSurfaceFailures).toEqual([]); + if (viewport.width === 1280) { await expect(suite.locator("[data-regression-width='280'] .greyui-window-tab")).toHaveCSS( "position", diff --git a/tests/styles.test.ts b/tests/styles.test.ts index e8dbcee..f07a4e3 100644 --- a/tests/styles.test.ts +++ b/tests/styles.test.ts @@ -128,8 +128,9 @@ describe("default theme contrast", () => { /\.greyui-window-header\s*\{[\s\S]*?container-name:\s*greyui-window-header/, ); expect(css).toMatch( - /\.greyui-window-header-layout\s*\{[\s\S]*?grid-template-columns:\s*minmax\(0, 1fr\) auto/, + /\.greyui-window-header-layout\s*\{[\s\S]*?grid-template-columns:\s*minmax\(0, 1fr\) minmax\(0, max-content\)/, ); + expect(css).toMatch(/\.greyui-window-actions\s*\{[\s\S]*?max-width:\s*100%/); expect(css).toMatch( /@container greyui-window-header \(max-width: 520px\)[\s\S]*?\[data-layout="auto"\]/, ); @@ -141,6 +142,9 @@ describe("default theme contrast", () => { expect(css).toMatch( /\.greyui-field-action-row\s*\{[\s\S]*?container-name:\s*greyui-field-action-row/, ); + expect(css).toMatch( + /\.greyui-field-action-row\s*\{[\s\S]*?contain-intrinsic-inline-size:\s*22rem/, + ); expect(css).toMatch( /@container greyui-field-action-row \(max-width: 350px\)[\s\S]*?\[data-layout="auto"\]/, );