Skip to content

Commit 9532b18

Browse files
committed
refactor(ui): migrate muted text in components
T16-B 第 1 批:照 tmp/t16a/slice.md 清单迁移 components/** 的弱化灰文本。 - 24 文件 / 55 处:color 一律走 Text 的 tone(本单元一律 ink-3,5.13:1) - A 类三元逐处判:非灰支有等价档才迁(ok/ink-2/due/inherit),品牌青/粉/靛蓝支登记例外 - B 类 15 处 guard 迁(条件留在调用点);fontSize 越界值原样留行内(R2 交批 5/6) - 文案逐字保留;data-testid/title 走 T16-A 的两槽;文案与结构零改动
1 parent 0b27540 commit 9532b18

24 files changed

Lines changed: 102 additions & 93 deletions

‎app/src/components/AiConversationDock.tsx‎

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
*/
1717
import { useCallback, useEffect, useRef, useState } from "react";
1818
import { zIndex } from "../ui/zIndex";
19-
import { EmptyState } from "../ui/primitives";
19+
import { EmptyState, Text } from "../ui/primitives";
2020
import { invoke } from "@tauri-apps/api/core";
2121
import { listen } from "@tauri-apps/api/event";
2222
import type { AiTaskRecord, AiTaskState, AiTurn, ChatMessage, ChatSession } from "../types";
@@ -176,9 +176,9 @@ export default function AiConversationDock({
176176
{OP_LABEL[t.opType] ?? t.opType} {taskRefTitle(t)}
177177
</span>
178178
<span style={{ fontSize: 10, fontWeight: 600, color }}>{done ? (t.state === "succeeded" ? "✓" : "✗") : "…"}</span>
179-
<span style={{ fontSize: 10, color: "#9ca3af" }}>
179+
<Text tone="ink-3" style={{ fontSize: 10 }}>
180180
{new Date(t.createdAt * 1000).toLocaleTimeString()}
181-
</span>
181+
</Text>
182182
</button>
183183
);
184184
})
@@ -198,7 +198,7 @@ export default function AiConversationDock({
198198
}}
199199
>
200200
<span style={{ flex: 1, overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap" }}>{s.title}</span>
201-
{s.model && <span style={{ fontSize: 10, color: "#9ca3af" }}>{s.model.split("/").pop()}</span>}
201+
{s.model && <Text tone="ink-3" style={{ fontSize: 10 }}>{s.model.split("/").pop()}</Text>}
202202
</button>
203203
))
204204
);
@@ -211,9 +211,9 @@ export default function AiConversationDock({
211211
}
212212
return messages.map((m) => (
213213
<div key={m.id} style={{ marginBottom: 8 }}>
214-
<div style={{ fontSize: 10, color: "#9ca3af", marginBottom: 2 }}>
214+
<Text as="div" tone="ink-3" style={{ fontSize: 10, marginBottom: 2 }}>
215215
{m.role === "user" ? "🧑 你" : "🤖 AI"}{m.model ? ` · ${m.model}` : ""}
216-
</div>
216+
</Text>
217217
<div style={{
218218
whiteSpace: "pre-wrap", wordBreak: "break-word", fontSize: 12.5, lineHeight: 1.6,
219219
background: m.role === "user" ? "#eef2ff" : "#f9fafb",

‎app/src/components/AiServicePanel.tsx‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ import { invoke } from "@tauri-apps/api/core";
1313
import type { AiAuditEntry, AiSettingsView, RefineStrategyMeta } from "../types";
1414
import RefineStrategyPicker from "./RefineStrategyPicker";
1515
import { draftFromPrefs, prefsFromDraft, type StrategyDraft } from "../utils/refineStrategy";
16-
import { Button, EmptyState, StatusLine } from "../ui/primitives";
16+
import { Button, EmptyState, StatusLine, Text } from "../ui/primitives";
1717

1818
/** 通用小按钮样式(与各设置面板一致) */
1919
const btn: React.CSSProperties = {
@@ -164,7 +164,7 @@ export default function AiServicePanel() {
164164
{view?.enabled ? (
165165
<span style={{ color: "#0d9488", fontWeight: 600 }}>● 已开启</span>
166166
) : (
167-
<span style={{ color: "#9ca3af" }}>○ 默认关闭</span>
167+
<Text tone="ink-3">○ 默认关闭</Text>
168168
)}
169169
</div>
170170

‎app/src/components/AiTaskPanel.tsx‎

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ import { invoke } from "@tauri-apps/api/core";
1515
import type { AiEnrichResult, AiRefineResult, AiTaskRecord } from "../types";
1616
// 低5(审查):类别词经 entityLabel.kindWord 单一来源(不带 id 的语义词)
1717
import { kindWord } from "../utils/entityLabel";
18-
import { Button, EmptyState, StatusLine } from "../ui/primitives";
18+
import { Button, EmptyState, StatusLine, Text } from "../ui/primitives";
1919

2020
const btn: React.CSSProperties = { padding: "3px 8px", fontSize: 11, borderRadius: 5, border: "1px solid #d1d5db", background: "#fff", cursor: "pointer" };
2121

@@ -148,7 +148,7 @@ export default function AiTaskPanel() {
148148
<div style={{ display: "flex", alignItems: "center", gap: 8, marginBottom: 6 }}>
149149
<span style={{ fontWeight: 600, fontSize: 12 }}>🗂 AI 任务中心</span>
150150
<Button variant="secondary" size="sm" onClick={() => void load()}>刷新</Button>
151-
<span style={{ fontSize: 11, color: "#9ca3af" }}>历史任务持久化保存——重启后可查看/采纳结果</span>
151+
<Text tone="ink-3" style={{ fontSize: 11 }}>历史任务持久化保存——重启后可查看/采纳结果</Text>
152152
</div>
153153

154154
{tasks.length === 0 ? (
@@ -168,9 +168,9 @@ export default function AiTaskPanel() {
168168
</span>
169169
<span style={{ color: "#374151", flex: 1, overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap" }}>
170170
{kindWord(t.opType === "refine" ? "session" : "note")}
171-
{t.model && <span style={{ color: "#9ca3af" }}> · {t.model}</span>}
171+
{t.model && <Text tone="ink-3"> · {t.model}</Text>}
172172
</span>
173-
<span style={{ color: "#9ca3af", width: 52, textAlign: "right" }}>{fmtMs(t.elapsedMs)}</span>
173+
<Text tone="ink-3" style={{ width: 52, textAlign: "right" }}>{fmtMs(t.elapsedMs)}</Text>
174174
{t.costYuan != null && (
175175
<span style={{ color: "#b45309", width: 52, textAlign: "right" }}>¥{t.costYuan.toFixed(4)}</span>
176176
)}

‎app/src/components/AsrConfusionPanel.tsx‎

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*/
99
import { useCallback, useEffect, useState } from "react";
1010
import { invoke } from "@tauri-apps/api/core";
11-
import { Button, EmptyState, Loading, StatusLine } from "../ui/primitives";
11+
import { Button, EmptyState, Loading, StatusLine, Text } from "../ui/primitives";
1212

1313
interface AsrPairView {
1414
wrong: string;
@@ -89,9 +89,9 @@ export function AsrConfusionPanel() {
8989
<div>
9090
<div style={{ fontSize: 12, color: "#374151", marginBottom: 8 }}>
9191
<b>ASR 同音混淆闭环</b>{" "}
92-
<span style={{ color: "#9ca3af", fontSize: 11 }}>
92+
<Text tone="ink-3" style={{ fontSize: 11 }}>
9393
画像来自离线精修采纳流;确认=纠错规则(共现才替换)+ 反哺热词;asr_confusion.json 可校准
94-
</span>
94+
</Text>
9595
</div>
9696
{msg && (
9797
<div style={{ fontSize: 11, color: "#047857", background: "#ecfdf5", border: "1px solid #6ee7b7", borderRadius: 6, padding: "4px 8px", marginBottom: 6 }}>
@@ -106,7 +106,7 @@ export function AsrConfusionPanel() {
106106
<div style={{ fontSize: 12, marginBottom: 4 }}>
107107
待确认候选({candidates.length})
108108
{view != null && view.dismissed_count > 0 && (
109-
<span style={{ color: "#9ca3af", fontSize: 11, marginLeft: 6 }}>已忽略 {view.dismissed_count} 条</span>
109+
<Text tone="ink-3" style={{ fontSize: 11, marginLeft: 6 }}>已忽略 {view.dismissed_count} 条</Text>
110110
)}
111111
</div>
112112
{candidates.length === 0 ? (
@@ -122,11 +122,11 @@ export function AsrConfusionPanel() {
122122
<span style={{ background: "#fff7ed", border: "1px solid #fdba74", borderRadius: 4, padding: "1px 6px" }}>
123123
{c.wrong}
124124
</span>
125-
<span style={{ color: "#9ca3af" }}>→</span>
125+
<Text tone="ink-3">→</Text>
126126
<span style={{ background: "#ecfdf5", border: "1px solid #6ee7b7", borderRadius: 4, padding: "1px 6px" }}>
127127
{c.right}
128128
</span>
129-
<span style={{ color: "#9ca3af", fontSize: 11 }}>×{c.count}</span>
129+
<Text tone="ink-3" style={{ fontSize: 11 }}>×{c.count}</Text>
130130
<span style={{ marginLeft: "auto", display: "flex", gap: 4 }}>
131131
<button style={{ ...rowBtn, color: "#047857", borderColor: "#6ee7b7" }} onClick={() => void confirm(c.wrong, c.right)}>
132132
确认纠错+热词

‎app/src/components/AudioLevelMeter.tsx‎

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
*/
1010
import { useEffect, useRef, useState } from "react";
1111
import { listen } from "@tauri-apps/api/event";
12+
import { Text } from "../ui/primitives";
1213

1314
/** 电平段数 */
1415
const SEGMENTS = 12;
@@ -79,9 +80,9 @@ export default function AudioLevelMeter() {
7980
</div>
8081
{clipping && <span style={{ fontSize: 10, color: "#dc2626", flexShrink: 0 }}>削波!</span>}
8182
</div>
82-
<div style={{ fontSize: 9, color: "#9ca3af", marginTop: 2 }}>
83+
<Text as="div" tone="ink-3" style={{ fontSize: 9, marginTop: 2 }}>
8384
电平跳动 = 正在采集课程声音(无跳动请检查系统声音/播放器)
84-
</div>
85+
</Text>
8586
</div>
8687
);
8788
}

‎app/src/components/BackupPanel.tsx‎

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
import { useState } from "react";
1212
import { invoke } from "@tauri-apps/api/core";
1313
import { open } from "@tauri-apps/plugin-dialog";
14-
import { ConfirmDialog, StatusLine } from "../ui/primitives";
14+
import { ConfirmDialog, StatusLine, Text } from "../ui/primitives";
1515

1616
interface BackupSummary {
1717
archivePath: string;
@@ -103,9 +103,9 @@ export default function BackupPanel() {
103103
</div>
104104
{error && <StatusLine kind="error">{error}</StatusLine>}
105105
{!error && info && <div style={{ fontSize: 11, color: "#0f766e" }}>{info}</div>}
106-
<div style={{ fontSize: 10, color: "#9ca3af" }}>
106+
<Text as="div" tone="ink-3" style={{ fontSize: 10 }}>
107107
备份保存在应用数据目录 backups/(本地优先:数据不出本机);如需异地保存请自行拷贝备份文件
108-
</div>
108+
</Text>
109109

110110
{/* 高危确认(§5.3):原文案「恢复将覆盖当前全部数据(现有数据库改名 .pre-restore 兜底)。\n继续?」
111111
逐字拆为 title(首句)+ impacts(括号内的保留项)+ 确认按钮「继续」 */}

‎app/src/components/CaptureFloatPanel.tsx‎

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ import { useFloatWindow } from "../hooks/useFloatWindow";
2727
// 批 2b:本窗独立的采集控制实例(provider 由 App ?float=1 分支包入)
2828
import { useCaptureControl } from "../hooks/useLiveCaptureControl";
2929
import { AUTO_RESUME_HINTS, pauseReasonLabel } from "../hooks/liveCaptureState";
30-
import { Button } from "../ui/primitives";
30+
import { Button, Text } from "../ui/primitives";
3131

3232
function fmtTime(ms: number): string {
3333
const s = Math.floor(ms / 1000);
@@ -204,13 +204,13 @@ export default function CaptureFloatPanel() {
204204
{/* 中部:最近转写 */}
205205
<div style={{ flex: 1, minHeight: 0, overflowY: "auto", padding: "6px 10px" }}>
206206
{transcripts.slice(-SHOW_TRANSCRIPT).length === 0 && partials.length === 0 && (
207-
<p style={{ margin: 0, color: "#9ca3af" }}>等待识别…</p>
207+
<Text as="p" tone="ink-3" style={{ margin: 0 }}>等待识别…</Text>
208208
)}
209209
{transcripts.slice(-SHOW_TRANSCRIPT).map((t) => (
210210
<div key={t.id} style={{ display: "flex", gap: 6, alignItems: "baseline", lineHeight: 1.5, marginBottom: 2 }}>
211-
<span style={{ fontSize: 10, color: "#9ca3af", width: 36, flexShrink: 0, fontVariantNumeric: "tabular-nums" }}>
211+
<Text tone="ink-3" style={{ fontSize: 10, width: 36, flexShrink: 0, fontVariantNumeric: "tabular-nums" }}>
212212
{fmtTime(t.time)}
213-
</span>
213+
</Text>
214214
<span style={{ color: t.source === "subtitle" ? "#0f766e" : "#374151", overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap" }}>
215215
{t.text}
216216
</span>
@@ -219,9 +219,9 @@ export default function CaptureFloatPanel() {
219219
{partials.slice(-2).map((p) => (
220220
<div key={p.id} style={{ display: "flex", gap: 6, alignItems: "baseline", lineHeight: 1.5, marginBottom: 2 }}>
221221
<span style={{ fontSize: 10, width: 36, flexShrink: 0 }} />
222-
<span style={{ color: p.committed ? "#374151" : "#9ca3af", fontStyle: p.committed ? "normal" : "italic", overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap" }}>
222+
<Text tone={p.committed ? "ink-2" : "ink-3"} style={{ fontStyle: p.committed ? "normal" : "italic", overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap" }}>
223223
{p.text}
224-
</span>
224+
</Text>
225225
</div>
226226
))}
227227
</div>

‎app/src/components/ChatMessageList.tsx‎

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import type { ChatMessage, KbHit } from "../types";
1414
import ChatMessageMarkdown from "./ChatMessageMarkdown";
1515
import CitationChips from "./CitationChips";
1616
import { parseKbMeta } from "../utils/kbHits";
17+
import { Text } from "../ui/primitives";
1718

1819
export interface StreamingState {
1920
/** 流式累积文本(非 null = 流式生成中) */
@@ -62,9 +63,9 @@ export default function ChatMessageList({ messages, streaming, onRegenerate, onE
6263
return (
6364
<div style={{ flex: 1, minHeight: 0, overflowY: "auto", padding: "12px 16px" }}>
6465
{messages.length === 0 && !streaming && (
65-
<div style={{ textAlign: "center", color: "#9ca3af", marginTop: 80, fontSize: 13 }}>
66+
<Text as="div" size={4} tone="ink-3" style={{ textAlign: "center", marginTop: 80 }}>
6667
开始你的第一句话——例如「用通俗的语言解释一下什么是梯度下降」
67-
</div>
68+
</Text>
6869
)}
6970
{messages.map((m) => {
7071
const isUser = m.role === "user";
@@ -104,14 +105,14 @@ export default function ChatMessageList({ messages, streaming, onRegenerate, onE
104105
</div>
105106
) : (
106107
<div style={{ borderRadius: "10px 10px 10px 2px" }}>
107-
<div style={{ fontSize: 11, color: "#9ca3af", marginBottom: 2, display: "flex", gap: 8 }}>
108+
<Text as="div" tone="ink-3" style={{ fontSize: 11, marginBottom: 2, display: "flex", gap: 8 }}>
108109
<span>🤖 {m.model ?? "AI"}</span>
109110
<span>{fmtTime(m.createdAt)}</span>
110111
{m.status === "aborted" && <span style={{ color: "#b45309" }}>已停止</span>}
111112
{parseUsage(m.usageJson).tokens != null && (
112113
<span>{parseUsage(m.usageJson).tokens} tokens</span>
113114
)}
114-
</div>
115+
</Text>
115116
<div style={{ background: "#f8fafc", border: "1px solid #e5e7eb", borderRadius: 8, padding: "8px 12px" }}>
116117
<ChatMessageMarkdown content={m.content} />
117118
{/* v0.19.1:引用 chips(answer 与 hits-only 引导同款展示) */}

‎app/src/components/ChatSidebar.tsx‎

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ import type { AiTaskRecord, ChatSession } from "../types";
1414
// 2026-09-09 批 1:任务标题统一按类别解析(taskRefLabel——会话级/笔记级
1515
// 精修 ref_id 语义不同;enrich 恒笔记级),侧栏与对话页/dock 同口径
1616
import { taskRefLabel } from "../utils/entityLabel";
17-
import { EmptyState } from "../ui/primitives";
17+
import { EmptyState, Text } from "../ui/primitives";
1818
// 批 3(规格 §6.2「AI 对话侧栏:接入列基础设施」):列宽不再写死——
1919
// 规格住在 shell/columnRegistry,运行时由页面里的 useColumnLayout 执行
2020
import { columnSpec } from "../shell/columnRegistry";
@@ -131,7 +131,7 @@ export default function ChatSidebar(props: ChatSidebarProps) {
131131
{s.retrieval && <span title="学习库问答模式">📚 </span>}
132132
{s.title}
133133
</span>
134-
{s.model && <span style={{ fontSize: 10, color: "#9ca3af" }}>{s.model.split("/").pop()}</span>}
134+
{s.model && <Text tone="ink-3" style={{ fontSize: 10 }}>{s.model.split("/").pop()}</Text>}
135135
<span
136136
role="button"
137137
title="重命名"
@@ -155,9 +155,9 @@ export default function ChatSidebar(props: ChatSidebarProps) {
155155
{/* 2026-09-09 批 1 语义说明:本段是精修/补充任务(来源会话/笔记)的
156156
只读轨迹视图,不是 💬 聊天会话——点选打开任务对话、结果可采纳 */}
157157
{tasks.length > 0 && (
158-
<div style={{ fontSize: 10.5, color: "#9ca3af", lineHeight: 1.6, padding: "0 8px 6px" }}>
158+
<Text as="div" tone="ink-3" style={{ fontSize: 10.5, lineHeight: 1.6, padding: "0 8px 6px" }}>
159159
精修/补充任务的轨迹(来源:会话或笔记)——非聊天会话;完成结果可采纳
160-
</div>
160+
</Text>
161161
)}
162162
{tasks.map((t) => {
163163
const refName = taskRefLabel(t, sessionTitles, noteTitles);
@@ -178,7 +178,7 @@ export default function ChatSidebar(props: ChatSidebarProps) {
178178
<span style={{ fontSize: 10, color: stateBadge, fontWeight: 600 }}>
179179
{t.state === "succeeded" ? "✓" : t.state === "failed" ? "✗" : "…"}
180180
</span>
181-
<span style={{ fontSize: 10, color: "#9ca3af" }}>{fmtTime(t.createdAt)}</span>
181+
<Text tone="ink-3" style={{ fontSize: 10 }}>{fmtTime(t.createdAt)}</Text>
182182
</div>
183183
);
184184
})}

‎app/src/components/CitationChips.tsx‎

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
*/
99
import type { KbHit } from "../types";
1010
import { firstMarkedTerm, hitLabel, isNoteHit } from "../utils/kbHits";
11+
import { Text } from "../ui/primitives";
1112

1213
interface Props {
1314
hits: KbHit[];
@@ -56,9 +57,9 @@ export default function CitationChips({ hits, onOpenNote, title = "📚 本地
5657
}}
5758
>
5859
<span style={{ whiteSpace: "nowrap", overflow: "hidden", textOverflow: "ellipsis" }}>{label}</span>
59-
<span style={{ color: "#9ca3af", whiteSpace: "nowrap", overflow: "hidden", textOverflow: "ellipsis", maxWidth: 220 }}>
60+
<Text tone="ink-3" style={{ whiteSpace: "nowrap", overflow: "hidden", textOverflow: "ellipsis", maxWidth: 220 }}>
6061
{(h.snippet ?? "").replace(/==/g, "")}
61-
</span>
62+
</Text>
6263
</button>
6364
);
6465
})}

0 commit comments

Comments
 (0)