diff --git a/src/App.tsx b/src/App.tsx index f7470a18aa..1270e7f3dd 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -225,7 +225,7 @@ function App() { const skillsPageRef = useRef(null); const unifiedSkillsPanelRef = useRef(null); const addActionButtonClass = - "bg-orange-500 hover:bg-orange-600 dark:bg-orange-500 dark:hover:bg-orange-600 text-white shadow-lg shadow-orange-500/30 dark:shadow-orange-500/40 rounded-full w-8 h-8"; + "bg-primary text-primary-foreground hover:bg-primary/90 shadow-lg shadow-primary/25 rounded-full w-8 h-8"; const { isRunning: isProxyRunning, @@ -1115,8 +1115,8 @@ function App() { className={cn( "text-xl font-semibold transition-colors", isProxyRunning && isCurrentAppTakeoverActive - ? "text-emerald-500 hover:text-emerald-600 dark:text-emerald-400 dark:hover:text-emerald-300" - : "text-blue-500 hover:text-blue-600 dark:text-blue-400 dark:hover:text-blue-300", + ? "text-primary hover:text-primary/80" + : "text-foreground/80 hover:text-foreground", )} > CC Switch @@ -1130,7 +1130,7 @@ function App() { setCurrentView("settings"); }} title={t("common.settings")} - className="hover:bg-black/5 dark:hover:bg-white/5" + className="hover:bg-accent/60" > @@ -1151,7 +1151,7 @@ function App() { title={t("usage.title", { defaultValue: "使用统计", })} - className="hover:bg-black/5 dark:hover:bg-white/5" + className="hover:bg-accent/60" > @@ -1189,7 +1189,7 @@ function App() { variant="ghost" size="sm" onClick={() => promptPanelRef.current?.openAdd()} - className="hover:bg-black/5 dark:hover:bg-white/5" + className="hover:bg-accent/60" > {t("prompts.add")} @@ -1201,7 +1201,7 @@ function App() { variant="ghost" size="sm" onClick={() => mcpPanelRef.current?.openImport()} - className="hover:bg-black/5 dark:hover:bg-white/5" + className="hover:bg-accent/60" > {t("mcp.importExisting")} @@ -1210,7 +1210,7 @@ function App() { variant="ghost" size="sm" onClick={() => mcpPanelRef.current?.openAdd()} - className="hover:bg-black/5 dark:hover:bg-white/5" + className="hover:bg-accent/60" > {t("mcp.addMcp")} @@ -1225,7 +1225,7 @@ function App() { onClick={() => unifiedSkillsPanelRef.current?.openRestoreFromBackup() } - className="hover:bg-black/5 dark:hover:bg-white/5" + className="hover:bg-accent/60" > {t("skills.restoreFromBackup.button")} @@ -1236,7 +1236,7 @@ function App() { onClick={() => unifiedSkillsPanelRef.current?.openInstallFromZip() } - className="hover:bg-black/5 dark:hover:bg-white/5" + className="hover:bg-accent/60" > {t("skills.installFromZip.button")} @@ -1247,7 +1247,7 @@ function App() { onClick={() => unifiedSkillsPanelRef.current?.openImport() } - className="hover:bg-black/5 dark:hover:bg-white/5" + className="hover:bg-accent/60" > {t("skills.import")} @@ -1256,7 +1256,7 @@ function App() { variant="ghost" size="sm" onClick={() => setCurrentView("skillsDiscovery")} - className="hover:bg-black/5 dark:hover:bg-white/5" + className="hover:bg-accent/60" > {t("skills.discover")} @@ -1269,7 +1269,7 @@ function App() { variant="ghost" size="sm" onClick={() => skillsPageRef.current?.refresh()} - className="hover:bg-black/5 dark:hover:bg-white/5" + className="hover:bg-accent/60" > {t("skills.refresh")} @@ -1278,7 +1278,7 @@ function App() { variant="ghost" size="sm" onClick={() => skillsPageRef.current?.openRepoManager()} - className="hover:bg-black/5 dark:hover:bg-white/5" + className="hover:bg-accent/60" > {t("skills.repoManager")} @@ -1312,7 +1312,7 @@ function App() { variant="ghost" size="sm" onClick={() => setCurrentView("workspace")} - className="text-muted-foreground hover:text-foreground hover:bg-black/5 dark:hover:bg-white/5" + className="text-muted-foreground hover:text-foreground hover:bg-accent/60" title={t("workspace.manage")} > @@ -1321,7 +1321,7 @@ function App() { variant="ghost" size="sm" onClick={() => setCurrentView("openclawEnv")} - className="text-muted-foreground hover:text-foreground hover:bg-black/5 dark:hover:bg-white/5" + className="text-muted-foreground hover:text-foreground hover:bg-accent/60" title={t("openclaw.env.title")} > @@ -1330,7 +1330,7 @@ function App() { variant="ghost" size="sm" onClick={() => setCurrentView("openclawTools")} - className="text-muted-foreground hover:text-foreground hover:bg-black/5 dark:hover:bg-white/5" + className="text-muted-foreground hover:text-foreground hover:bg-accent/60" title={t("openclaw.tools.title")} > @@ -1339,7 +1339,7 @@ function App() { variant="ghost" size="sm" onClick={() => setCurrentView("openclawAgents")} - className="text-muted-foreground hover:text-foreground hover:bg-black/5 dark:hover:bg-white/5" + className="text-muted-foreground hover:text-foreground hover:bg-accent/60" title={t("openclaw.agents.title")} > @@ -1348,7 +1348,7 @@ function App() { variant="ghost" size="sm" onClick={() => setCurrentView("sessions")} - className="text-muted-foreground hover:text-foreground hover:bg-black/5 dark:hover:bg-white/5" + className="text-muted-foreground hover:text-foreground hover:bg-accent/60" title={t("sessionManager.title")} > @@ -1361,7 +1361,7 @@ function App() { size="sm" onClick={() => setCurrentView("skills")} className={cn( - "text-muted-foreground hover:text-foreground hover:bg-black/5 dark:hover:bg-white/5", + "text-muted-foreground hover:text-foreground hover:bg-accent/60", "transition-all duration-200 ease-in-out overflow-hidden", hasSkillsSupport ? "opacity-100 w-8 scale-100 px-2" @@ -1375,7 +1375,7 @@ function App() { variant="ghost" size="sm" onClick={() => setCurrentView("prompts")} - className="text-muted-foreground hover:text-foreground hover:bg-black/5 dark:hover:bg-white/5" + className="text-muted-foreground hover:text-foreground hover:bg-accent/60" title={t("prompts.manage")} > @@ -1385,7 +1385,7 @@ function App() { size="sm" onClick={() => setCurrentView("sessions")} className={cn( - "text-muted-foreground hover:text-foreground hover:bg-black/5 dark:hover:bg-white/5", + "text-muted-foreground hover:text-foreground hover:bg-accent/60", "transition-all duration-200 ease-in-out overflow-hidden", hasSessionSupport ? "opacity-100 w-8 scale-100 px-2" @@ -1399,7 +1399,7 @@ function App() { variant="ghost" size="sm" onClick={() => setCurrentView("mcp")} - className="text-muted-foreground hover:text-foreground hover:bg-black/5 dark:hover:bg-white/5" + className="text-muted-foreground hover:text-foreground hover:bg-accent/60" title={t("mcp.title")} > diff --git a/src/components/ConfirmDialog.tsx b/src/components/ConfirmDialog.tsx index c2eb952b3d..c64b0638da 100644 --- a/src/components/ConfirmDialog.tsx +++ b/src/components/ConfirmDialog.tsx @@ -37,7 +37,7 @@ export function ConfirmDialog({ const IconComponent = variant === "info" ? Info : AlertTriangle; const iconClass = - variant === "info" ? "h-5 w-5 text-blue-500" : "h-5 w-5 text-destructive"; + variant === "info" ? "h-5 w-5 text-primary" : "h-5 w-5 text-destructive"; return ( {/* 主体内容整体右移,略大于标题内边距,让内容看起来不贴边 */} -
+
{request.resource === "prompt" && ( )} @@ -380,7 +380,7 @@ export function DeepLinkImportDialog() {
{t("deeplink.homepage")}
-
+
{request.homepage}
@@ -501,7 +501,7 @@ export function DeepLinkImportDialog() { {t("deeplink.configSource")}
- + {configSource === "base64" ? t("deeplink.configEmbedded") : t("deeplink.configRemote")} @@ -635,8 +635,8 @@ export function DeepLinkImportDialog() { {request.usageEnabled !== false @@ -703,7 +703,7 @@ export function DeepLinkImportDialog() { )} {/* Warning */} -
+
{t("deeplink.warning")}
diff --git a/src/components/JsonEditor.tsx b/src/components/JsonEditor.tsx index 8606602527..1c071ba5a5 100644 --- a/src/components/JsonEditor.tsx +++ b/src/components/JsonEditor.tsx @@ -84,54 +84,89 @@ const JsonEditor: React.FC = ({ // 创建编辑器扩展 const minHeightPx = height ? undefined : Math.max(1, rows) * 18; - // 使用 baseTheme 定义基础样式,优先级低于 oneDark,但可以正确响应主题 - const baseTheme = EditorView.baseTheme({ - ".cm-editor": { - border: "1px solid hsl(var(--border))", - borderRadius: "0.5rem", - background: "transparent", - }, - ".cm-editor.cm-focused": { - outline: "none", - borderColor: "hsl(var(--primary))", - }, - ".cm-scroller": { - background: "transparent", - }, - ".cm-gutters": { - background: "transparent", - borderRight: "1px solid hsl(var(--border))", - color: "hsl(var(--muted-foreground))", - }, - ".cm-selectionBackground, .cm-content ::selection": { - background: "hsl(var(--primary) / 0.18)", - }, - ".cm-selectionMatch": { - background: "hsl(var(--primary) / 0.12)", - }, - ".cm-activeLine": { - background: "hsl(var(--primary) / 0.08)", - }, - ".cm-activeLineGutter": { - background: "hsl(var(--primary) / 0.08)", - }, - }); - // 使用 theme 定义尺寸和字体样式 const heightValue = height ? typeof height === "number" ? `${height}px` : height : undefined; + const editorTheme = EditorView.theme( + { + "&": heightValue + ? { height: heightValue } + : { minHeight: `${minHeightPx}px` }, + ".cm-editor": { + height: "100%", + backgroundColor: "transparent", + color: "hsl(var(--foreground))", + }, + ".cm-editor.cm-focused": { + outline: "none", + }, + ".cm-scroller": { + overflow: "auto", + backgroundColor: "transparent", + }, + ".cm-content": { + padding: "0.875rem 0", + caretColor: "hsl(var(--primary))", + fontFamily: + "ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, 'Liberation Mono', 'Courier New', monospace", + fontSize: "14px", + }, + ".cm-line": { + padding: "0 1rem", + }, + ".cm-placeholder": { + color: "hsl(var(--muted-foreground) / 0.85)", + }, + ".cm-cursor, .cm-dropCursor": { + borderLeftColor: "hsl(var(--primary))", + }, + ".cm-gutters": { + minHeight: "100%", + backgroundColor: "hsl(var(--muted) / 0.65)", + color: "hsl(var(--muted-foreground))", + borderRight: "1px solid hsl(var(--border))", + }, + ".cm-gutterElement": { + padding: "0 0.75rem", + }, + ".cm-activeLine": { + backgroundColor: "hsl(var(--accent) / 0.28)", + }, + ".cm-activeLineGutter": { + backgroundColor: "hsl(var(--accent) / 0.4)", + color: "hsl(var(--foreground))", + }, + ".cm-selectionBackground, .cm-content ::selection": { + backgroundColor: "hsl(var(--primary) / 0.18) !important", + }, + ".cm-selectionMatch": { + backgroundColor: "hsl(var(--primary) / 0.12)", + }, + ".cm-matchingBracket": { + backgroundColor: "hsl(var(--accent) / 0.45)", + outline: "1px solid hsl(var(--border))", + color: "hsl(var(--foreground))", + }, + ".cm-nonmatchingBracket": { + color: "hsl(var(--destructive))", + }, + ".cm-panels, .cm-tooltip": { + backgroundColor: "hsl(var(--popover))", + color: "hsl(var(--popover-foreground))", + border: "1px solid hsl(var(--border))", + }, + ".cm-diagnosticText": { + color: "hsl(var(--destructive))", + }, + }, + { dark: darkMode }, + ); const sizingTheme = EditorView.theme({ - "&": heightValue - ? { height: heightValue } - : { minHeight: `${minHeightPx}px` }, - ".cm-scroller": { overflow: "auto" }, ".cm-content": { - fontFamily: - "ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, 'Liberation Mono', 'Courier New', monospace", - fontSize: "14px", + lineHeight: "1.6", }, }); @@ -139,7 +174,7 @@ const JsonEditor: React.FC = ({ basicSetup, language === "javascript" ? javascript() : json(), placeholder(placeholderText || ""), - baseTheme, + editorTheme, sizingTheme, jsonLinter, EditorView.updateListener.of((update) => { @@ -150,43 +185,8 @@ const JsonEditor: React.FC = ({ }), ]; - // 如果启用深色模式,添加深色主题 if (darkMode) { - extensions.push(oneDark); - // 在 oneDark 之后强制覆盖边框样式 - extensions.push( - EditorView.theme({ - ".cm-editor": { - border: "1px solid hsl(var(--border))", - borderRadius: "0.5rem", - background: "transparent", - }, - ".cm-editor.cm-focused": { - outline: "none", - borderColor: "hsl(var(--primary))", - }, - ".cm-scroller": { - background: "transparent", - }, - ".cm-gutters": { - background: "transparent", - borderRight: "1px solid hsl(var(--border))", - color: "hsl(var(--muted-foreground))", - }, - ".cm-selectionBackground, .cm-content ::selection": { - background: "hsl(var(--primary) / 0.18)", - }, - ".cm-selectionMatch": { - background: "hsl(var(--primary) / 0.12)", - }, - ".cm-activeLine": { - background: "hsl(var(--primary) / 0.08)", - }, - ".cm-activeLineGutter": { - background: "hsl(var(--primary) / 0.08)", - }, - }), - ); + extensions.unshift(oneDark); } // 创建初始状态 @@ -208,7 +208,7 @@ const JsonEditor: React.FC = ({ view.destroy(); viewRef.current = null; }; - }, [darkMode, rows, height, language, jsonLinter]); // 依赖项中不包含 onChange 和 placeholder,避免不必要的重建 + }, [darkMode, rows, height, language, jsonLinter, placeholderText]); // 当 value 从外部改变时更新编辑器内容 useEffect(() => { @@ -257,20 +257,28 @@ const JsonEditor: React.FC = ({ className={isFullHeight ? "flex flex-col" : ""} >
- {language === "json" && ( - - )} + className={`overflow-hidden rounded-[calc(var(--radius)+0.125rem)] border border-border/80 bg-card/85 shadow-sm ${ + isFullHeight ? "flex min-h-0 flex-1 flex-col" : "" + }`} + > +
+ {language === "json" && ( +
+ +
+ )} +
); }; diff --git a/src/components/MarkdownEditor.tsx b/src/components/MarkdownEditor.tsx index a59a64dcbb..add192f646 100644 --- a/src/components/MarkdownEditor.tsx +++ b/src/components/MarkdownEditor.tsx @@ -32,34 +32,70 @@ const MarkdownEditor: React.FC = ({ useEffect(() => { if (!editorRef.current) return; - // 定义基础主题 - const baseTheme = EditorView.baseTheme({ - "&": { - height: "100%", - minHeight, - maxHeight: maxHeight || "none", - }, - ".cm-scroller": { - overflow: "auto", - fontFamily: - "ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, 'Liberation Mono', 'Courier New', monospace", - fontSize: "14px", - }, - "&light .cm-content, &dark .cm-content": { - padding: "12px 0", - }, - "&light .cm-editor, &dark .cm-editor": { - backgroundColor: "transparent", - }, - "&.cm-focused": { - outline: "none", + const editorTheme = EditorView.theme( + { + "&": { + height: "100%", + minHeight, + maxHeight: maxHeight || "none", + }, + ".cm-editor": { + height: "100%", + backgroundColor: "transparent", + color: "hsl(var(--foreground))", + }, + ".cm-scroller": { + overflow: "auto", + backgroundColor: "transparent", + fontFamily: + "ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, 'Liberation Mono', 'Courier New', monospace", + fontSize: "14px", + }, + ".cm-content": { + padding: "0.875rem 1rem", + caretColor: "hsl(var(--primary))", + lineHeight: "1.6", + }, + ".cm-placeholder": { + color: "hsl(var(--muted-foreground) / 0.85)", + }, + ".cm-cursor, .cm-dropCursor": { + borderLeftColor: "hsl(var(--primary))", + }, + ".cm-gutters": { + minHeight: "100%", + backgroundColor: "hsl(var(--muted) / 0.65)", + color: "hsl(var(--muted-foreground))", + borderRight: "1px solid hsl(var(--border))", + }, + ".cm-gutterElement": { + padding: "0 0.75rem", + }, + ".cm-activeLine": { + backgroundColor: readOnly + ? "transparent" + : "hsl(var(--accent) / 0.28)", + }, + ".cm-activeLineGutter": { + backgroundColor: readOnly + ? "transparent" + : "hsl(var(--accent) / 0.4)", + color: "hsl(var(--foreground))", + }, + ".cm-selectionBackground, .cm-content ::selection": { + backgroundColor: "hsl(var(--primary) / 0.18) !important", + }, + "&.cm-focused": { + outline: "none", + }, }, - }); + { dark: darkMode }, + ); const extensions = [ basicSetup, markdown(), - baseTheme, + editorTheme, EditorView.lineWrapping, EditorState.readOnly.of(readOnly), ]; @@ -84,32 +120,8 @@ const MarkdownEditor: React.FC = ({ ); } - // 如果启用深色模式,添加深色主题 if (darkMode) { - extensions.push(oneDark); - } else { - // 浅色模式下的简单样式调整,使其更融入 UI - extensions.push( - EditorView.theme( - { - "&": { - backgroundColor: "transparent", - }, - ".cm-content": { - color: "#374151", // text-gray-700 - }, - ".cm-gutters": { - backgroundColor: "#f9fafb", // bg-gray-50 - color: "#9ca3af", // text-gray-400 - borderRight: "1px solid #e5e7eb", // border-gray-200 - }, - ".cm-activeLineGutter": { - backgroundColor: "#e5e7eb", - }, - }, - { dark: false }, - ), - ); + extensions.unshift(oneDark); } // 创建初始状态 @@ -149,9 +161,7 @@ const MarkdownEditor: React.FC = ({ return (
); }; diff --git a/src/components/UpdateBadge.tsx b/src/components/UpdateBadge.tsx index 04566a1bc7..46c1e21682 100644 --- a/src/components/UpdateBadge.tsx +++ b/src/components/UpdateBadge.tsx @@ -32,7 +32,7 @@ export function UpdateBadge({ className = "", onClick }: UpdateBadgeProps) { onClick={onClick} className={` relative h-8 w-8 rounded-full - ${isActive ? "text-green-600 dark:text-green-400 hover:bg-green-50 dark:hover:bg-green-500/10" : "text-muted-foreground hover:bg-muted/60"} + ${isActive ? "text-primary hover:bg-primary/10" : "text-muted-foreground hover:bg-muted/60"} ${className} `} > diff --git a/src/components/UsageFooter.tsx b/src/components/UsageFooter.tsx index 9b0654e526..28b3a7039d 100644 --- a/src/components/UsageFooter.tsx +++ b/src/components/UsageFooter.tsx @@ -78,7 +78,7 @@ const UsageFooter: React.FC = ({ if (inline) { return (
-
+
{t("usage.queryFailed")}
@@ -97,7 +97,7 @@ const UsageFooter: React.FC = ({ return (
-
+
{usage.error || t("usage.queryFailed")}
@@ -106,7 +106,7 @@ const UsageFooter: React.FC = ({
@@ -979,7 +979,7 @@ const UsageScriptModal: React.FC = ({ } placeholder="https://api.newapi.com" autoComplete="off" - className="border-white/10" + className="border-border/60" />
@@ -1002,7 +1002,7 @@ const UsageScriptModal: React.FC = ({ "usageScript.accessTokenPlaceholder", )} autoComplete="off" - className="border-white/10" + className="border-border/60" /> {script.accessToken && (
@@ -1050,7 +1050,7 @@ const UsageScriptModal: React.FC = ({ )} {/* 通用配置(始终显示) */} -
+
{/* 超时时间 */}
@@ -1110,7 +1110,7 @@ const UsageScriptModal: React.FC = ({ ), }) } - className="border-white/10" + className="border-border/60" />
@@ -1119,7 +1119,7 @@ const UsageScriptModal: React.FC = ({ {/* 提取器代码 - Copilot 模板不需要 */} {selectedTemplate !== TEMPLATE_TYPES.GITHUB_COPILOT && selectedTemplate !== TEMPLATE_TYPES.TOKEN_PLAN && ( -
+