diff --git a/src/generate.ts b/src/generate.ts index 304bb6e..aecc1b3 100644 --- a/src/generate.ts +++ b/src/generate.ts @@ -1,11 +1,9 @@ +import { mergeDeep } from "unocss" + import { themeCSSVarKeys, themes } from "./themes" -import type { - ThemeCSSVarKey, - ThemeCSSVars, - ThemeCSSVarsVariant, -} from "./themes" -import type { ShadcnThemeColor } from "./types" +import type { ThemeCSSVarKey, ThemeCSSVars } from "./themes" +import type { ColorOptions } from "./types" function generateLightVars( theme: "light" | "dark", @@ -23,23 +21,28 @@ function generateLightVars( ].join("\n") } -export function generateCSSVars( - color: ShadcnThemeColor | ThemeCSSVarsVariant, - radius: number, -) { +function getBuiltInTheme(name: string) { + const theme = themes.find((t) => t.name === name) + if (!theme) throw new Error(`Unknown color: ${name}`) + return theme.cssVars +} + +function getColorTheme(color: ColorOptions) { let light: ThemeCSSVars let dark: ThemeCSSVars if (typeof color === "string") { - const theme = themes.find((t) => t.name === color) - if (!theme) throw new Error(`Unknown color: ${color}`) - const { cssVars } = theme - light = cssVars.light - dark = cssVars.dark + ;({ light, dark } = getBuiltInTheme(color)) + } else if ("base" in color) { + ;({ light, dark } = mergeDeep(getBuiltInTheme(color.base), color.color)) } else { - light = color.light - dark = color.dark + ;({ light, dark } = color) } + return { light, dark } +} + +export function generateCSSVars(color: ColorOptions, radius: number) { + let { light, dark } = getColorTheme(color) const lightVars = generateLightVars("light", light, radius) const darkVars = generateLightVars("dark", dark, radius) diff --git a/src/types.ts b/src/types.ts index fbaf3f8..e13f01f 100644 --- a/src/types.ts +++ b/src/types.ts @@ -1,12 +1,21 @@ import type { Theme as ShadcnTheme, ThemeCSSVarsVariant } from "./themes" +import type { DeepPartial } from "unocss" export type ShadcnThemeColor = ShadcnTheme["name"] -export interface PresetShadcnOptions { +export type ColorOptions = + | ShadcnThemeColor + | ThemeCSSVarsVariant + | { + base: ShadcnThemeColor + color: DeepPartial + } + +export type PresetShadcnOptions = { /** * @default 'zinc' */ - color?: ShadcnThemeColor | ThemeCSSVarsVariant + color?: ColorOptions /** * @default 0.5 */ diff --git a/test/generate.test.ts b/test/generate.test.ts index de3bb22..8604c5a 100644 --- a/test/generate.test.ts +++ b/test/generate.test.ts @@ -61,4 +61,20 @@ describe("generate-theme-css-var", () => { ), ).toMatchFileSnapshot("custom.css") }) + + it("custom theme based on built in theme", () => { + expect( + generateCSSVars( + { + base: "zinc", + color: { + light: { + background: "0 1% 100%", + }, + }, + }, + 1, + ), + ).toMatchFileSnapshot("custom.css") + }) })