diff --git a/index.html b/index.html index eb6d965..537e58c 100644 --- a/index.html +++ b/index.html @@ -6,110 +6,6 @@ Vite + React + TS - diff --git a/package.json b/package.json index b392e7e..29d6f07 100644 --- a/package.json +++ b/package.json @@ -12,8 +12,10 @@ "dependencies": { "@uiw/codemirror-extensions-color": "^4.23.0", "@uiw/codemirror-extensions-langs": "^4.23.0", + "@uiw/codemirror-theme-vscode": "^4.23.0", "@uiw/react-codemirror": "^4.23.0", "@uiw/react-json-view": "1.12.0", + "color-selector-react": "0.3.0-beta.4", "localforage": "^1.10.0", "match-sorter": "^6.3.4", "react": "^18.2.0", diff --git a/src/components/Theme/ThemePrivider.tsx b/src/components/Theme/ThemePrivider.tsx index a034188..e1c914b 100644 --- a/src/components/Theme/ThemePrivider.tsx +++ b/src/components/Theme/ThemePrivider.tsx @@ -1,35 +1,7 @@ import { createContext, useContext, useEffect, useRef, useState } from "react"; -import { createTheme, reverseColor } from "../../utils/theme"; -import { getColorAsync } from "../../data/colors"; +import { ThemeSection } from "../../../typings"; -type ThemeSection = "dark" | "light" | "system"; - -let themeLightId: string | null = null; -let themeDarkId: string | null = null; - -getColorAsync().then((color) => { - themeLightId = createTheme( - "theme-color-light", - color - ) - const rev = reverseColor(color) - themeDarkId = createTheme( - "theme-color-dark", - rev - ) -}) - -// 在退出的时候删除这两个主题 -window.addEventListener("beforeunload", () => { - if (themeLightId) { - document.getElementById(themeLightId)?.remove(); - } - if (themeDarkId) { - document.getElementById(themeDarkId)?.remove(); - } -}); - -const themeMap: Record = { +const themeMap = { dark: "theme-color-dark", light: "theme-color-light", system: "", diff --git a/src/data/colors.ts b/src/data/colors.ts index 5fb48f0..9779845 100644 --- a/src/data/colors.ts +++ b/src/data/colors.ts @@ -1,94 +1,92 @@ -const themeColorLight = { - "primary-7": "rgb(14, 66, 210)", - "primary-6": "rgb(22, 93, 255)", - "primary-5": "rgb(64, 128, 255)", - "primary-4": "rgb(106, 161, 255)", - "primary-3": "rgb(148, 191, 255)", - "primary-2": "rgb(190, 218, 255)", - "primary-1": "rgb(232, 243, 255)", - "success-7": "rgb(0, 154, 41)", - "success-6": "rgb(0, 180, 42)", - "success-5": "rgb(35, 195, 67)", - "success-4": "rgb(76, 210, 99)", - "success-3": "rgb(123, 225, 136)", - "success-2": "rgb(175, 240, 181)", - "success-1": "rgb(232, 255, 234)", - "warning-7": "rgb(210, 95, 0)", - "warning-6": "rgb(255, 125, 0)", - "warning-5": "rgb(255, 154, 46)", - "warning-4": "rgb(255, 182, 93)", - "warning-3": "rgb(255, 207, 139)", - "warning-2": "rgb(255, 228, 186)", - "warning-1": "rgb(255, 247, 232)", - "danger-7": "rgb(203, 39, 45)", - "danger-6": "rgb(245, 63, 63)", - "danger-5": "rgb(247, 101, 96)", - "danger-4": "rgb(249, 137, 129)", - "danger-3": "rgb(251, 172, 163)", - "danger-2": "rgb(253, 205, 197)", - "danger-1": "rgb(255, 236, 232)", - "link-7": "rgb(14, 66, 210)", - "link-6": "rgb(22, 93, 255)", - "link-5": "rgb(64, 128, 255)", - "link-4": "rgb(106, 161, 255)", - "link-3": "rgb(148, 191, 255)", - "link-2": "rgb(190, 218, 255)", - "link-1": "rgb(232, 243, 255)", - "data-1": "rgb(64, 128, 255)", - "data-2": "rgb(190, 218, 255)", - "data-3": "rgb(85, 197, 253)", - "data-4": "rgb(156, 220, 252)", - "data-5": "rgb(255, 125, 0)", - "data-6": "rgb(255, 207, 139)", - "data-7": "rgb(76, 210, 99)", - "data-8": "rgb(175, 240, 181)", - "data-9": "rgb(168, 113, 227)", - "data-10": "rgb(221, 190, 246)", - "data-11": "rgb(247, 186, 30)", - "data-12": "rgb(250, 220, 109)", - "data-13": "rgb(159, 219, 29)", - "data-14": "rgb(201, 233, 104)", - "data-15": "rgb(249, 121, 183)", - "data-16": "rgb(251, 157, 199)", - "data-17": "rgb(20, 201, 201)", - "data-18": "rgb(137, 233, 224)", - "data-19": "rgb(232, 101, 223)", - "data-20": "rgb(247, 186, 239)", - "color-border-1": "rgb(242, 243, 245)", - "color-border-2": "rgb(229, 230, 235)", - "color-border-3": "rgb(201, 205, 212)", - "color-border-4": "rgb(134, 144, 156)", - "color-border-5": "rgb(78, 89, 105)", - "color-border-6": "rgb(29, 33, 41)", - "color-border-7": "rgb(14, 16, 20)", - "color-fill-1": "rgb(247, 248, 250)", - "color-fill-2": "rgb(242, 243, 245)", - "color-fill-3": "rgb(229, 230, 235)", - "color-fill-4": "rgb(201, 205, 212)", - "color-fill-5": "rgb(134, 144, 156)", - "color-fill-6": "rgb(78, 89, 105)", - "color-fill-7": "rgb(29, 33, 41)", - "color-text-1": "rgb(29, 33, 41)", - "color-text-2": "rgb(78, 89, 105)", - "color-text-3": "rgb(134, 144, 156)", - "color-text-4": "rgb(201, 205, 212)", - "color-text-5": "rgb(229, 230, 235)", - "color-text-6": "rgb(242, 243, 245)", - "color-text-7": "rgb(247, 248, 250)", - "color-bg-1": "rgb(255, 255, 255)", - "color-bg-2": "rgb(255, 255, 255)", - "color-bg-3": "rgb(255, 255, 255)", - "color-bg-4": "rgb(255, 255, 255)", - "color-bg-5": "rgb(255, 255, 255)", - "color-bg-6": "rgb(255, 255, 255)", - "color-bg-7": "rgb(255, 255, 255)", - "color-bg-white": "rgb(255, 255, 255)", - "color-bg-black": "rgb(0, 0, 0)", - "color-shadow": "rgba(255, 255, 255, 0.5)", -}; +import { ColorSchema } from "../../typings"; -export const getColorAsync = async () => { - return await Promise.resolve({ - ...themeColorLight, - }); +export const themeColorSchema: ColorSchema = { + onLight: { + "primary-7": "rgb(14, 66, 210)", + "primary-6": "rgb(22, 93, 255)", + "primary-5": "rgb(64, 128, 255)", + "primary-4": "rgb(106, 161, 255)", + "primary-3": "rgb(148, 191, 255)", + "primary-2": "rgb(190, 218, 255)", + "primary-1": "rgb(232, 243, 255)", + "success-7": "rgb(0, 154, 41)", + "success-6": "rgb(0, 180, 42)", + "success-5": "rgb(35, 195, 67)", + "success-4": "rgb(76, 210, 99)", + "success-3": "rgb(123, 225, 136)", + "success-2": "rgb(175, 240, 181)", + "success-1": "rgb(232, 255, 234)", + "warning-7": "rgb(210, 95, 0)", + "warning-6": "rgb(255, 125, 0)", + "warning-5": "rgb(255, 154, 46)", + "warning-4": "rgb(255, 182, 93)", + "warning-3": "rgb(255, 207, 139)", + "warning-2": "rgb(255, 228, 186)", + "warning-1": "rgb(255, 247, 232)", + "danger-7": "rgb(203, 39, 45)", + "danger-6": "rgb(245, 63, 63)", + "danger-5": "rgb(247, 101, 96)", + "danger-4": "rgb(249, 137, 129)", + "danger-3": "rgb(251, 172, 163)", + "danger-2": "rgb(253, 205, 197)", + "danger-1": "rgb(255, 236, 232)", + "link-7": "rgb(14, 66, 210)", + "link-6": "rgb(22, 93, 255)", + "link-5": "rgb(64, 128, 255)", + "link-4": "rgb(106, 161, 255)", + "link-3": "rgb(148, 191, 255)", + "link-2": "rgb(190, 218, 255)", + "link-1": "rgb(232, 243, 255)", + "data-1": "rgb(64, 128, 255)", + "data-2": "rgb(190, 218, 255)", + "data-3": "rgb(85, 197, 253)", + "data-4": "rgb(156, 220, 252)", + "data-5": "rgb(255, 125, 0)", + "data-6": "rgb(255, 207, 139)", + "data-7": "rgb(76, 210, 99)", + "data-8": "rgb(175, 240, 181)", + "data-9": "rgb(168, 113, 227)", + "data-10": "rgb(221, 190, 246)", + "data-11": "rgb(247, 186, 30)", + "data-12": "rgb(250, 220, 109)", + "data-13": "rgb(159, 219, 29)", + "data-14": "rgb(201, 233, 104)", + "data-15": "rgb(249, 121, 183)", + "data-16": "rgb(251, 157, 199)", + "data-17": "rgb(20, 201, 201)", + "data-18": "rgb(137, 233, 224)", + "data-19": "rgb(232, 101, 223)", + "data-20": "rgb(247, 186, 239)", + "color-border-1": "rgb(242, 243, 245)", + "color-border-2": "rgb(229, 230, 235)", + "color-border-3": "rgb(201, 205, 212)", + "color-border-4": "rgb(134, 144, 156)", + "color-border-5": "rgb(78, 89, 105)", + "color-border-6": "rgb(29, 33, 41)", + "color-border-7": "rgb(14, 16, 20)", + "color-fill-1": "rgb(247, 248, 250)", + "color-fill-2": "rgb(242, 243, 245)", + "color-fill-3": "rgb(229, 230, 235)", + "color-fill-4": "rgb(201, 205, 212)", + "color-fill-5": "rgb(134, 144, 156)", + "color-fill-6": "rgb(78, 89, 105)", + "color-fill-7": "rgb(29, 33, 41)", + "color-text-1": "rgb(29, 33, 41)", + "color-text-2": "rgb(78, 89, 105)", + "color-text-3": "rgb(134, 144, 156)", + "color-text-4": "rgb(201, 205, 212)", + "color-text-5": "rgb(229, 230, 235)", + "color-text-6": "rgb(242, 243, 245)", + "color-text-7": "rgb(247, 248, 250)", + "color-bg-1": "rgb(255, 255, 255)", + "color-bg-2": "rgb(255, 255, 255)", + "color-bg-3": "rgb(255, 255, 255)", + "color-bg-4": "rgb(255, 255, 255)", + "color-bg-5": "rgb(255, 255, 255)", + "color-bg-6": "rgb(255, 255, 255)", + "color-bg-7": "rgb(255, 255, 255)", + "color-bg-white": "rgb(255, 255, 255)", + "color-bg-black": "rgb(0, 0, 0)", + "color-shadow": "rgba(255, 255, 255, 0.5)", + }, }; diff --git a/src/pages/creation/components/colorPalette.tsx b/src/pages/creation/components/colorPalette.tsx new file mode 100644 index 0000000..15f6057 --- /dev/null +++ b/src/pages/creation/components/colorPalette.tsx @@ -0,0 +1,150 @@ +import React, { useEffect, useState, useRef } from "react"; +import { ColorSelector, IColorSelectorProps } from "color-selector-react"; +import "color-selector-react/dist/es/index.css"; +import { ColorSchema, ThemeVariables } from "../../../../typings"; +import { + createDarkTheme, + createLightTheme, + getColorAsync, +} from "../../../utils/theme"; + +interface ColorPaletteProps {} + +interface VisibleColorPicker { + key: string; + palette: "light" | "dark"; + position: { top: number; left: number }; +} + +const ColorPalette: React.FC = () => { + const [colors, setColors] = useState({ + onLight: {}, + onDark: {}, + }); + + useEffect(() => { + getColorAsync().then((res) => { + setColors(res); + }); + }, []); + + const [visibleColorPicker, setVisibleColorPicker] = + useState(null); + const [currentColor, setCurrentColor] = useState(""); + + const paletteRef = useRef(null); + + useEffect(() => { + const handleClickOutside = (event: MouseEvent) => { + if ( + paletteRef.current && + !paletteRef.current.contains(event.target as Node) + ) { + setVisibleColorPicker(null); + } + }; + document.addEventListener("mousedown", handleClickOutside); + return () => { + document.removeEventListener("mousedown", handleClickOutside); + }; + }, [paletteRef]); + + const handleColorClick = ( + key: string, + palette: "light" | "dark", + event: React.MouseEvent + ) => { + const { clientX, clientY } = event; + const rect = paletteRef.current?.getBoundingClientRect(); + const adjustedX = clientX - (rect?.left ?? 0); + const adjustedY = clientY - (rect?.top ?? 0); + + setCurrentColor( + palette === "light" ? colors.onLight[key] : colors.onDark![key] + ); + setVisibleColorPicker({ + key, + palette, + position: { top: adjustedY, left: adjustedX }, + }); + }; + + const setLightColors = (newColor: ThemeVariables) => { + setColors({ ...colors, onLight: newColor }); + createLightTheme(newColor); + }; + + const setDarkColors = (newColor: ThemeVariables) => { + setColors({ ...colors, onDark: newColor }); + createDarkTheme(newColor); + }; + + const handleColorChange: IColorSelectorProps["onChange"] = ({ color }) => { + if (visibleColorPicker) { + if (visibleColorPicker.palette === "light") { + setLightColors({ ...colors.onLight, [visibleColorPicker.key]: color }); + } else { + setDarkColors({ ...colors.onDark, [visibleColorPicker.key]: color }); + } + setCurrentColor(color); + } + }; + + return ( +
+
调色盘
+
+
+
Light Colors
+
+ {Object.keys(colors.onLight).map((key) => ( +
+ {`${key}:`} +
handleColorClick(key, "light", event)} + className="w-5 h-5 cursor-pointer border" + style={{ + backgroundColor: `${colors.onLight[key]}`, + }} + >
+
+ ))} +
+
+
+
Dark Colors
+
+ {Object.keys(colors.onDark!).map((key) => ( +
+ {`${key}:`} +
handleColorClick(key, "dark", event)} + className="w-5 h-5 cursor-pointer border" + style={{ + backgroundColor: `${colors.onDark![key]}`, + }} + >
+
+ ))} +
+
+
+ {visibleColorPicker && ( + !v && setVisibleColorPicker(null)} + /> + )} +
+ ); +}; + +export default ColorPalette; diff --git a/src/pages/creation/index.tsx b/src/pages/creation/index.tsx index 0afc383..e2e3a37 100644 --- a/src/pages/creation/index.tsx +++ b/src/pages/creation/index.tsx @@ -1,4 +1,4 @@ -import React from "react"; +import React, { useEffect } from "react"; import CodeMirror, { basicSetup } from "@uiw/react-codemirror"; import { loadLanguage, langs } from "@uiw/codemirror-extensions-langs"; import LiveProvider from "../../components/Live/LiveProvider"; @@ -9,6 +9,9 @@ import JsonViewEditor from "@uiw/react-json-view/editor"; import { ThemeProvider } from "../../components/Theme/ThemePrivider"; import { plugin as colorCom } from "./completions"; import { functionBlockList } from "../../data/functionBlocks"; +import { vscodeDark } from "@uiw/codemirror-theme-vscode"; +import { ColorSchema } from "../../../typings"; +import ColorPalette from "./components/colorPalette"; loadLanguage("tsx"); const extensions = [color, langs.tsx(), colorView(false), colorTheme, colorCom]; @@ -87,6 +90,7 @@ export const Creation = () => { { -
-

Props 编辑器

-
-
- -
- setNewPropKey(e.target.value)} - className="border border-text-1 rounded p-2 flex-grow" - /> - +
+
+

Props 编辑器

+
+
+ +
+ setNewPropKey(e.target.value)} + className="border border-text-1 rounded p-2 flex-grow" + /> + +
-
- { - const updateNestedProp = ( - obj: Record, - path: string[], - value: unknown - ) => { - if (path.length === 1) { - obj[path[0]] = value; - } else { - if (!obj[path[0]]) { - obj[path[0]] = {}; + { + const updateNestedProp = ( + obj: Record, + path: string[], + value: unknown + ) => { + if (path.length === 1) { + obj[path[0]] = value; + } else { + if (!obj[path[0]]) { + obj[path[0]] = {}; + } + updateNestedProp(obj[path[0]], path.slice(1), value); } - updateNestedProp(obj[path[0]], path.slice(1), value); - } - }; - const updatedProps = { ...componentsProps }; - updateNestedProp( - updatedProps, - (opts as any).namespace, - opts.value - ); - setComponentsProps(updatedProps); - return true; - }} - /> + }; + const updatedProps = { ...componentsProps }; + updateNestedProp( + updatedProps, + (opts as any).namespace, + opts.value + ); + setComponentsProps(updatedProps); + return true; + }} + /> +
+
diff --git a/src/utils/theme/index.ts b/src/utils/theme/index.ts index 8445f29..bd87862 100644 --- a/src/utils/theme/index.ts +++ b/src/utils/theme/index.ts @@ -1,9 +1,12 @@ import { + ColorSchema, RGBString, RGBValue, + ThemeSection, ThemeVariables, UpdateThemeColor, } from "../../../typings"; +import { themeColorSchema } from "../../data/colors"; export function updateThemeColor({ themeClass, @@ -217,108 +220,180 @@ export const setTailwindExtendProps = (colors: Record) => { if (!tailwind) { throw new Error("Tailwind CSS not found"); } - console.log(tailwind); - tailwind.config = { theme: { extend: { colors: { - primary: { - 1: "var(--primary-1)", - 2: "var(--primary-2)", - 3: "var(--primary-3)", - 4: "var(--primary-4)", - 5: "var(--primary-5)", - 6: "var(--primary-6)", - 7: "var(--primary-7)", - }, - success: { - 1: "var(--success-1)", - 2: "var(--success-2)", - 3: "var(--success-3)", - 4: "var(--success-4)", - 5: "var(--success-5)", - 6: "var(--success-6)", - 7: "var(--success-7)", - }, - warning: { - 1: "var(--warning-1)", - 2: "var(--warning-2)", - 3: "var(--warning-3)", - 4: "var(--warning-4)", - 5: "var(--warning-5)", - 6: "var(--warning-6)", - 7: "var(--warning-7)", - }, - danger: { - 1: "var(--danger-1)", - 2: "var(--danger-2)", - 3: "var(--danger-3)", - 4: "var(--danger-4)", - 5: "var(--danger-5)", - 6: "var(--danger-6)", - 7: "var(--danger-7)", - }, - link: { - 1: "var(--link-1)", - 2: "var(--link-2)", - 3: "var(--link-3)", - 4: "var(--link-4)", - 5: "var(--link-5)", - 6: "var(--link-6)", - 7: "var(--link-7)", - }, - background: { - 1: "var(--color-bg-1)", - 2: "var(--color-bg-2)", - 3: "var(--color-bg-3)", - 4: "var(--color-bg-4)", - 5: "var(--color-bg-5)", - white: "var(--color-bg-white)", - }, - text: { - 1: "var(--color-text-1)", - 2: "var(--color-text-2)", - 3: "var(--color-text-3)", - 4: "var(--color-text-4)", - }, - border: { - 1: "var(--color-border-1)", - 2: "var(--color-border-2)", - 3: "var(--color-border-3)", - 4: "var(--color-border-4)", - }, - fill: { - 1: "var(--color-fill-1)", - 2: "var(--color-fill-2)", - 3: "var(--color-fill-3)", - 4: "var(--color-fill-4)", - }, - data: { - 1: "var(--data-1)", - 2: "var(--data-2)", - 3: "var(--data-3)", - 4: "var(--data-4)", - 5: "var(--data-5)", - 6: "var(--data-6)", - 7: "var(--data-7)", - 8: "var(--data-8)", - 9: "var(--data-9)", - 10: "var(--data-10)", - 11: "var(--data-11)", - 12: "var(--data-12)", - 13: "var(--data-13)", - 14: "var(--data-14)", - 15: "var(--data-15)", - 16: "var(--data-16)", - 17: "var(--data-17)", - 18: "var(--data-18)", - 19: "var(--data-19)", - 20: "var(--data-20)", - }, - shadow: "--color-shadow", + // primary: { + // 1: "var(--primary-1)", + // 2: "var(--primary-2)", + // 3: "var(--primary-3)", + // 4: "var(--primary-4)", + // 5: "var(--primary-5)", + // 6: "var(--primary-6)", + // 7: "var(--primary-7)", + // }, + // success: { + // 1: "var(--success-1)", + // 2: "var(--success-2)", + // 3: "var(--success-3)", + // 4: "var(--success-4)", + // 5: "var(--success-5)", + // 6: "var(--success-6)", + // 7: "var(--success-7)", + // }, + // warning: { + // 1: "var(--warning-1)", + // 2: "var(--warning-2)", + // 3: "var(--warning-3)", + // 4: "var(--warning-4)", + // 5: "var(--warning-5)", + // 6: "var(--warning-6)", + // 7: "var(--warning-7)", + // }, + // danger: { + // 1: "var(--danger-1)", + // 2: "var(--danger-2)", + // 3: "var(--danger-3)", + // 4: "var(--danger-4)", + // 5: "var(--danger-5)", + // 6: "var(--danger-6)", + // 7: "var(--danger-7)", + // }, + // link: { + // 1: "var(--link-1)", + // 2: "var(--link-2)", + // 3: "var(--link-3)", + // 4: "var(--link-4)", + // 5: "var(--link-5)", + // 6: "var(--link-6)", + // 7: "var(--link-7)", + // }, + // background: { + // 1: "var(--color-bg-1)", + // 2: "var(--color-bg-2)", + // 3: "var(--color-bg-3)", + // 4: "var(--color-bg-4)", + // 5: "var(--color-bg-5)", + // white: "var(--color-bg-white)", + // }, + // text: { + // 1: "var(--color-text-1)", + // 2: "var(--color-text-2)", + // 3: "var(--color-text-3)", + // 4: "var(--color-text-4)", + // }, + // border: { + // 1: "var(--color-border-1)", + // 2: "var(--color-border-2)", + // 3: "var(--color-border-3)", + // 4: "var(--color-border-4)", + // }, + // fill: { + // 1: "var(--color-fill-1)", + // 2: "var(--color-fill-2)", + // 3: "var(--color-fill-3)", + // 4: "var(--color-fill-4)", + // }, + // data: { + // 1: "var(--data-1)", + // 2: "var(--data-2)", + // 3: "var(--data-3)", + // 4: "var(--data-4)", + // 5: "var(--data-5)", + // 6: "var(--data-6)", + // 7: "var(--data-7)", + // 8: "var(--data-8)", + // 9: "var(--data-9)", + // 10: "var(--data-10)", + // 11: "var(--data-11)", + // 12: "var(--data-12)", + // 13: "var(--data-13)", + // 14: "var(--data-14)", + // 15: "var(--data-15)", + // 16: "var(--data-16)", + // 17: "var(--data-17)", + // 18: "var(--data-18)", + // 19: "var(--data-19)", + // 20: "var(--data-20)", + // }, + // shadow: "--color-shadow", + // TODO: 这里使用传入的颜色 + ...colors, }, }, }, }; }; + +const themeMap = { + dark: "theme-color-dark", + light: "theme-color-light", + system: "", +} as const; + +export const createLightTheme = (themeVariables: ThemeVariables) => { + return createTheme(themeMap.light, themeVariables); +}; + +export const createDarkTheme = (themeVariables: ThemeVariables) => { + return createTheme(themeMap.dark, themeVariables); +}; + +export const getColorAsync = async () => { + if (!themeColorSchema.onDark) { + themeColorSchema.onDark = reverseColor(themeColorSchema.onLight); + } + + return await Promise.resolve({ + onLight: themeColorSchema.onLight, + onDark: themeColorSchema.onDark, + }); +}; + +let themeLightId: string | null = null; +let themeDarkId: string | null = null; + +getColorAsync().then((color) => { + themeLightId = createLightTheme(color.onLight); + themeDarkId = createDarkTheme(color.onDark!); +}); + +// 在退出的时候删除这两个主题,防止重复加载 +window.addEventListener("unload", () => { + setTimeout(() => { + if (themeLightId) { + document.getElementById(themeLightId)?.remove(); + } + if (themeDarkId) { + document.getElementById(themeDarkId)?.remove(); + } + }, 0); +}); + +export const changeThemeSchema = (schema: ColorSchema) => { + // 通过id删除原有的主题,然后重新生成 + if (themeLightId) { + document.getElementById(themeLightId)?.remove(); + } + if (themeDarkId) { + document.getElementById(themeDarkId)?.remove(); + } + themeLightId = createTheme(themeMap.light, schema.onLight); + themeDarkId = createTheme(themeMap.dark, schema.onDark!); +}; + +export const overrideColor = ( + theme: ThemeSection, + color: Record +) => { + const themeElement = document.querySelector(`.${themeMap[theme]}`); + if (themeElement) { + for (const key in color) { + if (color.hasOwnProperty(key)) { + const value = color[key]; + (themeElement as HTMLElement).style.setProperty(`--${key}`, value); + } + } + } +}; diff --git a/typings/index.ts b/typings/index.ts index 953c73f..fe71aa9 100644 --- a/typings/index.ts +++ b/typings/index.ts @@ -24,3 +24,10 @@ export type RGBValue = { export type ThemeVariables = { [key: string]: string; }; + +export type ColorSchema = { + onLight: Record, + onDark?: Record, +} + +export type ThemeSection = "dark" | "light" | "system"; \ No newline at end of file