mirror of
https://gitee.com/vant-contrib/vant.git
synced 2025-04-06 03:57:59 +08:00
78 lines
1.8 KiB
TypeScript
78 lines
1.8 KiB
TypeScript
import {
|
|
watch,
|
|
provide,
|
|
computed,
|
|
defineComponent,
|
|
type PropType,
|
|
type InjectionKey,
|
|
type CSSProperties,
|
|
type ExtractPropTypes,
|
|
} from 'vue';
|
|
import {
|
|
inBrowser,
|
|
kebabCase,
|
|
makeStringProp,
|
|
createNamespace,
|
|
} from '../utils';
|
|
|
|
const [name, bem] = createNamespace('config-provider');
|
|
|
|
export type ConfigProviderTheme = 'light' | 'dark';
|
|
|
|
export type ConfigProviderProvide = {
|
|
iconPrefix?: string;
|
|
};
|
|
|
|
export const CONFIG_PROVIDER_KEY: InjectionKey<ConfigProviderProvide> =
|
|
Symbol(name);
|
|
|
|
const configProviderProps = {
|
|
tag: makeStringProp<keyof HTMLElementTagNameMap>('div'),
|
|
theme: makeStringProp<ConfigProviderTheme>('light'),
|
|
themeVars: Object as PropType<Record<string, string | number>>,
|
|
iconPrefix: String,
|
|
};
|
|
|
|
export type ConfigProviderProps = ExtractPropTypes<typeof configProviderProps>;
|
|
|
|
function mapThemeVarsToCSSVars(themeVars: Record<string, string | number>) {
|
|
const cssVars: Record<string, string | number> = {};
|
|
Object.keys(themeVars).forEach((key) => {
|
|
cssVars[`--van-${kebabCase(key)}`] = themeVars[key];
|
|
});
|
|
return cssVars;
|
|
}
|
|
|
|
export default defineComponent({
|
|
name,
|
|
|
|
props: configProviderProps,
|
|
|
|
setup(props, { slots }) {
|
|
const style = computed<CSSProperties | undefined>(() => {
|
|
if (props.themeVars) {
|
|
return mapThemeVarsToCSSVars(props.themeVars);
|
|
}
|
|
});
|
|
|
|
if (inBrowser) {
|
|
watch(
|
|
() => props.theme,
|
|
(newVal, oldVal) => {
|
|
document.body.classList.remove(`van-theme-${oldVal}`);
|
|
document.body.classList.add(`van-theme-${newVal}`);
|
|
},
|
|
{ immediate: true }
|
|
);
|
|
}
|
|
|
|
provide(CONFIG_PROVIDER_KEY, props);
|
|
|
|
return () => (
|
|
<props.tag class={bem()} style={style.value}>
|
|
{slots.default?.()}
|
|
</props.tag>
|
|
);
|
|
},
|
|
});
|