From 28deb31ffcb994f04d1eb8e9f6ccdfba44c8c085 Mon Sep 17 00:00:00 2001 From: Stella-xixi <2559689615@qq.com> Date: Wed, 2 Sep 2026 01:05:31 +0800 Subject: [PATCH] fix(settings): prevent usage table overlap in narrow views Signed-off-by: Stella-xixi <2559689615@qq.com> --- .../settings/usage/UsageBreakdownTables.tsx | 15 ++++- .../__tests__/UsageBreakdownTables.test.tsx | 61 +++++++++++++++++++ 2 files changed, 73 insertions(+), 3 deletions(-) create mode 100644 apps/desktop/src/renderer/components/settings/usage/__tests__/UsageBreakdownTables.test.tsx diff --git a/apps/desktop/src/renderer/components/settings/usage/UsageBreakdownTables.tsx b/apps/desktop/src/renderer/components/settings/usage/UsageBreakdownTables.tsx index f56dc8b4cca..12fe8ac8ac5 100644 --- a/apps/desktop/src/renderer/components/settings/usage/UsageBreakdownTables.tsx +++ b/apps/desktop/src/renderer/components/settings/usage/UsageBreakdownTables.tsx @@ -40,8 +40,17 @@ const TD_CLASS = * `w-full + max-w-0` 让它先塌到 0 (打破"按最长内容取列宽"的默认行为) 再领走 * 其余列分完后剩下的空间, 内层的 truncate 由此生效 (见 #3393 的同一段分析)。 * pl-3 是列间距, 否则相邻两列的数字会贴到一起; 首列自身取 pl-0。 + * + * `overflow-hidden` 是最后一道单元格边界: 模型行还有不可收缩的色块与 agent 标签, + * 即使浏览器在边界宽度下给首列算出异常小的宽度, 它们也不能穿透到数字列 (#3546)。 + * 表本身另有明确的最小宽度, 空间不足时由外层 overflow-x-auto 横向滚动, 而不是 + * 继续把首列压到不可读。 */ -const FIRST_COL_CLASS = 'w-full max-w-0 pl-0'; +const FIRST_COL_CLASS = 'w-full max-w-0 overflow-hidden pl-0'; + +/** 数字列保持完整可读所需的最小表宽; 低于该宽度时交给 Card 的横向滚动容器。 */ +const AGENT_TABLE_CLASS = 'w-full min-w-[520px] border-collapse'; +const MODEL_TABLE_CLASS = 'w-full min-w-[720px] border-collapse'; function Swatch({ rank }: { rank: number }): React.JSX.Element { return ( @@ -92,7 +101,7 @@ export function UsageAgentTable({ rows }: { rows: AgentTokenRow[] }): React.JSX. /> ))} - +
@@ -140,7 +149,7 @@ export function UsageModelTable({ rows }: { rows: ModelTokenRow[] }): React.JSX. const { t } = useTranslation(); return ( - +
diff --git a/apps/desktop/src/renderer/components/settings/usage/__tests__/UsageBreakdownTables.test.tsx b/apps/desktop/src/renderer/components/settings/usage/__tests__/UsageBreakdownTables.test.tsx new file mode 100644 index 00000000000..615b595d419 --- /dev/null +++ b/apps/desktop/src/renderer/components/settings/usage/__tests__/UsageBreakdownTables.test.tsx @@ -0,0 +1,61 @@ +// @vitest-environment jsdom + +import React from 'react'; +import { render } from '@testing-library/react'; +import { describe, expect, it, vi } from 'vitest'; + +import { UsageAgentTable, UsageModelTable } from '../UsageBreakdownTables'; + +vi.mock('react-i18next', () => ({ + useTranslation: () => ({ + t: (key: string) => key, + }), +})); + +describe('UsageBreakdownTables responsive layout', () => { + it('keeps the agent table wide enough for numeric columns to scroll instead of overlap', () => { + const { container } = render( + , + ); + + const table = container.querySelector('table'); + expect(table?.className).toContain('min-w-[520px]'); + expect(table?.querySelector('tbody td')?.className).toContain('overflow-hidden'); + }); + + it('keeps the wider model table scrollable and clips first-column decorations at its boundary', () => { + const { container } = render( + , + ); + + const table = container.querySelector('table'); + expect(table?.className).toContain('min-w-[720px]'); + expect(table?.querySelector('tbody td')?.className).toContain('overflow-hidden'); + }); +});