Skip to content

Commit

Permalink
feat: add support for CSS variables in UnoCSS references
Browse files Browse the repository at this point in the history
  • Loading branch information
kirklin committed Jul 19, 2023
1 parent c8d91cb commit cdebe37
Show file tree
Hide file tree
Showing 8 changed files with 132 additions and 0 deletions.
6 changes: 6 additions & 0 deletions apps/admin/src/App.vue
Original file line number Diff line number Diff line change
@@ -1,7 +1,13 @@
<script setup lang="ts">
import { logger } from "@celeris/utils";
import { useNaiveUIConfigProvider } from "~/composables";
import { subscribeStore } from "~/store/subscribe";
/**
* Subscribe to the store.
* 订阅 store。
*/
subscribeStore();
logger.info("I'm ready! ⸜(๑'ᵕ'๑)⸝⋆*");
const { configProviderProps } = useNaiveUIConfigProvider();
</script>
Expand Down
1 change: 1 addition & 0 deletions apps/admin/src/composables/useNaiveUIConfigProvider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ export function useNaiveUIConfigProvider() {
"theme": getNaiveUIPresetTheme,
"theme-overrides": getNaiveUICustomTheme,
"namespace": designNamespace,
"inline-theme-disabled": true,
});

return {
Expand Down
1 change: 1 addition & 0 deletions apps/admin/src/setting/themeSetting.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,5 +26,6 @@ export const DEFAULT_THEME_SETTING: ThemeSetting = {
info: presetPrimaryColors.blue,
success: presetPrimaryColors.green,
warning: presetPrimaryColors.orange,
error: presetPrimaryColors.red,
},
};
9 changes: 9 additions & 0 deletions apps/admin/src/store/subscribe/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import subscribeThemeStore from "./theme";

/**
* Subscribe to the store.
* 订阅 store。
*/
export function subscribeStore() {
subscribeThemeStore();
}
59 changes: 59 additions & 0 deletions apps/admin/src/store/subscribe/theme.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
import { colorToRgb, generateColorPalettes, setCssVariable } from "@celeris/utils";
import { effectScope, onScopeDispose, watch } from "vue";
import type { GlobalThemeOverrides } from "naive-ui";
import { kebabCase } from "lodash-es";
import { useDesignStore } from "~/store/modules/design";

/**
* 订阅NaiveUI自定义主题的变化
* Subscribe to changes in the NaiveUI custom theme
*/
export default function subscribeThemeStore() {
const designStore = useDesignStore();
const scope = effectScope();

scope.run(() => {
watch(
() => designStore.getNaiveUICustomTheme,
(newTheme) => {
if (newTheme?.common) {
addThemeCssVariablesToHtml(newTheme?.common);
}
},
{ immediate: true },
);
});
/**
* 组件销毁时清理effect scope
* Clean up the effect scope when the component is destroyed
*/
onScopeDispose(() => {
scope.stop();
});
}

type ThemeVars = Exclude<GlobalThemeOverrides["common"], undefined>;
type ThemeVarsKeys = keyof ThemeVars;

/**
* 将主题颜色变量添加到HTML中
* Add theme color variables to HTML
* @param {ThemeVars} themeVars - 主题变量对象
*/
function addThemeCssVariablesToHtml(themeVars: ThemeVars) {
for (const [key, color] of Object.entries(themeVars) as [ThemeVarsKeys, string][]) {
if (color) {
const { r, g, b } = colorToRgb(color);
setCssVariable(`--${kebabCase(key)}`, `${r},${g},${b}`);
if (key === "primaryColor") {
const colorPalettes = generateColorPalettes(color);

for (let index = 0; index < colorPalettes.length; index++) {
const palette = colorPalettes[index];
const { r: pR, g: pG, b: pB } = colorToRgb(palette);
setCssVariable(`--${kebabCase(key)}${index + 1}`, `${pR},${pG},${pB}`);
}
}
}
}
}
34 changes: 34 additions & 0 deletions packages/node/vite/src/plugins/unocss.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,40 @@ export function createUnoCSSPluginConfig(): PluginOption {
"flex-x-center": "flex justify-center",
"flex-y-center": "flex items-center",
},
theme: {
colors: {
primary: "rgb(var(--primary-color))",
primary_hover: "rgb(var(--primary-color-hover))",
primary_suppl: "rgb(var(--primary-color-suppl))",
primary_pressed: "rgb(var(--primary-color-pressed))",
primary_1: "rgb(var(--primary-color1))",
primary_2: "rgb(var(--primary-color2))",
primary_3: "rgb(var(--primary-color3))",
primary_4: "rgb(var(--primary-color4))",
primary_5: "rgb(var(--primary-color5))",
primary_6: "rgb(var(--primary-color6))",
primary_7: "rgb(var(--primary-color7))",
primary_8: "rgb(var(--primary-color8))",
primary_9: "rgb(var(--primary-color9))",
primary_10: "rgb(var(--primary-color10))",
info: "rgb(var(--info-color))",
info_hover: "rgb(var(--info-color-hover))",
info_suppl: "rgb(var(--info-color-suppl))",
info_pressed: "rgb(var(--info-color-pressed))",
success: "rgb(var(--success-color))",
success_hover: "rgb(var(--success-color-hover))",
success_suppl: "rgb(var(--success-color-suppl))",
success_pressed: "rgb(var(--success-color-pressed))",
warning: "rgb(var(--warning-color))",
warning_hover: "rgb(var(--warning-color-hover))",
warning_suppl: "rgb(var(--warning-color-suppl))",
warning_pressed: "rgb(var(--warning-color-pressed))",
error: "rgb(var(--error-color))",
error_hover: "rgb(var(--error-color-hover))",
error_suppl: "rgb(var(--error-color-suppl))",
error_pressed: "rgb(var(--error-color-pressed))",
},
},
transformers: [
transformerDirectives(),
transformerVariantGroup(),
Expand Down
9 changes: 9 additions & 0 deletions packages/web/utils/src/color/utils.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,14 @@
import { colord } from "colord";
import type { RgbaColor } from "colord/types";

export function isWhiteColor(color: string) {
return colord(color).isEqual("#ffffff");
}

export function isBlackColor(color: string) {
return colord(color).isEqual("#000000");
}

export function colorToRgb(color: string): RgbaColor {
return colord(color).toRgb();
}
13 changes: 13 additions & 0 deletions packages/web/utils/src/domUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,19 @@ export function setCssVariable(property: string, value: string | null, element:
element.style.setProperty(property, value); // Set the specified property with the specified value.
}

/**
* Set CSS variables on the specified element.
* 在指定的元素上设置 CSS 变量。
*
* @param variables - An object containing the CSS variables to set and their values. 包含要设置的 CSS 变量及其值的对象。
* @param element - The HTML element on which to set the CSS variables. 要设置 CSS 变量的 HTML 元素。
*/
export function setCssVariables(variables: Record<string, string | null>, element: HTMLElement = document.documentElement) {
for (const [property, value] of Object.entries(variables)) {
element.style.setProperty(property, value);
}
}

/**
* Parses a CSS string and returns an object with key-value pairs of CSS properties and their values.
* 解析 CSS 字符串并返回一个包含 CSS 属性及其值的键值对对象。
Expand Down

2 comments on commit cdebe37

@vercel
Copy link

@vercel vercel bot commented on cdebe37 Jul 19, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Successfully deployed to the following URLs:

celeris-web-api – ./services/admin

celeris-web-api-git-master-kirklin.vercel.app
celeris-web-api.vercel.app
celeris-web-api-kirklin.vercel.app

@vercel
Copy link

@vercel vercel bot commented on cdebe37 Jul 19, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Successfully deployed to the following URLs:

celeris-web – ./apps/admin

celeris-web-kirklin.vercel.app
celeris-web-git-master-kirklin.vercel.app
celeris-web.vercel.app

Please sign in to comment.