Skip to content

Commit 0e17e66

Browse files
committed
refactor(ui): migrate button style constants
1 parent bde807d commit 0e17e66

35 files changed

Lines changed: 209 additions & 253 deletions

‎app/src/components/AiRefineCard.tsx‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ import type {
2323
import RefineWorkbench from "./RefineWorkbench";
2424
import RefineLaunchDialog from "./RefineLaunchDialog";
2525
import { overrideFromInfo } from "../utils/refineStrategy";
26+
import { Button } from "../ui/primitives";
2627

2728
const btn: React.CSSProperties = { padding: "5px 10px", cursor: "pointer", fontSize: 12, borderRadius: 6 };
2829

@@ -242,7 +243,7 @@ export default function AiRefineCard({
242243
>
243244
🔧 打开工作台
244245
</button>
245-
<button style={btn} onClick={reset}>放弃(保留规则版)</button>
246+
<Button variant="secondary" size="md" onClick={reset}>放弃(保留规则版)</Button>
246247
</div>
247248
</div>
248249
)}

‎app/src/components/AiServicePanel.tsx‎

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +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 } from "../ui/primitives";
1617

1718
/** 通用小按钮样式(与各设置面板一致) */
1819
const btn: React.CSSProperties = {
@@ -240,9 +241,9 @@ export default function AiServicePanel() {
240241
<button style={{ ...btn, background: "#0d9488", color: "#fff", border: "none" }} onClick={() => void consent()} disabled={busy}>
241242
同意并开启
242243
</button>
243-
<button style={btn} onClick={() => setConsentVisible(false)} disabled={busy}>
244+
<Button variant="secondary" size="md" disabled={busy} onClick={() => setConsentVisible(false)}>
244245
暂不
245-
</button>
246+
</Button>
246247
</div>
247248
</div>
248249
)}

‎app/src/components/AiTaskPanel.tsx‎

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +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 } from "../ui/primitives";
1819

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

@@ -146,7 +147,7 @@ export default function AiTaskPanel() {
146147
<div>
147148
<div style={{ display: "flex", alignItems: "center", gap: 8, marginBottom: 6 }}>
148149
<span style={{ fontWeight: 600, fontSize: 12 }}>🗂 AI 任务中心</span>
149-
<button style={btn} onClick={() => void load()}>刷新</button>
150+
<Button variant="secondary" size="sm" onClick={() => void load()}>刷新</Button>
150151
<span style={{ fontSize: 11, color: "#9ca3af" }}>历史任务持久化保存——重启后可查看/采纳结果</span>
151152
</div>
152153

@@ -174,7 +175,7 @@ export default function AiTaskPanel() {
174175
<span style={{ color: "#b45309", width: 52, textAlign: "right" }}>¥{t.costYuan.toFixed(4)}</span>
175176
)}
176177
{t.state === "succeeded" && !t.adopted && (
177-
<button style={btn} onClick={() => void viewResult(t)}>查看</button>
178+
<Button variant="secondary" size="sm" onClick={() => void viewResult(t)}>查看</Button>
178179
)}
179180
{t.state === "succeeded" && t.adopted && (
180181
<span style={{ color: "#0d9488", fontSize: 11 }}>✅ 已采纳</span>
@@ -210,7 +211,7 @@ export default function AiTaskPanel() {
210211
<button style={{ ...btn, background: "#0d9488", color: "#fff", border: "none" }} onClick={() => void adopt()}>
211212
✅ 采纳落库
212213
</button>
213-
<button style={btn} onClick={() => { setSelected(null); setSummary(null); }}>关闭</button>
214+
<Button variant="secondary" size="sm" onClick={() => { setSelected(null); setSummary(null); }}>关闭</Button>
214215
</div>
215216
</div>
216217
)}

‎app/src/components/AsrConfusionPanel.tsx‎

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

1213
interface AsrPairView {
1314
wrong: string;
@@ -128,9 +129,9 @@ export function AsrConfusionPanel() {
128129
<button style={{ ...rowBtn, color: "#047857", borderColor: "#6ee7b7" }} onClick={() => void confirm(c.wrong, c.right)}>
129130
确认纠错+热词
130131
</button>
131-
<button style={rowBtn} onClick={() => void dismiss(c.wrong, c.right)}>
132+
<Button variant="secondary" size="md" onClick={() => void dismiss(c.wrong, c.right)}>
132133
忽略
133-
</button>
134+
</Button>
134135
</span>
135136
</div>
136137
))}

‎app/src/components/CaptureFloatPanel.tsx‎

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +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";
3031

3132
function fmtTime(ms: number): string {
3233
const s = Math.floor(ms / 1000);
@@ -145,9 +146,9 @@ export default function CaptureFloatPanel() {
145146
🔒 已锁定
146147
</span>
147148
) : (
148-
<button style={iconBtn} title="点击穿透锁定" onClick={toggleLocked}>🔓</button>
149+
<Button variant="ghost" size="sm" title="点击穿透锁定" onClick={toggleLocked}>🔓</Button>
149150
)}
150-
<button style={iconBtn} title="展开为面板(Esc)" onClick={expandToPanel}>⤢</button>
151+
<Button variant="ghost" size="sm" title="展开为面板(Esc)" onClick={expandToPanel}>⤢</Button>
151152
</div>
152153
);
153154
}
@@ -186,18 +187,18 @@ export default function CaptureFloatPanel() {
186187
</span>
187188
<span style={{ color: "#6b7280", fontVariantNumeric: "tabular-nums" }}>⏱ {fmtTime(elapsedMs)}</span>
188189
<span style={{ marginLeft: "auto", color: "#6b7280" }}>{info?.platform ?? ""}</span>
189-
<button style={iconBtn} title={snapshot.topmost ? "取消置顶" : "置顶"} onClick={toggleTopmost}>
190+
<Button variant="ghost" size="sm" title={snapshot.topmost ? "取消置顶" : "置顶"} onClick={toggleTopmost}>
190191
{snapshot.topmost ? "📌" : "📍"}
191-
</button>
192-
<button style={iconBtn} title={snapshot.locked ? "点击穿透已锁定(Ctrl+Shift+F 解锁)" : "点击穿透锁定"} onClick={toggleLocked}>
192+
</Button>
193+
<Button variant="ghost" size="sm" title={snapshot.locked ? "点击穿透已锁定(Ctrl+Shift+F 解锁)" : "点击穿透锁定"} onClick={toggleLocked}>
193194
{snapshot.locked ? "🔒" : "🔓"}
194-
</button>
195+
</Button>
195196
{snapshot.locked && (
196197
<span style={{ fontSize: 10, color: "#b45309", flexShrink: 0 }} title="点击穿透已锁定——按 Ctrl+Shift+F 解锁">
197198
已锁定
198199
</span>
199200
)}
200-
<button style={iconBtn} title="收起为字幕条(Esc)" onClick={shrinkToBar}>⤡</button>
201+
<Button variant="ghost" size="sm" title="收起为字幕条(Esc)" onClick={shrinkToBar}>⤡</Button>
201202
</div>
202203

203204
{/* 中部:最近转写 */}

‎app/src/components/EnrichPanel.tsx‎

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import { invoke } from "@tauri-apps/api/core";
1313
// M8:轮询/事件双通道/卡住检测抽入共用 hook(与 AiRefineCard 同源)
1414
import { useAiTaskPolling } from "../hooks/useAiTaskPolling";
1515
import { failureGuide } from "./aiTaskFailure";
16+
import { Button } from "../ui/primitives";
1617
import type {
1718
AiEnrichResult,
1819
AiSettingsView,
@@ -244,7 +245,7 @@ export default function EnrichPanel({ noteId, onUpdated }: { noteId: number; onU
244245
setSettings({ ...settings!, authorized: true });
245246
await loadConfirm();
246247
}}>同意并继续</button>
247-
<button style={btn} onClick={() => setPhase("idle")}>暂不</button>
248+
<Button variant="secondary" size="md" onClick={() => setPhase("idle")}>暂不</Button>
248249
</div>
249250
</div>
250251
)}
@@ -274,7 +275,7 @@ export default function EnrichPanel({ noteId, onUpdated }: { noteId: number; onU
274275
<button style={{ ...btn, background: "#0d9488", color: "#fff", border: "none" }} onClick={() => void start()}>
275276
开始补充
276277
</button>
277-
<button style={btn} onClick={reset}>取消</button>
278+
<Button variant="secondary" size="md" onClick={reset}>取消</Button>
278279
</div>
279280
</div>
280281
)}
@@ -312,8 +313,8 @@ export default function EnrichPanel({ noteId, onUpdated }: { noteId: number; onU
312313
<button style={{ ...btn, background: "#7c3aed", color: "#fff", border: "none" }} onClick={() => void apply()}>
313314
✅ 采纳(应用补充)
314315
</button>
315-
<button style={btn} onClick={() => void revert()}>撤销(还原补充前)</button>
316-
<button style={btn} onClick={reset}>放弃预览</button>
316+
<Button variant="secondary" size="md" onClick={() => void revert()}>撤销(还原补充前)</Button>
317+
<Button variant="secondary" size="md" onClick={reset}>放弃预览</Button>
317318
</div>
318319
</div>
319320
)}

‎app/src/components/GoalPlanApprovalDialog.tsx‎

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
* 清理登记(丢弃项)诚实展示,绝不静默。
99
*/
1010
import { useMemo, useState } from "react";
11-
import { Modal } from "../ui/primitives";
11+
import { Button, Modal } from "../ui/primitives";
1212
import type { GoalPlanView } from "../types/goals";
1313

1414
interface Props {
@@ -88,11 +88,11 @@ export default function GoalPlanApprovalDialog({ view, onConfirm, onClose, onUse
8888
testId="plan-approval"
8989
footer={
9090
<>
91-
<button onClick={onUseRules} style={ghostBtn} title="不采纳 AI 建议——回到 M1 规则草案(永远可用的降级基线)">改用规则草案</button>
92-
<button onClick={onClose} style={ghostBtn}>再想想</button>
93-
<button data-testid="plan-confirm" onClick={() => void confirm()} disabled={saving} style={primaryBtn}>
91+
<Button variant="secondary" size="md" onClick={onUseRules} title="不采纳 AI 建议——回到 M1 规则草案(永远可用的降级基线)">改用规则草案</Button>
92+
<Button variant="secondary" size="md" onClick={onClose}>再想想</Button>
93+
<Button variant="primary" size="md" testId="plan-confirm" busy={saving} onClick={() => void confirm()}>
9494
{saving ? "落库中…" : "✓ 确认采用"}
95-
</button>
95+
</Button>
9696
</>
9797
}
9898
>
@@ -181,5 +181,3 @@ function Empty({ children }: { children: React.ReactNode }) {
181181
}
182182

183183
const numStyle: React.CSSProperties = { width: 56, fontSize: 12, padding: "2px 6px", border: "1px solid #e5e7eb", borderRadius: 4 };
184-
const primaryBtn: React.CSSProperties = { fontSize: 12, padding: "6px 16px", borderRadius: 6, cursor: "pointer", border: "1px solid #0f766e", background: "#0f766e", color: "#fff" };
185-
const ghostBtn: React.CSSProperties = { fontSize: 12, padding: "6px 12px", borderRadius: 6, cursor: "pointer", border: "1px solid #d1d5db", background: "#fff", color: "#4b5563" };

‎app/src/components/GraduateDialog.tsx‎

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
* @ai-context: 未达标时按钮不可达(GoalDetail 禁用);本对话框只管确认流。
88
*/
99
import { useCallback, useEffect, useState } from "react";
10-
import { Modal } from "../ui/primitives";
10+
import { Button, Modal } from "../ui/primitives";
1111
import { invoke } from "@tauri-apps/api/core";
1212
import type { GraduationReport, GoalDetailView, GoalProgressView } from "../types/goals";
1313

@@ -65,13 +65,13 @@ export default function GraduateDialog({ goalId, onClose, onGraduated }: Props)
6565
testId="graduate-dialog"
6666
footer={
6767
report ? (
68-
<button onClick={onClose} style={primaryBtn}>完成</button>
68+
<Button variant="primary" size="md" onClick={onClose}>完成</Button>
6969
) : (
7070
<>
71-
<button onClick={onClose} style={ghostBtn}>再等等</button>
72-
<button data-testid="confirm-graduate" onClick={() => void confirm()} disabled={saving} style={primaryBtn}>
71+
<Button variant="secondary" size="md" onClick={onClose}>再等等</Button>
72+
<Button variant="primary" size="md" testId="confirm-graduate" busy={saving} onClick={() => void confirm()}>
7373
{saving ? "毕业中…" : "🎓 确认毕业"}
74-
</button>
74+
</Button>
7575
</>
7676
)
7777
}
@@ -144,6 +144,3 @@ export function ReportBody({ report }: { report: GraduationReport }) {
144144
function Section({ children }: { children: string }) {
145145
return <div style={{ fontWeight: 600, color: "#374151", marginTop: 8 }}>{children}</div>;
146146
}
147-
148-
const primaryBtn: React.CSSProperties = { fontSize: 12, padding: "6px 16px", borderRadius: 6, cursor: "pointer", border: "1px solid #0f766e", background: "#0f766e", color: "#fff" };
149-
const ghostBtn: React.CSSProperties = { fontSize: 12, padding: "6px 12px", borderRadius: 6, cursor: "pointer", border: "1px solid #d1d5db", background: "#fff", color: "#4b5563" };

‎app/src/components/ImageGallery.tsx‎

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,7 @@ import { convertFileSrc } from "@tauri-apps/api/core";
1313
import { listen } from "@tauri-apps/api/event";
1414
import ImagePreviewOverlay from "./ImagePreviewOverlay";
1515
import StructureImageSection from "./StructureImageSection";
16-
17-
const btn: React.CSSProperties = { padding: "4px 10px", cursor: "pointer", fontSize: 12 };
16+
import { Button } from "../ui/primitives";
1817

1918
export default function ImageGallery({ sessionId }: { sessionId: number }) {
2019
const [images, setImages] = useState<string[]>([]);
@@ -70,9 +69,9 @@ export default function ImageGallery({ sessionId }: { sessionId: number }) {
7069
<div>
7170
<div style={{ display: "flex", alignItems: "center", gap: 8, marginBottom: 6 }}>
7271
<span style={{ fontSize: 12, fontWeight: 600 }}>📷 参考图集({images.length})</span>
73-
<button style={btn} onClick={() => void refresh()} disabled={loading}>
72+
<Button variant="secondary" size="md" busy={loading} onClick={() => void refresh()}>
7473
{loading ? "加载中…" : "⟳ 刷新"}
75-
</button>
74+
</Button>
7675
{error && <span style={{ fontSize: 11, color: "#dc2626" }}>{error}</span>}
7776
</div>
7877
{images.length === 0 && !loading && (

‎app/src/components/InterviewDialog.tsx‎

Lines changed: 6 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
* 判定的唯一事实源在后端 goal_interview.rs)。
1010
*/
1111
import { useEffect, useState } from "react";
12-
import { Modal } from "../ui/primitives";
12+
import { Button, Modal } from "../ui/primitives";
1313
import { invoke } from "@tauri-apps/api/core";
1414
import type { Goal, GoalPlanView, MilestoneDraft } from "../types/goals";
1515
import type { InterviewAnswers } from "../utils/goalInterview";
@@ -222,10 +222,10 @@ export default function InterviewDialog({ mode, groups, onClose, onCreated, goal
222222
{!quickMode && step === 4 && "确认后即创建——里程碑/判据可从详情页调整"}
223223
</span>
224224
{!quickMode && step > 0 && (
225-
<button onClick={() => setStep((s) => s - 1)} style={ghostBtn}>上一步</button>
225+
<Button variant="secondary" size="md" onClick={() => setStep((s) => s - 1)}>上一步</Button>
226226
)}
227227
{!quickMode && (step === 1 || step === 3) && (
228-
<button data-testid="skip-step" onClick={() => setStep((s) => s + 1)} style={ghostBtn}>跳过/以后想</button>
228+
<Button variant="secondary" size="md" testId="skip-step" onClick={() => setStep((s) => s + 1)}>跳过/以后想</Button>
229229
)}
230230
{!quickMode && step === 4 && (
231231
<button
@@ -239,12 +239,12 @@ export default function InterviewDialog({ mode, groups, onClose, onCreated, goal
239239
</button>
240240
)}
241241
{!quickMode && step < 4 && (
242-
<button data-testid="next-step" onClick={next} style={primaryBtn}>下一步</button>
242+
<Button variant="primary" size="md" testId="next-step" onClick={next}>下一步</Button>
243243
)}
244244
{(quickMode || step === 4) && (
245-
<button data-testid="confirm-create" onClick={() => void create()} disabled={saving || !name.trim()} style={primaryBtn}>
245+
<Button variant="primary" size="md" testId="confirm-create" disabled={saving || !name.trim()} onClick={() => void create()}>
246246
{saving ? "创建中…" : "✓ 确认创建"}
247-
</button>
247+
</Button>
248248
)}
249249
</div>
250250
{/* v0.18.2:AI 规划确认流(建议制——确认后替换规则草案落库) */}
@@ -271,10 +271,6 @@ const inputStyle: React.CSSProperties = {
271271
width: "100%", padding: "7px 10px", fontSize: 13, border: "1px solid #e5e7eb",
272272
borderRadius: 6, boxSizing: "border-box", marginBottom: 10,
273273
};
274-
const primaryBtn: React.CSSProperties = {
275-
fontSize: 12, padding: "6px 16px", borderRadius: 6, cursor: "pointer",
276-
border: "1px solid #0f766e", background: "#0f766e", color: "#fff",
277-
};
278274
const ghostBtn: React.CSSProperties = {
279275
fontSize: 12, padding: "6px 12px", borderRadius: 6, cursor: "pointer",
280276
border: "1px solid #d1d5db", background: "#fff", color: "#4b5563",

0 commit comments

Comments
 (0)