|
|
@@ -1,5 +1,5 @@
|
|
|
-import { computed, inject, provide, type ComputedRef } from "vue";
|
|
|
-import { DefaultTheme } from "./Theme";
|
|
|
+import { computed, inject, provide, ref, shallowRef, type ComputedRef, type Ref } from "vue";
|
|
|
+import { DefaultDarkTheme, DefaultTheme } from "./Theme";
|
|
|
import type { DynamicVarType } from "./ThemeTools";
|
|
|
import { ObjectUtils } from "@imengyu/imengyu-utils";
|
|
|
|
|
|
@@ -24,6 +24,10 @@ export interface ThemeConfig {
|
|
|
textConfigs: Record<string, Record<string, string|object>>,
|
|
|
}
|
|
|
|
|
|
+function popInjectTheme() : ThemeConfig {
|
|
|
+ return inject<Ref<ThemeConfig>>(ThemeKey)?.value ?? DefaultTheme;
|
|
|
+}
|
|
|
+
|
|
|
/**
|
|
|
* 在PropDefault回调中使用主题默认值的函数
|
|
|
* @param key
|
|
|
@@ -31,7 +35,7 @@ export interface ThemeConfig {
|
|
|
* @returns
|
|
|
*/
|
|
|
export function propGetThemeVar<T>(key: string, defaultValue?: T) : T {
|
|
|
- const theme = (inject(ThemeKey, DefaultTheme) as ThemeConfig);
|
|
|
+ const theme = popInjectTheme();
|
|
|
return theme?.varOverrides[key] ?? defaultValue;
|
|
|
}
|
|
|
/**
|
|
|
@@ -40,33 +44,40 @@ export function propGetThemeVar<T>(key: string, defaultValue?: T) : T {
|
|
|
* @returns 回调函数的返回值
|
|
|
*/
|
|
|
export function propGetThemeVar2(cb: (getVar: (key: string, defaultValue: any) => any, theme: ThemeConfig) => any) {
|
|
|
- const theme = (inject(ThemeKey, DefaultTheme) as ThemeConfig);
|
|
|
+ const theme = popInjectTheme();
|
|
|
return cb((key, defaultValue) => getVar(theme, key, defaultValue), theme);
|
|
|
}
|
|
|
|
|
|
|
|
|
-export function provideTheme(theme: ThemeConfig) {
|
|
|
- provide(ThemeKey, theme);
|
|
|
-}
|
|
|
export function provideSomeThemeColor(record: Record<string, any>) {
|
|
|
- const v = {
|
|
|
- ...DefaultTheme,
|
|
|
- colorConfigs: {
|
|
|
- ...DefaultTheme.colorConfigs,
|
|
|
- ...record
|
|
|
- }
|
|
|
- } as ThemeConfig;
|
|
|
- provide(ThemeKey, v);
|
|
|
+ const topTheme = inject<Ref<ThemeConfig>>(ThemeKey);
|
|
|
+ const newTheme = computed(() => {
|
|
|
+ const topThemeValue = topTheme?.value ?? DefaultTheme;
|
|
|
+ const v = {
|
|
|
+ ...topThemeValue,
|
|
|
+ colorConfigs: {
|
|
|
+ ...topThemeValue.colorConfigs,
|
|
|
+ ...record
|
|
|
+ }
|
|
|
+ } as ThemeConfig;
|
|
|
+ return v;
|
|
|
+ });
|
|
|
+ provide(ThemeKey, newTheme);
|
|
|
}
|
|
|
export function provideSomeThemeVar(record: Record<string, any>) {
|
|
|
- const v = {
|
|
|
- ...DefaultTheme,
|
|
|
- varOverrides: {
|
|
|
- ...DefaultTheme.varOverrides,
|
|
|
- ...record
|
|
|
- }
|
|
|
- } as ThemeConfig;
|
|
|
- provide(ThemeKey, v);
|
|
|
+ const topTheme = inject<Ref<ThemeConfig>>(ThemeKey);
|
|
|
+ const newTheme = computed(() => {
|
|
|
+ const topThemeValue = topTheme?.value ?? DefaultTheme;
|
|
|
+ const v = {
|
|
|
+ ...topThemeValue,
|
|
|
+ varOverrides: {
|
|
|
+ ...topThemeValue.varOverrides,
|
|
|
+ ...record
|
|
|
+ }
|
|
|
+ } as ThemeConfig;
|
|
|
+ return v;
|
|
|
+ });
|
|
|
+ provide(ThemeKey, newTheme);
|
|
|
}
|
|
|
|
|
|
export function getVar<T>(theme : ThemeConfig, key: string, defaultValue: T) : T {
|
|
|
@@ -77,7 +88,8 @@ export function getVar<T>(theme : ThemeConfig, key: string, defaultValue: T) : T
|
|
|
* 主题的组合代码
|
|
|
*/
|
|
|
export function useTheme() {
|
|
|
- const theme = inject(ThemeKey, DefaultTheme) as ThemeConfig;
|
|
|
+ const topTheme = inject<Ref<ThemeConfig>>(ThemeKey);
|
|
|
+ const theme = computed(() => topTheme?.value ?? DefaultTheme);
|
|
|
|
|
|
function resolveThemeSize(inValue?: string|number, defaultValue?: string|number) : string|undefined {
|
|
|
const preResolve = resolveSize(inValue);
|
|
|
@@ -131,9 +143,9 @@ export function useTheme() {
|
|
|
key = getVar(key, key);
|
|
|
if (key.includes('.'))
|
|
|
[type, key] = key.split('.');
|
|
|
- let group = theme.colorConfigs[type || 'default'];
|
|
|
+ let group = theme.value.colorConfigs[type || 'default'];
|
|
|
if (!group)
|
|
|
- group = theme.colorConfigs['default'];
|
|
|
+ group = theme.value.colorConfigs['default'];
|
|
|
return group?.[key] ?? defaultValue;
|
|
|
}
|
|
|
function getSize(key: string, defaultValue?: string|number) {
|
|
|
@@ -144,14 +156,14 @@ export function useTheme() {
|
|
|
[type, key] = key.split('.');
|
|
|
let v: any = undefined;
|
|
|
if (type) {
|
|
|
- const group = theme.varOverrides[type];
|
|
|
+ const group = theme.value.varOverrides[type];
|
|
|
v = group?.[key];
|
|
|
} else
|
|
|
- v = theme.varOverrides[key];
|
|
|
+ v = theme.value.varOverrides[key];
|
|
|
return resolveSize(v ?? defaultValue);
|
|
|
}
|
|
|
function getText(key: string, defaultValue: Record<string, string>) {
|
|
|
- return theme.textConfigs[key]?? defaultValue;
|
|
|
+ return theme.value.textConfigs[key]?? defaultValue;
|
|
|
}
|
|
|
function getVar<T>(key: string, defaultValue: T) : T {
|
|
|
let rs = undefined;
|
|
|
@@ -159,10 +171,10 @@ export function useTheme() {
|
|
|
if (key.includes('.'))
|
|
|
[type, key] = key.split('.');
|
|
|
if (type) {
|
|
|
- const group = theme.varOverrides[type];
|
|
|
+ const group = theme.value.varOverrides[type];
|
|
|
rs = group?.[key];
|
|
|
} else
|
|
|
- rs = theme.varOverrides[key];
|
|
|
+ rs = theme.value.varOverrides[key];
|
|
|
return rs ?? defaultValue;
|
|
|
}
|
|
|
|
|
|
@@ -278,7 +290,50 @@ export interface ThemePaddingMargin {
|
|
|
/**
|
|
|
* 配置主题变量,建议在App.vue中调用
|
|
|
* @param cb 回调函数,参数为默认主题配置,返回值为新的主题配置
|
|
|
+ * @returns 主题配置对象,返回currentTheme为当前主题,可以修改为其他主题对象,但请注意主题对象为shallowRef,
|
|
|
+ * 直接修改主题对象的属性不会触发主题更新,需要调用currentTheme.value = newTheme新的对象来更新主题。
|
|
|
+ */
|
|
|
+export function configTheme(
|
|
|
+ /**
|
|
|
+ * 是否自动匹配系统深色主题
|
|
|
+ * @default true
|
|
|
+ */
|
|
|
+ autoMatchSystemDark?: boolean,
|
|
|
+ /**
|
|
|
+ * 回调函数,用于配置修改主题,参数为默认主题配置,返回值为新的主题配置
|
|
|
+ * @default undefined
|
|
|
+ * @returns 可以返回新的主题对象或者是传入的对象,第一个为亮色主题,第二个为深色主题
|
|
|
+ */
|
|
|
+ cb?: (defaultTheme: ThemeConfig, defaultDarkTheme: ThemeConfig) => [ThemeConfig,ThemeConfig]
|
|
|
+) {
|
|
|
+ let defaultTheme = ObjectUtils.clone(DefaultTheme);
|
|
|
+ let defaultDarkTheme = ObjectUtils.clone(DefaultDarkTheme);
|
|
|
+ const [theme, darkTheme] = cb?.(defaultTheme, defaultDarkTheme) ?? [defaultTheme, defaultDarkTheme];
|
|
|
+ const currentSystemDark = ref(uni.getSystemInfoSync().theme === 'dark');
|
|
|
+
|
|
|
+ console.log(uni.getSystemInfoSync());
|
|
|
+
|
|
|
+ const currentTheme = shallowRef(currentSystemDark.value ? darkTheme : theme);
|
|
|
+ provide(ThemeKey, currentTheme);
|
|
|
+
|
|
|
+ if (autoMatchSystemDark !== false) {
|
|
|
+ // 监听系统主题变化
|
|
|
+ uni.onThemeChange((res) => {
|
|
|
+ currentSystemDark.value = res.theme === 'dark';
|
|
|
+ currentTheme.value = currentSystemDark.value ? darkTheme : theme;
|
|
|
+ });
|
|
|
+ }
|
|
|
+
|
|
|
+ return {
|
|
|
+ currentTheme,
|
|
|
+ }
|
|
|
+}
|
|
|
+/**
|
|
|
+ * 克隆默认主题,用于自定义主题
|
|
|
+ * @param cb 回调函数,参数为默认主题配置,返回值为新的主题配置
|
|
|
+ * @param dark 是否为深色主题,默认false为亮色主题
|
|
|
+ * @returns 新的主题配置对象
|
|
|
*/
|
|
|
-export function configTheme(cb: (defaultTheme: ThemeConfig) => ThemeConfig) {
|
|
|
- provide(ThemeKey, cb(ObjectUtils.clone(DefaultTheme)));
|
|
|
+export function cloneTheme(dark?: boolean, cb?: (defaultTheme: ThemeConfig) => ThemeConfig) {
|
|
|
+ return cb?.(ObjectUtils.clone(dark ? DefaultDarkTheme : DefaultTheme)) ?? ObjectUtils.clone(dark ? DefaultDarkTheme : DefaultTheme);
|
|
|
}
|