From a65012c1b34f0a215e832ce4a97acd79388b931c Mon Sep 17 00:00:00 2001 From: yanweidong Date: Mon, 20 Jul 2026 12:13:57 +0800 Subject: [PATCH] Apply hover scrollbars to project internals --- .../scripts/visual-check.mjs | 36 +++++++++++++++- apps/senlinai-acro-react/src/App.css | 43 ++++++++++++++++--- 2 files changed, 73 insertions(+), 6 deletions(-) diff --git a/apps/senlinai-acro-react/scripts/visual-check.mjs b/apps/senlinai-acro-react/scripts/visual-check.mjs index 028e8b2..c93af1c 100644 --- a/apps/senlinai-acro-react/scripts/visual-check.mjs +++ b/apps/senlinai-acro-react/scripts/visual-check.mjs @@ -32,8 +32,11 @@ const collectMetrics = async () => page.evaluate(() => { const rail = document.querySelector('.project-rail') const railChildren = rail?.querySelector('.arco-layout-sider-children') const sidebar = document.querySelector('.channel-sidebar') + const channelList = document.querySelector('.channel-list') const stage = document.querySelector('.stage') const inspector = document.querySelector('.inspector') + const inspectorTabsContent = document.querySelector('.inspector .arco-tabs-content') + const propertyList = document.querySelector('.property-list') const workspaceActions = [...document.querySelectorAll('.workspace-page .overview-head .arco-btn')] .map((button) => button.textContent?.trim()) const dashboard = document.querySelector('.dashboard-button') @@ -91,8 +94,11 @@ const collectMetrics = async () => page.evaluate(() => { projectRailOverflow: overflowState(rail), projectRailChildrenOverflow: overflowState(railChildren), channelSidebarOverflow: overflowState(sidebar), + channelListOverflow: overflowState(channelList), stageOverflow: overflowState(stage), inspectorOverflow: overflowState(inspector), + inspectorTabsContentOverflow: overflowState(inspectorTabsContent), + propertyListOverflow: overflowState(propertyList), overflowX: document.documentElement.scrollWidth > document.documentElement.clientWidth, viewportWidth: window.innerWidth, } @@ -117,6 +123,15 @@ await page.locator('.stage').hover() const stageHoverMetrics = await collectMetrics() await page.locator('.inspector').hover() const inspectorHoverMetrics = await collectMetrics() +await page.locator('.channel-list').hover() +const channelListHoverMetrics = await collectMetrics() +await page.locator('.inspector .arco-tabs-content').hover() +const inspectorTabsContentHoverMetrics = await collectMetrics() +await page.getByText('属性', { exact: true }).click() +await page.waitForTimeout(200) +const propertyMetrics = await collectMetrics() +await page.locator('.property-list').hover() +const propertyListHoverMetrics = await collectMetrics() await page.locator('.topbar-actions .arco-btn').first().click() await page.screenshot({ path: 'test-results/project-react-acro-dark.png', fullPage: true }) @@ -124,7 +139,18 @@ await page.screenshot({ path: 'test-results/project-react-acro-dark.png', fullPa await browser.close() await server.close() -console.log(JSON.stringify({ workspaceMetrics, projectMetrics, channelSidebarHoverMetrics, stageHoverMetrics, inspectorHoverMetrics, errors }, null, 2)) +console.log(JSON.stringify({ + workspaceMetrics, + projectMetrics, + channelSidebarHoverMetrics, + stageHoverMetrics, + inspectorHoverMetrics, + channelListHoverMetrics, + inspectorTabsContentHoverMetrics, + propertyMetrics, + propertyListHoverMetrics, + errors, +}, null, 2)) const failures = [] const metrics = workspaceMetrics @@ -226,8 +252,10 @@ if (!projectMetrics.projectRail || !projectMetrics.channelSidebar || !projectMet } for (const [name, overflow] of [ ['channel sidebar', projectMetrics.channelSidebarOverflow], + ['channel list', projectMetrics.channelListOverflow], ['stage', projectMetrics.stageOverflow], ['inspector', projectMetrics.inspectorOverflow], + ['inspector tabs content', projectMetrics.inspectorTabsContentOverflow], ]) { if (!overflow || overflow.overflowX !== 'hidden' || overflow.overflowY !== 'auto') { failures.push(`expected ${name} to hide horizontal scrollbars and show vertical scrollbars only when needed, got ${JSON.stringify(overflow)}`) @@ -238,13 +266,19 @@ for (const [name, overflow] of [ } for (const [name, overflow] of [ ['channel sidebar hover', channelSidebarHoverMetrics.channelSidebarOverflow], + ['channel list hover', channelListHoverMetrics.channelListOverflow], ['stage hover', stageHoverMetrics.stageOverflow], ['inspector hover', inspectorHoverMetrics.inspectorOverflow], + ['inspector tabs content hover', inspectorTabsContentHoverMetrics.inspectorTabsContentOverflow], + ['property list hover', propertyListHoverMetrics.propertyListOverflow], ]) { if (overflow?.scrollbarWidth !== 'thin') { failures.push(`expected ${name} scrollbar to appear on hover, got ${JSON.stringify(overflow)}`) } } +if (propertyMetrics.propertyListOverflow?.scrollbarWidth !== 'none') { + failures.push(`expected property list scrollbar to be hidden until hover, got ${JSON.stringify(propertyMetrics.propertyListOverflow)}`) +} if (failures.length) { throw new Error(failures.join('\n')) diff --git a/apps/senlinai-acro-react/src/App.css b/apps/senlinai-acro-react/src/App.css index 8dd5363..cbc2597 100644 --- a/apps/senlinai-acro-react/src/App.css +++ b/apps/senlinai-acro-react/src/App.css @@ -373,6 +373,10 @@ .channel-list { display: grid; gap: 4px; + overflow-x: hidden; + overflow-y: auto; + scrollbar-width: none; + scrollbar-color: color-mix(in srgb, var(--senlin-muted) 45%, transparent) transparent; } .channel-button { @@ -567,34 +571,49 @@ .channel-sidebar:hover, .stage:hover, -.inspector:hover { +.inspector:hover, +.channel-list:hover, +.inspector .arco-tabs-content:hover, +.property-list:hover { scrollbar-width: thin; } .channel-sidebar::-webkit-scrollbar, .stage::-webkit-scrollbar, -.inspector::-webkit-scrollbar { +.inspector::-webkit-scrollbar, +.channel-list::-webkit-scrollbar, +.inspector .arco-tabs-content::-webkit-scrollbar, +.property-list::-webkit-scrollbar { width: 0; height: 0; } .channel-sidebar:hover::-webkit-scrollbar, .stage:hover::-webkit-scrollbar, -.inspector:hover::-webkit-scrollbar { +.inspector:hover::-webkit-scrollbar, +.channel-list:hover::-webkit-scrollbar, +.inspector .arco-tabs-content:hover::-webkit-scrollbar, +.property-list:hover::-webkit-scrollbar { width: 8px; height: 8px; } .channel-sidebar::-webkit-scrollbar-thumb, .stage::-webkit-scrollbar-thumb, -.inspector::-webkit-scrollbar-thumb { +.inspector::-webkit-scrollbar-thumb, +.channel-list::-webkit-scrollbar-thumb, +.inspector .arco-tabs-content::-webkit-scrollbar-thumb, +.property-list::-webkit-scrollbar-thumb { border-radius: 999px; background: color-mix(in srgb, var(--senlin-muted) 45%, transparent); } .channel-sidebar::-webkit-scrollbar-track, .stage::-webkit-scrollbar-track, -.inspector::-webkit-scrollbar-track { +.inspector::-webkit-scrollbar-track, +.channel-list::-webkit-scrollbar-track, +.inspector .arco-tabs-content::-webkit-scrollbar-track, +.property-list::-webkit-scrollbar-track { background: transparent; } @@ -602,6 +621,13 @@ margin-bottom: 12px; } +.inspector .arco-tabs-content { + overflow-x: hidden; + overflow-y: auto; + scrollbar-width: none; + scrollbar-color: color-mix(in srgb, var(--senlin-muted) 45%, transparent) transparent; +} + .discussion-panel { display: grid; } @@ -653,6 +679,13 @@ width: 100%; } +.property-list { + overflow-x: hidden; + overflow-y: auto; + scrollbar-width: none; + scrollbar-color: color-mix(in srgb, var(--senlin-muted) 45%, transparent) transparent; +} + .property-row { display: flex; justify-content: space-between;