11import type { CSSEntries , CSSObject , CSSObjectInput , CSSValueInput , DynamicMatcher , RuleContext , StaticRule , VariantContext } from '@unocss/core'
22import type { Theme } from '../theme'
33import { symbols , toArray } from '@unocss/core'
4- import { colorToString , getStringComponent , getStringComponents , parseCssColor } from '@unocss/rule-utils'
4+ import { colorToString , getStringComponent , getStringComponents , isInterpolatedMethod , parseCssColor } from '@unocss/rule-utils'
55import { SpecialColorKey } from './constant'
66import { h } from './handlers'
77import { bracketTypeRe , numberWithUnitRE } from './handlers/regex'
@@ -127,17 +127,37 @@ export function splitShorthand(body: string, type: string) {
127127 * 'red-100' // From theme, plus scale
128128 * 'red-100/20' // From theme, plus scale/opacity
129129 * '[rgb(100 2 3)]/[var(--op)]' // Bracket with rgb color and bracket with opacity
130+ * '[rgb(100 2 3)]/[var(--op)]/[in_oklab]' // Bracket with rgb color, bracket with opacity and bracket with interpolation method
130131 *
131132 * @param body - Color string to be parsed.
132133 * @param theme - {@link Theme} object.
133134 * @return object if string is parseable.
134135 */
135136export function parseColor ( body : string , theme : Theme ) {
136- const split = splitShorthand ( body , 'color' )
137+ let split
138+ const [ front , ...rest ] = getStringComponents ( body , [ '/' , ':' ] , 3 ) ?? [ ]
139+
140+ if ( front != null ) {
141+ const match = ( front . match ( bracketTypeRe ) ?? [ ] ) [ 1 ]
142+
143+ if ( match == null || match === 'color' ) {
144+ split = [ front , ...rest ]
145+ }
146+ }
147+
137148 if ( ! split )
138149 return
139150
140- const [ main , opacity ] = split
151+ let opacity : string | undefined
152+ let [ main , opacityOrModifier , modifier ] = split as [ string , string | undefined , string | undefined ]
153+
154+ if ( isInterpolatedMethod ( opacityOrModifier ) || isInterpolatedMethod ( h . bracket ( opacityOrModifier ?? '' ) ) ) {
155+ modifier = opacityOrModifier
156+ }
157+ else {
158+ opacity = opacityOrModifier
159+ }
160+
141161 const colors = main
142162 . replace ( / ( [ a - z ] ) ( \d ) / g, '$1-$2' )
143163 . split ( / - / g)
@@ -167,6 +187,7 @@ export function parseColor(body: string, theme: Theme) {
167187
168188 return {
169189 opacity,
190+ modifier : ( modifier && h . bracket . cssvar ( modifier ) ) || modifier ,
170191 name,
171192 no,
172193 color : color ?? SpecialColorKey [ name as keyof typeof SpecialColorKey ] ,
@@ -247,7 +268,7 @@ export function colorCSSGenerator(
247268 if ( ! data )
248269 return
249270
250- const { color, keys, alpha } = data
271+ const { color, keys, alpha, modifier } = data
251272 const rawColorComment = ctx ?. generator . config . envMode === 'dev' && color ? ` /* ${ color } */` : ''
252273 const css : CSSObject = { }
253274
@@ -260,16 +281,24 @@ export function colorCSSGenerator(
260281 else {
261282 const alphaKey = `--un-${ varName } -opacity`
262283 const value = keys ? generateThemeVariable ( 'colors' , keys ) : color
263-
264- if ( ! alpha ) {
265- css [ alphaKey ] = alpha
284+ let method = modifier ?? ( keys ? 'in srgb' : 'in oklab' )
285+ if ( ! method . startsWith ( 'in ' ) && ! method . startsWith ( 'var(' ) ) {
286+ method = `in ${ method } `
266287 }
267- css [ property ] = `color-mix(in oklch, ${ value } ${ alpha ?? `var(${ alphaKey } )` } , transparent)${ rawColorComment } `
268288
289+ css [ property ] = `color-mix(${ method } , ${ value } ${ alpha ?? `var(${ alphaKey } )` } , transparent)${ rawColorComment } `
269290 result . push ( defineProperty ( alphaKey , { syntax : '<percentage>' , initialValue : '100%' } ) )
270291
271292 if ( keys ) {
272293 themeTracking ( `colors` , keys )
294+ if ( ! modifier ) {
295+ result . push ( {
296+ [ symbols . parent ] : '@supports (color: color-mix(in lab, red, red))' ,
297+ [ symbols . noMerge ] : true ,
298+ [ symbols . shortcutsNoMerge ] : true ,
299+ [ property ] : `color-mix(in oklab, ${ value } ${ alpha ?? `var(${ alphaKey } )` } , transparent)${ rawColorComment } ` ,
300+ } )
301+ }
273302 }
274303 if ( ctx ?. theme ) {
275304 detectThemeValue ( color , ctx . theme )
0 commit comments