From f648b0c0060f6c734d373ce4650270b02419ea15 Mon Sep 17 00:00:00 2001 From: Menghuan1918 Date: Mon, 24 Aug 2026 00:35:58 +0800 Subject: [PATCH] =?UTF-8?q?fix(ui):=20=E6=B5=AE=E7=AA=97=E5=86=85=E5=AE=B9?= =?UTF-8?q?=E5=8C=BA=E6=94=B9=E4=B8=BA=E5=88=97=E6=96=B9=E5=90=91=20flex?= =?UTF-8?q?=20=E5=A5=91=E7=BA=A6=EF=BC=8C=E4=BF=AE=E5=A4=8D=E6=8F=92?= =?UTF-8?q?=E4=BB=B6=20tab=20=E5=86=85=E5=AE=B9=200=20=E5=AE=BD=E7=99=BD?= =?UTF-8?q?=E7=AA=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit .floatContent 原为行方向 flex——弹性子项主尺寸(宽)按内容收缩,内在宽度为 0 的插件宿主(如深迹 DeepTrace)塌成 0px 宽:DOM 在、内容画不出(可见白窗 但 DevTools 有内容)。对齐 pane 的内容契约:.floatContent 复制 .paneContent 的列方向 + overflow hidden,浮窗内再包一层 .paneTab(pane 的 per-tab 包装, flex:1),子项宽度由 align-stretch 撑满——浮窗里的 tab 获得与 pane 内完全 一致的尺寸契约。e2e 增加内容绘制断言(浮动后内容子项实际宽度 > 200px), 真实浏览器回归。 --- src/client/FreeWindow.tsx | 6 +++++- src/client/sidebar.module.css | 7 +++++++ tests/e2e/float-window.e2e.ts | 14 ++++++++++++++ 3 files changed, 26 insertions(+), 1 deletion(-) diff --git a/src/client/FreeWindow.tsx b/src/client/FreeWindow.tsx index 4768741..6b37a6d 100644 --- a/src/client/FreeWindow.tsx +++ b/src/client/FreeWindow.tsx @@ -284,8 +284,12 @@ export function FreeWindow(props: { anchor={} /> + {/* The tab cell reuses .paneTab (the pane's per-tab wrapper): the + column-flex chain (window → .floatContent → .paneTab) is what + gives the component a definite width via align-stretch — the exact + sizing contract a tab gets inside a pane. */}
- {renderTab(float.tab, true, float.id)} +
{renderTab(float.tab, true, float.id)}
{ + const width = await page.evaluate(() => { + const cell = document.querySelector('[data-dsh-float-window] [class*="floatContent"]') + const child = cell?.firstElementChild + return child === null || child === undefined ? -1 : Math.round(child.getBoundingClientRect().width) + }) + expect(width, `${label}: the floated tab's content must have real width`).toBeGreaterThan(200) +} + test('float a tab, move the window, reload restores it, dock it back', async ({ page }) => { const sidebar = await bootExpanded(page) @@ -158,6 +170,7 @@ test('float a tab, move the window, reload restores it, dock it back', async ({ await expect(floatWindow).toHaveCount(1, { timeout: 10_000 }) // The tab left the strip with the window born over the conversation area // (center), well clear of the panel's right edge. + await assertContentPainted(page, 'context-menu float') const leftBefore = await floatWindow.evaluate((node) => Number.parseFloat((node as HTMLElement).style.left)) expect(Number.isFinite(leftBefore), `style.left must be numeric, got ${leftBefore}`).toBe(true) expect(leftBefore).toBeGreaterThan(0) @@ -240,5 +253,6 @@ test('dragging a tab onto the conversation area floats it (drag-out gesture)', a // its title. await expect(stripTabs).toHaveCount(1) await expect(floatWindow.locator('[class*="floatTitle"]')).toHaveText(terminalTitle) + await assertContentPainted(page, 'drag-out float') await assertNoCrash(page) })