Skip to content

Commit

Permalink
feat(vue): 重写主题为 vue 插件
Browse files Browse the repository at this point in the history
  • Loading branch information
YuJianghao committed Nov 12, 2021
1 parent 54f6fee commit 3b0b8be
Show file tree
Hide file tree
Showing 12 changed files with 178 additions and 172 deletions.
22 changes: 0 additions & 22 deletions packages/hexon-web/.storybook/preview.js

This file was deleted.

27 changes: 27 additions & 0 deletions packages/hexon-web/.storybook/preview.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import { Parameters, Decorators, app } from "@storybook/vue3";
import themes from "../src/themes";
import "../src/styles/reset.less";
import { useThemeController } from "../src/lib/theme";

app.use(themes);

export const parameters: Parameters = {
actions: { argTypesRegex: "^on[A-Z].*" },
controls: {
matchers: {
color: /(background|color)$/i,
date: /Date$/,
},
},
};

export const decorators: Decorators = [
() => ({
setup() {
const t = useThemeController();
const styles = t?.styles;
return { styles };
},
template: '<div :style="styles"><story /></div>',
}),
];
12 changes: 5 additions & 7 deletions packages/hexon-web/src/App.vue
Original file line number Diff line number Diff line change
@@ -1,18 +1,16 @@
<script setup lang="ts">
import account from "./account";
import { useAccountProvider } from "./lib/account";
import { blueTheme } from "./themes";
import { ThemeProvider, useThemeSwitcherProvider } from "./lib/theme";
const switcher = useThemeSwitcherProvider("blue", blueTheme);
const theme = switcher.theme;
import { useThemeController } from "./lib/theme";
useAccountProvider(account);
const theme = useThemeController();
const styles = theme?.styles;
</script>

<template>
<ThemeProvider :theme="theme">
<div :style="styles">
<router-view></router-view>
</ThemeProvider>
</div>
</template>

<style lang="less">
Expand Down
16 changes: 8 additions & 8 deletions packages/hexon-web/src/components/HButton.vue
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ button {
width: 32px;
}
&.primary {
background-color: var(--color-primary-0);
background-color: var(--color-primary-n);
color: var(--color-foreground-9);
&:hover {
background-color: var(--color-primary-l2);
Expand All @@ -71,7 +71,7 @@ button {
background-color: var(--color-primary-l4);
}
&.inverted {
color: var(--color-primary-0);
color: var(--color-primary-n);
background-color: var(--color-background-1);
&:hover {
background-color: var(--color-primary-l9);
Expand All @@ -82,7 +82,7 @@ button {
}
}
&.success {
background-color: var(--color-success-0);
background-color: var(--color-success-n);
color: var(--color-foreground-9);
&:hover {
background-color: var(--color-success-l2);
Expand All @@ -91,7 +91,7 @@ button {
background-color: var(--color-success-l4);
}
&.inverted {
color: var(--color-success-0);
color: var(--color-success-n);
background-color: var(--color-background-1);
&:hover {
background-color: var(--color-success-l9);
Expand All @@ -102,7 +102,7 @@ button {
}
}
&.warning {
background-color: var(--color-warning-0);
background-color: var(--color-warning-n);
color: var(--color-foreground-9);
&:hover {
background-color: var(--color-warning-l2);
Expand All @@ -111,7 +111,7 @@ button {
background-color: var(--color-warning-l4);
}
&.inverted {
color: var(--color-warning-0);
color: var(--color-warning-n);
background-color: var(--color-background-1);
&:hover {
background-color: var(--color-warning-l9);
Expand All @@ -122,7 +122,7 @@ button {
}
}
&.error {
background-color: var(--color-error-0);
background-color: var(--color-error-n);
color: var(--color-foreground-9);
&:hover {
background-color: var(--color-error-l2);
Expand All @@ -131,7 +131,7 @@ button {
background-color: var(--color-error-l4);
}
&.inverted {
color: var(--color-error-0);
color: var(--color-error-n);
background-color: var(--color-background-1);
&:hover {
background-color: var(--color-error-l9);
Expand Down
71 changes: 0 additions & 71 deletions packages/hexon-web/src/lib/theme/core.ts

This file was deleted.

92 changes: 89 additions & 3 deletions packages/hexon-web/src/lib/theme/index.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,89 @@
export * from "./core";
export * from "./switcher";
export * from "./types";
import { App, InjectionKey, inject, computed, ref, ComputedRef } from "vue";

import { DEV } from "../../utils";
export interface ITheme {
[key: string]: string | ITheme;
}

function serialize(
obj: ITheme = {},
prefix: string = "-"
): { [key: string]: string } {
return Object.keys(obj).reduce((o, key) => {
const value = obj[key];
const name = `${prefix}-${key}`;
if (typeof value === "string") {
o[name] = value;
return o;
} else {
const res = serialize(value, name);
return { ...o, ...res };
}
}, {} as { [key: string]: string });
}

const themeProviderInjectionKey: InjectionKey<Theme<any>> = Symbol("theme");

type ThemeMap<T> = {
default: T;
[key: string]: T;
};

class Theme<T extends ITheme = ITheme> {
private name = ref("default");
private map = new Map<string, T>();
constructor(map: ThemeMap<T>) {
this.map = new Map(Object.entries(map));
}
install(app: App, injectKey?: InjectionKey<Theme<any>> | string) {
app.provide(injectKey || themeProviderInjectionKey, this);
}
changeTheme(name: string) {
if (!this.map.has(name)) {
DEV && console.warn(`theme ${name} not found`);
return;
}
this.name.value = name;
}
setTheme(name: string, theme: T) {
this.map.set(name, theme);
}
deleteTheme(name: string) {
if (name === "default") {
DEV &&
console.warn(
`can not delete default theme, try change it by \`setTheme('default', newTheme)\``
);
return;
}
this.map.delete(name);
}
get data() {
return computed(() => this.map.get(this.name.value));
}
get styles() {
return computed(() => serialize(this.data.value));
}
get currentTheme() {
return computed(() => this.name.value);
}
get themeList() {
return computed(() => [...this.map.keys()]);
}
}

export function useThemeController<T extends ITheme = ITheme>(
key: InjectionKey<Theme<T>> | string | null = null
): Theme<T> | undefined {
return inject(key !== null ? key : themeProviderInjectionKey);
}

export function useTheme<T extends ITheme = ITheme>(
key: InjectionKey<Theme<T>> | string | null = null
): ComputedRef<T> | undefined {
return inject(key !== null ? key : themeProviderInjectionKey)?.data;
}

export function createTheme<T extends ITheme = ITheme>(map: ThemeMap<T>) {
return new Theme(map);
}
41 changes: 0 additions & 41 deletions packages/hexon-web/src/lib/theme/switcher.ts

This file was deleted.

3 changes: 0 additions & 3 deletions packages/hexon-web/src/lib/theme/types.ts

This file was deleted.

3 changes: 2 additions & 1 deletion packages/hexon-web/src/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,6 @@ import { createApp } from "vue";
import App from "./App.vue";
import router from "./router";
import store from "./store";
import themes from "./themes";

createApp(App).use(router).use(store).mount("#app");
createApp(App).use(router).use(store).use(themes).mount("#app");
Loading

0 comments on commit 3b0b8be

Please sign in to comment.