diff --git a/src/generate.ts b/src/generate.ts index aedf9c7..73e9f9d 100644 --- a/src/generate.ts +++ b/src/generate.ts @@ -15,10 +15,42 @@ function generateColorCSSVars(color: ThemeCSSVars) { .join('\n') } +function colorCSSVarsStyles(lightVars: string, darkVars: string, { radius, themeName }: { radius?: number | false, themeName?: string | false }) { + return ` +${themeName ? `.theme-${themeName}` : ':root'} { +${lightVars} +${radius ? generateRadiusCSSVars(radius) : ''} +} +${themeName ? `.dark .theme-${themeName}` : '.dark'} { +${darkVars} +}` +} + 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) @@ -58,27 +90,20 @@ 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} { -${lightVars} -${generateRadiusCSSVars(radius)} -} + let cssStyle = '' -.dark .theme-${name} { -${darkVars} -}` + if (!color) { + if (radius) + cssStyle += radiusCSSVarsStyles(radius) } + else { + const { light, dark, name } = getColorTheme(color) + const lightVars = generateColorCSSVars(light) + const darkVars = generateColorCSSVars(dark) - return `:root { -${lightVars} -${generateRadiusCSSVars(radius)} -} + cssStyle += colorCSSVarsStyles(lightVars, darkVars, { radius, themeName: !onlyOne && name }) + } -.dark { -${darkVars} -}` + return cssStyle } diff --git a/src/index.ts b/src/index.ts index 73b2172..9053315 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,14 +1,18 @@ 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 +25,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() : ''} `, }, ], @@ -95,8 +92,8 @@ export function presetShadcn(options: PresetShadcnOptions = {}): Preset { }, }, borderRadius: { - lg: `var(--radius)`, - md: `calc(var(--radius) - 2px)`, + lg: 'var(--radius)', + md: 'calc(var(--radius) - 2px)', sm: 'calc(var(--radius) - 4px)', }, }, diff --git a/src/types.ts b/src/types.ts index 2c899d2..2063069 100644 --- a/src/types.ts +++ b/src/types.ts @@ -18,11 +18,11 @@ export type ThemeOptions = { /** * @default 'zinc' */ - color?: ColorOptions + color?: ColorOptions | false /** * @default 0.5 */ - radius?: number + radius?: number | false } export type PresetShadcnOptions = ArrayOrSingle 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%;