diff --git a/packages/preset-mini/src/rules/border.ts b/packages/preset-mini/src/rules/border.ts index 1cdf74399f..afad7bbaa8 100644 --- a/packages/preset-mini/src/rules/border.ts +++ b/packages/preset-mini/src/rules/border.ts @@ -1,6 +1,6 @@ import type { CSSEntries, CSSObject, Rule, RuleContext } from '@unocss/core' import type { Theme } from '../theme' -import { colorToString, cornerMap, directionMap, globalKeywords, handler as h, hasParseableColor, parseColor } from '../utils' +import { colorOpacityToString, colorToString, cornerMap, directionMap, globalKeywords, handler as h, hasParseableColor, parseColor } from '../utils' const borderStyles = ['solid', 'dashed', 'dotted', 'double', 'hidden', 'none', 'groove', 'ridge', 'inset', 'outset', ...globalKeywords] @@ -64,14 +64,14 @@ const borderColorResolver = (direction: string) => ([, body]: string[], theme: T } if (direction === '') { return { - '--un-border-opacity': cssColor.alpha ?? 1, - [`border${direction}-color`]: colorToString(cssColor, `var(--un-border${direction}-opacity)`), + '--un-border-opacity': colorOpacityToString(cssColor), + 'border-color': colorToString(cssColor, 'var(--un-border-opacity)'), } } else { return { // Separate this return since if `direction` is an empty string, the first key will be overwritten by the second. - '--un-border-opacity': cssColor.alpha ?? 1, + '--un-border-opacity': colorOpacityToString(cssColor), [`--un-border${direction}-opacity`]: 'var(--un-border-opacity)', [`border${direction}-color`]: colorToString(cssColor, `var(--un-border${direction}-opacity)`), } @@ -79,7 +79,7 @@ const borderColorResolver = (direction: string) => ([, body]: string[], theme: T } else if (color) { return { - [`border${direction}-color`]: color.replace('%alpha', `${alpha ?? 1}`), + [`border${direction}-color`]: colorToString(color, alpha), } } } diff --git a/packages/preset-mini/src/utils/colors.ts b/packages/preset-mini/src/utils/colors.ts index 3335bbdf48..b63d624b37 100644 --- a/packages/preset-mini/src/utils/colors.ts +++ b/packages/preset-mini/src/utils/colors.ts @@ -34,7 +34,15 @@ export function parseCssColor(str = ''): CSSColorValue | undefined { return { type, components, alpha } } -export function colorToString(color: CSSColorValue, alphaOverride?: string | number) { +export function colorOpacityToString(color: CSSColorValue) { + const alpha = color.alpha ?? 1 + return alpha === '%alpha' ? 1 : alpha +} + +export function colorToString(color: CSSColorValue | string, alphaOverride?: string | number) { + if (typeof color === 'string') + return color.replace('%alpha', `${alphaOverride ?? 1}`) + const { components } = color let { alpha, type } = color alpha = alphaOverride ?? alpha diff --git a/packages/preset-mini/src/utils/utilities.ts b/packages/preset-mini/src/utils/utilities.ts index e54235d50d..1ce4ce6907 100644 --- a/packages/preset-mini/src/utils/utilities.ts +++ b/packages/preset-mini/src/utils/utilities.ts @@ -1,7 +1,7 @@ import type { CSSEntries, CSSObject, ParsedColorValue, RuleContext, VariantContext } from '@unocss/core' import { toArray } from '@unocss/core' import type { Theme } from '../theme' -import { colorToString, getComponents, parseCssColor } from './colors' +import { colorOpacityToString, colorToString, getComponents, parseCssColor } from './colors' import { handler as h } from './handlers' import { directionMap } from './mappings' @@ -147,14 +147,14 @@ export const colorResolver = (property: string, varName: string) => ([, body]: s } else { return { - [`--un-${varName}-opacity`]: cssColor.alpha ?? 1, + [`--un-${varName}-opacity`]: colorOpacityToString(cssColor), [property]: colorToString(cssColor, `var(--un-${varName}-opacity)`), } } } else if (color) { return { - [property]: color.replace('%alpha', `${alpha ?? 1}`), + [property]: colorToString(color, alpha), } } } diff --git a/packages/preset-wind/src/rules/background.ts b/packages/preset-wind/src/rules/background.ts index 139ac56310..4aaaca6e98 100644 --- a/packages/preset-wind/src/rules/background.ts +++ b/packages/preset-wind/src/rules/background.ts @@ -1,5 +1,5 @@ import type { Rule, RuleContext } from '@unocss/core' -import { colorToString, handler as h, parseColor, positionMap } from '@unocss/preset-mini/utils' +import { colorOpacityToString, colorToString, handler as h, parseColor, positionMap } from '@unocss/preset-mini/utils' import type { Theme } from '@unocss/preset-mini' const bgGradientColorResolver = (mode: 'from' | 'to' | 'via') => @@ -19,7 +19,7 @@ const bgGradientColorResolver = (mode: 'from' | 'to' | 'via') => if (alpha != null) colorString = colorToString(cssColor, alpha) else - colorString = colorToString(cssColor, `var(--un-${mode}-opacity, ${cssColor.alpha ?? 1})`) + colorString = colorToString(cssColor, `var(--un-${mode}-opacity, ${colorOpacityToString(cssColor)})`) } switch (mode) { diff --git a/test/__snapshots__/preset-uno.test.ts.snap b/test/__snapshots__/preset-uno.test.ts.snap index 63966485b7..a701457204 100644 --- a/test/__snapshots__/preset-uno.test.ts.snap +++ b/test/__snapshots__/preset-uno.test.ts.snap @@ -6,6 +6,15 @@ exports[`targets 1`] = ` .border-custom-b\\\\/0{border-color:rgba(var(--custom), 0);} .border-custom-b\\\\/10{border-color:rgba(var(--custom), 0.1);} .bg-custom-b{background-color:rgba(var(--custom), 1);} +.bg-custom-c{--un-bg-opacity:1;background-color:rgba(var(--custom-c),var(--un-bg-opacity));} +.bg-custom-c\\\\/10{background-color:rgba(var(--custom-c),0.1);} +.bg-custom-d{background-color:hsl(var(--custom-d), 1);} +.bg-custom-d\\\\/20{background-color:hsl(var(--custom-d), 0.2);} +.bg-custom-e{--un-bg-opacity:1;background-color:hsla(var(--custom-e),var(--un-bg-opacity));} +.bg-custom-e\\\\/30{background-color:hsla(var(--custom-e),0.3);} +.bg-custom-f{--un-bg-opacity:1;background-color:lch(var(--custom-f) / var(--un-bg-opacity));} +.bg-custom-f\\\\/\\\\[var\\\\(--f-op\\\\)\\\\]{background-color:lch(var(--custom-f) / var(--f-op));} +.bg-custom-f\\\\/30{background-color:lch(var(--custom-f) / 0.3);} .bg-info{--un-bg-opacity:1;background-color:hsla(200.1,100%,54.3%,var(--un-bg-opacity));} .bg-info\\\\/\\\\[10\\\\%\\\\]{background-color:hsla(200.1,100%,54.3%,10%);} .bg-info\\\\/10{background-color:hsla(200.1,100%,54.3%,0.1);} diff --git a/test/preset-uno.test.ts b/test/preset-uno.test.ts index 65f16743b8..3acdf5a637 100644 --- a/test/preset-uno.test.ts +++ b/test/preset-uno.test.ts @@ -18,6 +18,15 @@ const targets = [ 'border-custom-b', 'border-custom-b/0', 'border-custom-b/10', + 'bg-custom-c', + 'bg-custom-c/10', + 'bg-custom-d', + 'bg-custom-d/20', + 'bg-custom-e', + 'bg-custom-e/30', + 'bg-custom-f', + 'bg-custom-f/30', + 'bg-custom-f/[var(--f-op)]', // wind - placeholder 'placeholder-red-400', @@ -119,6 +128,10 @@ const uno = createGenerator({ custom: { a: 'var(--custom)', b: 'rgba(var(--custom), %alpha)', + c: 'rgba(var(--custom-c) / %alpha)', + d: 'hsl(var(--custom-d), %alpha)', + e: 'hsl(var(--custom-e) / %alpha)', + f: 'lch(var(--custom-f) / %alpha)', }, info: 'hsl(200.1, 100%, 54.3%)', },