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');
+ });
+});
| |