diff --git a/src/generate.ts b/src/generate.ts index aedf9c7..dfc0262 100644 --- a/src/generate.ts +++ b/src/generate.ts @@ -19,6 +19,27 @@ function generateRadiusCSSVars(radius: number) { return ` --radius: ${radius}rem;` } +function radiusCSSVarsStyles(radius: number) { + return ` +:root { +${generateRadiusCSSVars(radius)} +} +` +} + +export function generateGlobalStyles() { + return ` +* { + border-color: hsl(var(--border)); +} + +body { + color: hsl(var(--foreground)); + background: hsl(var(--background)); +} +` +} + function getBuiltInTheme(name: string) { const theme = themes.find(t => t.name === name) if (!theme) @@ -36,16 +57,16 @@ function getColorTheme(color: ColorOptions) { if (typeof color === 'string') { name = color - ;({ light, dark } = getBuiltInTheme(color)) + ; ({ light, dark } = getBuiltInTheme(color)) } else if ('base' in color) { name = color.base - ;({ light, dark } = mergeDeep(getBuiltInTheme(color.base), color.color)) + ; ({ light, dark } = mergeDeep(getBuiltInTheme(color.base), color.color)) } else { // eslint-disable-next-line prefer-destructuring name = color.name - ;({ light, dark } = color) + ; ({ light, dark } = color) } return { light, dark, name } } @@ -58,26 +79,39 @@ export function generateCSSVars( return theme.map(t => generateCSSVars(t, false)).join('\n') const { color = 'zinc', radius = 0.5 } = theme - const { light, dark, name } = getColorTheme(color) - const lightVars = generateColorCSSVars(light) - const darkVars = generateColorCSSVars(dark) - if (!onlyOne) { - return `.theme-${name} { + let cssStyle = '' + + if (!color) { + if (radius) + cssStyle += radiusCSSVarsStyles(radius) + } + else { + const { light, dark, name } = getColorTheme(color) + const lightVars = generateColorCSSVars(light) + const darkVars = generateColorCSSVars(dark) + + cssStyle += colorCSSVarsStyles(lightVars, darkVars, { radius, themeName: !onlyOne && name }) + } + + return cssStyle +} + +function colorCSSVarsStyles(lightVars: string, darkVars: string, { radius, themeName }: { radius: number, themeName?: string | false }) { + return themeName + ? ` +.theme-${themeName} { ${lightVars} ${generateRadiusCSSVars(radius)} } - -.dark .theme-${name} { +.dark .theme-${themeName} { ${darkVars} }` - } - - return `:root { + : ` +:root { ${lightVars} ${generateRadiusCSSVars(radius)} } - .dark { ${darkVars} }` diff --git a/src/index.ts b/src/index.ts index 73b2172..daaa0b2 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,14 +1,17 @@ import type { Preset } from 'unocss' import type { Theme } from 'unocss/preset-mini' -import { generateCSSVars } from './generate' +import { generateCSSVars, generateGlobalStyles } from './generate' import { themes } from './themes' import type { PresetShadcnOptions } from './types' export const builtinColors = themes.map(theme => theme.name) export const builtinRadiuses = [0, 0.3, 0.5, 0.75, 1] as const -export function presetShadcn(options: PresetShadcnOptions = {}): Preset { +/** + * @param globals Generates global variables, like *.border-color, body.color, body.background - @default true + */ +export function presetShadcn(options: PresetShadcnOptions = {}, globals?: boolean): Preset { return { name: 'unocss-preset-shadcn', preflights: [ @@ -21,14 +24,7 @@ export function presetShadcn(options: PresetShadcnOptions = {}): Preset { ${generateCSSVars(options)} - * { - border-color: hsl(var(--border)); - } - - body { - color: hsl(var(--foreground)); - background: hsl(var(--background)); - } + ${globals ? generateGlobalStyles() : ''} `, }, ], diff --git a/src/types.ts b/src/types.ts index 2c899d2..39c0bde 100644 --- a/src/types.ts +++ b/src/types.ts @@ -18,7 +18,7 @@ export type ThemeOptions = { /** * @default 'zinc' */ - color?: ColorOptions + color?: ColorOptions | null /** * @default 0.5 */ diff --git a/test/custom.css b/test/custom.css index 4afe69f..f12dd56 100644 --- a/test/custom.css +++ b/test/custom.css @@ -20,7 +20,6 @@ --ring: 240 5.9% 10%; --radius: 1rem; } - .dark { --background: 240 10% 3.9%; --foreground: 0 0% 98%; diff --git a/test/multiple.css b/test/multiple.css index ae2fad4..9e50cf6 100644 --- a/test/multiple.css +++ b/test/multiple.css @@ -20,7 +20,6 @@ --ring: 240 5.9% 10%; --radius: 0.5rem; } - .dark .theme-zinc { --background: 240 10% 3.9%; --foreground: 0 0% 98%; @@ -42,6 +41,7 @@ --input: 240 3.7% 15.9%; --ring: 240 4.9% 83.9%; } + .theme-neutral { --background: 0 0% 100%; --foreground: 0 0% 3.9%; @@ -64,7 +64,6 @@ --ring: 0 0% 3.9%; --radius: 0.75rem; } - .dark .theme-neutral { --background: 0 0% 3.9%; --foreground: 0 0% 98%; diff --git a/test/neutral-0.75.css b/test/neutral-0.75.css index 72cf601..2a7818e 100644 --- a/test/neutral-0.75.css +++ b/test/neutral-0.75.css @@ -20,7 +20,6 @@ --ring: 0 0% 3.9%; --radius: 0.75rem; } - .dark { --background: 0 0% 3.9%; --foreground: 0 0% 98%; diff --git a/test/zinc-0.5.css b/test/zinc-0.5.css index 30ec881..4dbde1c 100644 --- a/test/zinc-0.5.css +++ b/test/zinc-0.5.css @@ -20,7 +20,6 @@ --ring: 240 5.9% 10%; --radius: 0.5rem; } - .dark { --background: 240 10% 3.9%; --foreground: 0 0% 98%;