refactor(storybook): hide page headers and preserve accessibility
StoryPageHeader no longer shows the page title, kicker, description or the SW group notice; it renders only a visually hidden H1 with the Story title, so the preview keeps a page heading for screen readers while the first section starts at the top gutter (unchanged position). - OrgChart verify-p8 / p9 / p9-1 / p9-2-composition wait for the first visible StoryPage content block and read the page H1 instead of .sb-page-title; existing expectations are unchanged. - SW overview browser test clicks the page gutter as its outside-click target. - Drop the unused .sb-page-description from the SW Storybook hide rules. - Update the Storybook page frame rule in the project guideline.
This commit is contained in:
1 parent
f22428548a
commit
63b3ab010b
11 files changed
+59
-105
No files matched your search
@@ -46,8 +46,11 @@ page.setDefaultTimeout(20000);
|
||||
async function settle(target = page) {
|
||||
await target.evaluate(async () => { await document.fonts.ready; for (let i = 0; i < 5; i++) await new Promise(resolve => requestAnimationFrame(resolve)); });
|
||||
}
|
||||
// The Storybook page title is a visually hidden H1 (2026-11-11), so readiness waits for the first visible content block
|
||||
// of the StoryPage frame, and page identity reads the H1 text (the Story's accessible page heading).
|
||||
const pageContent = '.sb-page-inner > :not(h1)', pageHeading = '.sb-page-inner > h1';
|
||||
async function ready(expected) {
|
||||
await page.locator('.sb-page-title').waitFor();
|
||||
await page.locator(pageContent).first().waitFor();
|
||||
await page.waitForFunction(expected => {
|
||||
const hosts = [...document.querySelectorAll('.hm-orgchart-host,.hm-orgchart-component-host')];
|
||||
if (!hosts.length) return false;
|
||||
@@ -76,10 +79,8 @@ async function commonStyle() {
|
||||
const properties = {
|
||||
'.sb-page': ['fontFamily', 'color', 'paddingTop', 'paddingBottom', 'boxSizing', 'width'],
|
||||
'.sb-page-inner': ['width', 'boxSizing'],
|
||||
'.sb-page-header': ['paddingBottom', 'borderBottomWidth', 'borderBottomColor', 'fontSize', 'lineHeight'],
|
||||
'.sb-page-kicker': ['fontSize', 'fontWeight', 'color', 'marginBottom'],
|
||||
'.sb-page-title': ['fontSize', 'fontWeight', 'lineHeight', 'marginTop', 'marginBottom'],
|
||||
'.sb-page-description': ['fontSize', 'fontWeight', 'lineHeight', 'marginBottom'],
|
||||
// The visible header (kicker, title, description) is no longer rendered; the page H1 stays visually hidden.
|
||||
'.sb-page-inner > h1': ['position', 'width', 'height', 'overflow', 'clipPath'],
|
||||
'.sb-page-section': ['marginTop', 'scrollMarginTop'],
|
||||
'.sb-page-section-header': ['paddingBottom', 'marginBottom', 'borderBottomWidth', 'borderBottomColor'],
|
||||
'.sb-page-section-title': ['fontSize', 'lineHeight', 'fontWeight', 'marginTop', 'marginBottom'],
|
||||
@@ -105,7 +106,7 @@ async function pageGeometry() {
|
||||
return page.evaluate(() => {
|
||||
const rect = element => { if (!element) return null; const r = element.getBoundingClientRect(); return { x: r.x, y: r.y, width: r.width, height: r.height, right: r.right, bottom: r.bottom }; };
|
||||
const documentGeometry = { scrollWidth: document.documentElement.scrollWidth, clientWidth: document.documentElement.clientWidth, innerWidth, scrollHeight: document.documentElement.scrollHeight, clientHeight: document.documentElement.clientHeight };
|
||||
const frame = { page: rect(document.querySelector('.sb-page')), inner: rect(document.querySelector('.sb-page-inner')), title: document.querySelector('.sb-page-title')?.textContent };
|
||||
const frame = { page: rect(document.querySelector('.sb-page')), inner: rect(document.querySelector('.sb-page-inner')), title: document.querySelector('.sb-page-inner > h1')?.textContent };
|
||||
const shadow = document.querySelector('.hm-orgchart-host')?.shadowRoot;
|
||||
const wrapper = shadow?.querySelector('.hm-orgchart-composition');
|
||||
const stage = shadow?.querySelector('.hm-orgchart-stage');
|
||||
@@ -159,10 +160,10 @@ try {
|
||||
await manager.waitForFunction(() => {
|
||||
const preview = document.querySelector('#storybook-preview-iframe')?.contentDocument;
|
||||
const hosts = [...preview?.querySelectorAll('.hm-orgchart-component-host') ?? []];
|
||||
return preview?.querySelector('.sb-page-title')?.textContent === 'Overview' && hosts.length > 0
|
||||
return preview?.querySelector('.sb-page-inner > h1')?.textContent === 'Overview' && hosts.length > 0
|
||||
&& hosts.every(host => host.shadowRoot && [...host.shadowRoot.querySelectorAll('link[rel="stylesheet"]')].every(link => link.sheet));
|
||||
});
|
||||
await manager.frameLocator('#storybook-preview-iframe').locator('.sb-page-title').evaluate(async element => {
|
||||
await manager.frameLocator('#storybook-preview-iframe').locator(pageHeading).evaluate(async element => {
|
||||
const document = element.ownerDocument, view = document.defaultView;
|
||||
await document.fonts.ready;
|
||||
for (let i = 0; i < 5; i++) await new Promise(resolve => view.requestAnimationFrame(resolve));
|
||||
@@ -198,7 +199,7 @@ try {
|
||||
await gotoStory(story);
|
||||
const rendered = await page.evaluate(({ selectors }) => {
|
||||
const hosts = [...document.querySelectorAll('.hm-orgchart-host,.hm-orgchart-component-host')];
|
||||
return { title: document.querySelector('.sb-page-title')?.textContent, hosts: hosts.length,
|
||||
return { title: document.querySelector('.sb-page-inner > h1')?.textContent, hosts: hosts.length,
|
||||
specimens: Object.fromEntries(selectors.map(selector => [selector, hosts.reduce((total, host) => total + host.shadowRoot.querySelectorAll(selector).length, 0)])),
|
||||
employees: hosts.reduce((total, host) => total + host.shadowRoot.querySelectorAll('.hm-orgchart-employee').length, 0),
|
||||
autoLayout: hosts.find(host => host.classList.contains('hm-orgchart-host'))?.shadowRoot.querySelector('.hm-orgchart-expanded')?.dataset.autoLayout };
|
||||
@@ -214,7 +215,7 @@ try {
|
||||
for (const id of patterns) {
|
||||
await page.setViewportSize({ width: 1440, height: 1100 });
|
||||
await page.goto(`${origin}/iframe.html?id=${id}&viewMode=story`);
|
||||
await page.locator('.sb-page-title').waitFor(); await settle();
|
||||
await page.locator(pageContent).first().waitFor(); await settle();
|
||||
references.push({ id, style: await commonStyle() });
|
||||
}
|
||||
const reference = references[0].style;
|
||||
@@ -268,7 +269,7 @@ try {
|
||||
await section('full-repair', async () => {
|
||||
await page.setViewportSize({ width: 1440, height: 1100 });
|
||||
await page.goto(`${origin}/iframe.html?id=${patterns[0]}&viewMode=story`);
|
||||
await page.locator('.sb-page-title').waitFor(); await settle();
|
||||
await page.locator(pageContent).first().waitFor(); await settle();
|
||||
const reference = await commonStyle();
|
||||
await gotoStory(stories[2]);
|
||||
const style = await commonStyle();
|
||||
|
||||
Reference in new issue
Block a user