import { ref, watch } from 'vue'; import { theme } from 'ant-design-vue'; const primaryColor = ref('#1890ff'); const isDark = ref(false); const fontFamily = ref('default'); const codeFontFamily = ref('default'); export function useTheme() { const toggleTheme = (color) => { primaryColor.value = color; updateCSSVariables(); }; const toggleDarkMode = (dark) => { isDark.value = dark; updateCSSVariables(); }; const setFontFamily = (font) => { fontFamily.value = font; updateCSSVariables(); }; const setCodeFontFamily = (font) => { codeFontFamily.value = font; updateCSSVariables(); }; const updateCSSVariables = () => { const root = document.documentElement; root.dataset.theme = isDark.value ? 'dark' : 'light'; root.style.setProperty('--primary-color', primaryColor.value); // 生成一个浅色背景用于选中态 root.style.setProperty('--primary-color-bg', primaryColor.value + '1A'); // 10% opacity // 字体设置 let fontValue = '-apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif'; if (fontFamily.value === 'lxgw') { fontValue = '"LXGW WenKai Screen", sans-serif'; } else if (fontFamily.value === 'serif') { fontValue = '"Noto Serif SC", serif'; } else if (fontFamily.value === 'zcool') { fontValue = '"ZCOOL KuaiLe", cursive'; } root.style.setProperty('--app-font-family', fontValue); let codeFontValue = 'SFMono-Regular, Consolas, "Liberation Mono", Menlo, monospace'; if (codeFontFamily.value === 'fira') { codeFontValue = '"Fira Code", monospace'; } root.style.setProperty('--editor-font-family', codeFontValue); if (isDark.value) { root.style.setProperty('--app-background', '#141414'); root.style.setProperty('--card-background', '#1f1f1f'); root.style.setProperty('--text-color', 'rgba(255, 255, 255, 0.85)'); root.style.setProperty('--border-color', '#303030'); root.style.setProperty('--hover-background', 'rgba(255, 255, 255, 0.08)'); root.style.setProperty('--text-color-secondary', 'rgba(255, 255, 255, 0.45)'); root.style.setProperty('--scrollbar-thumb', 'rgba(255, 255, 255, 0.28)'); } else { root.style.setProperty('--app-background', '#f4f4f4'); root.style.setProperty('--card-background', '#ffffff'); root.style.setProperty('--text-color', 'rgba(0, 0, 0, 0.85)'); root.style.setProperty('--border-color', '#f0f0f0'); root.style.setProperty('--hover-background', 'rgba(0, 0, 0, 0.04)'); root.style.setProperty('--text-color-secondary', 'rgba(0, 0, 0, 0.45)'); root.style.setProperty('--scrollbar-thumb', 'rgba(0, 0, 0, 0.28)'); } }; const getAntdTheme = () => { const layoutBackground = isDark.value ? '#141414' : '#f4f4f4'; const containerBackground = isDark.value ? '#1f1f1f' : '#ffffff'; const textColor = isDark.value ? 'rgba(255, 255, 255, 0.85)' : 'rgba(0, 0, 0, 0.85)'; const textColorSecondary = isDark.value ? 'rgba(255, 255, 255, 0.45)' : 'rgba(0, 0, 0, 0.45)'; const borderColor = isDark.value ? '#303030' : '#f0f0f0'; const hoverBackground = isDark.value ? 'rgba(255, 255, 255, 0.08)' : 'rgba(0, 0, 0, 0.04)'; return { algorithm: isDark.value ? theme.darkAlgorithm : theme.defaultAlgorithm, token: { colorPrimary: primaryColor.value, colorBgLayout: layoutBackground, colorBgContainer: containerBackground, colorBgElevated: containerBackground, colorText: textColor, colorTextSecondary: textColorSecondary, colorBorder: borderColor, colorFillTertiary: hoverBackground, fontSize: 15, }, }; }; const setGlobalTheme = (color, dark) => { if (color) primaryColor.value = color; if (typeof dark === 'boolean') isDark.value = dark; updateCSSVariables(); }; return { primaryColor, isDark, toggleTheme, toggleDarkMode, getAntdTheme, setGlobalTheme, fontFamily, codeFontFamily, setFontFamily, setCodeFontFamily }; }