fix(ui): 浮窗内容区改为列方向 flex 契约,修复插件 tab 内容 0 宽白窗
.floatContent 原为行方向 flex——弹性子项主尺寸(宽)按内容收缩,内在宽度为 0 的插件宿主(如深迹 DeepTrace)塌成 0px 宽:DOM 在、内容画不出(可见白窗 但 DevTools 有内容)。对齐 pane 的内容契约:.floatContent 复制 .paneContent 的列方向 + overflow hidden,浮窗内再包一层 .paneTab(pane 的 per-tab 包装, flex:1),子项宽度由 align-stretch 撑满——浮窗里的 tab 获得与 pane 内完全 一致的尺寸契约。e2e 增加内容绘制断言(浮动后内容子项实际宽度 > 200px), 真实浏览器回归。
This commit is contained in:
@@ -284,8 +284,12 @@ export function FreeWindow(props: {
|
||||
anchor={<span />}
|
||||
/>
|
||||
</div>
|
||||
{/* 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. */}
|
||||
<div className={css.floatContent}>
|
||||
{renderTab(float.tab, true, float.id)}
|
||||
<div className={css.paneTab}>{renderTab(float.tab, true, float.id)}</div>
|
||||
</div>
|
||||
<div
|
||||
className={css.floatResize}
|
||||
|
||||
@@ -361,11 +361,18 @@ body[data-dsh-sidebar-dragging] .bottomPanel {
|
||||
color: var(--dsw-alias-label-primary);
|
||||
}
|
||||
|
||||
/* Mirrors .paneContent's column-flex contract: the tab cell must hand its
|
||||
child a definite WIDTH via align-stretch. A row flex (the default) sizes
|
||||
the main axis (width) from content — intrinsic-zero hosts (e.g. a plugin
|
||||
tab UI) collapse to a 0px-wide sliver and paint nothing (the blank
|
||||
whale-report window). */
|
||||
.floatContent {
|
||||
flex: 1;
|
||||
min-height: 0;
|
||||
min-width: 0;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
/* The SE resize corner (mirror of .cornerHandle). */
|
||||
|
||||
@@ -144,6 +144,18 @@ async function conversationBox(page: Page): Promise<{ x: number; y: number; widt
|
||||
})
|
||||
}
|
||||
|
||||
/** The float's content cell must hand its child a real width (the
|
||||
* column-flex contract): a collapsed 0px cell paints nothing — the tab is
|
||||
* "in" the window but invisible. */
|
||||
async function assertContentPainted(page: Page, label: string): Promise<void> {
|
||||
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)
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user