markdown/src/composables/useTheme.js

117 lines
4.0 KiB
JavaScript

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
};
}