CNCEC_APP/uni_modules/uview-pro/libs/hooks/useTheme.ts

174 lines
5.0 KiB
TypeScript
Raw Normal View History

2026-03-25 14:54:15 +08:00
/**
* composable
* CSS
*
* 使
* const { currentTheme, themes, setTheme, getDarkMode, setDarkMode, isInDarkMode, getAvailableThemes, initTheme } = useTheme()
*/
import type { DarkMode, Theme } from '../../types/global';
import configProvider, { type DefaultThemeConfig } from '../util/config-provider';
import { defaultThemes } from '../config/theme-tokens';
const THEME_STORAGE_KEY = 'uview-pro-theme';
const DARK_MODE_STORAGE_KEY = 'uview-pro-dark-mode';
const themesRef = configProvider.themesRef;
const currentTheme = configProvider.currentThemeRef;
const darkModeRef = configProvider.darkModeRef;
/**
* Storage
*/
function saveThemeToStorage(themeName: string) {
try {
uni.setStorageSync(THEME_STORAGE_KEY, themeName);
} catch (e) {
console.warn('[useTheme] failed to write storage', e);
}
}
/**
* Storage
*/
function saveDarkModeToStorage(mode: DarkMode) {
try {
uni.setStorageSync(DARK_MODE_STORAGE_KEY, mode);
} catch (e) {
console.warn('[useTheme] failed to write storage', e);
}
}
/**
*
*/
function setTheme(themeName: string) {
configProvider.setTheme(themeName);
currentTheme.value = configProvider.getCurrentTheme();
saveThemeToStorage(themeName);
}
/**
*
*/
function getCurrentTheme(): Theme | null {
return currentTheme.value || configProvider.getCurrentTheme();
}
/**
*
*/
function getAvailableThemes() {
return configProvider.getThemes();
}
/**
*
* @param themes uni.$u.themes
* @param defaultConfig { defaultTheme?, defaultDarkMode? }
*/
export function initTheme(themes?: Theme[], defaultConfig?: string | DefaultThemeConfig, isForce?: boolean) {
// 如果有传入主题列表,使用传入的
if (Array.isArray(themes) && themes.length > 0) {
configProvider.initTheme(themes, defaultConfig, isForce);
return;
}
// // 若已通过插件或其他方式完成初始化,则不再覆盖,最多按需切换默认主题
// const existingThemes = configProvider.getThemes();
// if (existingThemes.length > 0) {
// if (typeof defaultConfig === 'string') {
// configProvider.setTheme(defaultConfig);
// } else if (defaultConfig && typeof defaultConfig === 'object' && (defaultConfig as any).defaultTheme) {
// configProvider.setTheme(defaultConfig.defaultTheme);
// } else if (!configProvider.getCurrentTheme()) {
// configProvider.setTheme(existingThemes[0].name);
// } else {
// // 触发一次 apply便于初始化 CSS 变量
// configProvider.setTheme(configProvider.getCurrentTheme()!.name);
// }
// return;
// }
// // 初始化 configProvider如果运行时提供了内置主题
// try {
// const builtin = (typeof uni !== 'undefined' && (uni as any).$u && (uni as any).$u.themes) || [];
// if (Array.isArray(builtin) && builtin.length > 0) {
// configProvider.initTheme(builtin as Theme[], defaultConfig);
// return;
// }
// } catch (e) {
// // ignore
// }
// 回退到内置默认主题
configProvider.initTheme(defaultThemes as Theme[], defaultConfig);
}
/**
*
* @param darkMode
* @param isForce
*/
function initDarkMode(darkMode?: DarkMode, isForce?: boolean) {
configProvider.initDarkMode(darkMode, isForce);
}
/**
*
*/
function getDarkMode(): DarkMode {
return configProvider.getDarkMode();
}
/**
*
* @param mode 'auto' () | 'light' () | 'dark' ()
*/
function setDarkMode(mode: DarkMode) {
configProvider.setDarkMode(mode);
darkModeRef.value = mode;
saveDarkModeToStorage(mode);
}
/**
*
*/
function isInDarkMode(): boolean {
return configProvider.isInDarkMode();
}
/**
*
*/
function toggleDarkMode() {
const current = getDarkMode();
const nextMode = current === 'dark' ? 'light' : 'dark';
setDarkMode(nextMode);
}
/**
* 使 composable
*
*/
export function useTheme() {
return {
// 响应式引用
currentTheme,
themes: themesRef,
darkMode: darkModeRef,
cssVars: configProvider.cssVarsRef,
// 主题相关方法
initTheme,
setTheme,
getCurrentTheme,
getAvailableThemes,
// 暗黑模式相关方法
initDarkMode,
getDarkMode,
setDarkMode,
isInDarkMode,
toggleDarkMode
};
}