diff --git a/src/components/JsonEditor.tsx b/src/components/JsonEditor.tsx index d24184a..8f16ca7 100644 --- a/src/components/JsonEditor.tsx +++ b/src/components/JsonEditor.tsx @@ -78,6 +78,20 @@ const JsonEditor: React.FC = ({ // 创建编辑器扩展 const minHeightPx = height ? undefined : Math.max(1, rows) * 18; + + // 使用 baseTheme 定义基础样式,优先级低于 oneDark,但可以正确响应主题 + const baseTheme = EditorView.baseTheme({ + "&light .cm-editor, &dark .cm-editor": { + border: "1px solid hsl(var(--border))", + borderRadius: "0.5rem", + }, + "&light .cm-editor.cm-focused, &dark .cm-editor.cm-focused": { + outline: "none", + borderColor: "hsl(var(--primary))", + }, + }); + + // 使用 theme 定义尺寸和字体样式 const sizingTheme = EditorView.theme({ "&": height ? { height } : { minHeight: `${minHeightPx}px` }, ".cm-scroller": { overflow: "auto" }, @@ -86,20 +100,13 @@ const JsonEditor: React.FC = ({ "ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, 'Liberation Mono', 'Courier New', monospace", fontSize: "14px", }, - ".cm-editor": { - border: "1px solid hsl(var(--border))", - borderRadius: "0.5rem", - }, - ".cm-editor.cm-focused": { - outline: "none", - borderColor: "hsl(var(--primary))", - }, }); const extensions = [ basicSetup, language === "javascript" ? javascript() : json(), placeholder(placeholderText || ""), + baseTheme, sizingTheme, jsonLinter, EditorView.updateListener.of((update) => { @@ -113,6 +120,19 @@ 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", + }, + ".cm-editor.cm-focused": { + outline: "none", + borderColor: "hsl(var(--primary))", + }, + }), + ); } // 创建初始状态 diff --git a/src/components/providers/forms/ClaudeConfigEditor.tsx b/src/components/providers/forms/ClaudeConfigEditor.tsx index 2846526..ba0c3b8 100644 --- a/src/components/providers/forms/ClaudeConfigEditor.tsx +++ b/src/components/providers/forms/ClaudeConfigEditor.tsx @@ -1,5 +1,4 @@ import React, { useEffect, useState } from "react"; -import JsonEditor from "@/components/JsonEditor"; import { Save } from "lucide-react"; import { useTranslation } from "react-i18next"; import { @@ -33,34 +32,8 @@ const ClaudeConfigEditor: React.FC = ({ configError, }) => { const { t } = useTranslation(); - const [isDarkMode, setIsDarkMode] = useState(false); const [isCommonConfigModalOpen, setIsCommonConfigModalOpen] = useState(false); - useEffect(() => { - // 检测暗色模式 - const checkDarkMode = () => { - setIsDarkMode(document.documentElement.classList.contains("dark")); - }; - - checkDarkMode(); - - // 监听暗色模式变化 - const observer = new MutationObserver((mutations) => { - mutations.forEach((mutation) => { - if (mutation.attributeName === "class") { - checkDarkMode(); - } - }); - }); - - observer.observe(document.documentElement, { - attributes: true, - attributeFilter: ["class"], - }); - - return () => observer.disconnect(); - }, []); - useEffect(() => { if (commonConfigError && !isCommonConfigModalOpen) { setIsCommonConfigModalOpen(true); @@ -70,6 +43,7 @@ const ClaudeConfigEditor: React.FC = ({ const closeModal = () => { setIsCommonConfigModalOpen(false); }; + return (
@@ -84,7 +58,7 @@ const ClaudeConfigEditor: React.FC = ({ type="checkbox" checked={useCommonConfig} onChange={(e) => onCommonConfigToggle(e.target.checked)} - className="w-4 h-4 text-blue-500 bg-white dark:bg-gray-800 border-border-default rounded focus:ring-blue-500 dark:focus:ring-blue-400 focus:ring-2" + className="w-4 h-4 text-blue-500 bg-white dark:bg-gray-800 border-border-default rounded focus:ring-blue-500 dark:focus:ring-blue-400 focus:ring-2" /> {t("claudeConfig.writeCommonConfig")} @@ -103,10 +77,10 @@ const ClaudeConfigEditor: React.FC = ({ {commonConfigError}

)} - onChange(e.target.value)} placeholder={`{ "env": { "ANTHROPIC_BASE_URL": "https://your-api-endpoint.com", @@ -114,6 +88,16 @@ const ClaudeConfigEditor: React.FC = ({ } }`} rows={12} + className="w-full px-3 py-2 border border-border-default dark:bg-gray-800 dark:text-gray-100 rounded-lg text-sm font-mono focus:outline-none focus:ring-2 focus:ring-blue-500/20 dark:focus:ring-blue-400/20 focus:border-border-active transition-colors resize-y min-h-[14rem]" + autoComplete="off" + autoCorrect="off" + autoCapitalize="none" + spellCheck={false} + lang="en" + inputMode="text" + data-gramm="false" + data-gramm_editor="false" + data-enable-grammarly="false" /> {configError && (

{configError}

@@ -138,11 +122,20 @@ const ClaudeConfigEditor: React.FC = ({

{t("claudeConfig.commonConfigHint")}

- onCommonConfigSnippetChange(e.target.value)} rows={12} + className="w-full px-3 py-2 border border-border-default dark:bg-gray-800 dark:text-gray-100 rounded-lg text-sm font-mono focus:outline-none focus:ring-2 focus:ring-blue-500/20 dark:focus:ring-blue-400/20 focus:border-border-active transition-colors resize-y min-h-[14rem]" + autoComplete="off" + autoCorrect="off" + autoCapitalize="none" + spellCheck={false} + lang="en" + inputMode="text" + data-gramm="false" + data-gramm_editor="false" + data-enable-grammarly="false" /> {commonConfigError && (

diff --git a/src/components/providers/forms/CommonConfigEditor.tsx b/src/components/providers/forms/CommonConfigEditor.tsx index b7e6d1c..ee1be6d 100644 --- a/src/components/providers/forms/CommonConfigEditor.tsx +++ b/src/components/providers/forms/CommonConfigEditor.tsx @@ -6,9 +6,6 @@ import { DialogTitle, } from "@/components/ui/dialog"; import { Label } from "@/components/ui/label"; -import JsonEditor from "@/components/JsonEditor"; -import { useTheme } from "@/components/theme-provider"; -import { useMemo } from "react"; interface CommonConfigEditorProps { value: string; @@ -36,15 +33,6 @@ export function CommonConfigEditor({ onModalClose, }: CommonConfigEditorProps) { const { t } = useTranslation(); - const { theme } = useTheme(); - - const isDarkMode = useMemo(() => { - if (theme === "dark") return true; - if (theme === "light") return false; - return typeof window !== "undefined" - ? window.document.documentElement.classList.contains("dark") - : false; - }, [theme]); return ( <> @@ -60,7 +48,7 @@ export function CommonConfigEditor({ id="useCommonConfig" checked={useCommonConfig} onChange={(e) => onCommonConfigToggle(e.target.checked)} - className="w-4 h-4 text-blue-500 bg-white dark:bg-gray-800 border-border-default rounded focus:ring-blue-500 dark:focus:ring-blue-400 focus:ring-2" + className="w-4 h-4 text-blue-500 bg-white dark:bg-gray-800 border-border-default rounded focus:ring-blue-500 dark:focus:ring-blue-400 focus:ring-2" /> {t("claudeConfig.writeCommonConfig", { @@ -86,21 +74,28 @@ export function CommonConfigEditor({ {commonConfigError}

)} -
- onChange(e.target.value)} + placeholder={`{ "env": { "ANTHROPIC_BASE_URL": "https://your-api-endpoint.com", "ANTHROPIC_AUTH_TOKEN": "your-api-key-here" } }`} - darkMode={isDarkMode} - rows={14} - showValidation - /> -
+ rows={14} + className="w-full px-3 py-2 border border-border-default dark:bg-gray-800 dark:text-gray-100 rounded-lg text-sm font-mono focus:outline-none focus:ring-2 focus:ring-blue-500/20 dark:focus:ring-blue-400/20 focus:border-border-active transition-colors resize-y min-h-[16rem]" + autoComplete="off" + autoCorrect="off" + autoCapitalize="none" + spellCheck={false} + lang="en" + inputMode="text" + data-gramm="false" + data-gramm_editor="false" + data-enable-grammarly="false" + />

{t("claudeConfig.fullSettingsHint", { defaultValue: "请填写完整的 Claude Code 配置", @@ -126,14 +121,21 @@ export function CommonConfigEditor({ defaultValue: "通用配置片段将合并到所有启用它的供应商配置中", })}

-
- -
+