1
1
import type { CSSEntries , CSSObject , CSSObjectInput , CSSValueInput , DynamicMatcher , RuleContext , StaticRule , VariantContext } from '@unocss/core'
2
2
import type { Theme } from '../theme'
3
3
import { 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'
5
5
import { SpecialColorKey } from './constant'
6
6
import { h } from './handlers'
7
7
import { bracketTypeRe , numberWithUnitRE } from './handlers/regex'
@@ -127,17 +127,37 @@ export function splitShorthand(body: string, type: string) {
127
127
* 'red-100' // From theme, plus scale
128
128
* 'red-100/20' // From theme, plus scale/opacity
129
129
* '[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
130
131
*
131
132
* @param body - Color string to be parsed.
132
133
* @param theme - {@link Theme} object.
133
134
* @return object if string is parseable.
134
135
*/
135
136
export 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
+
137
148
if ( ! split )
138
149
return
139
150
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
+
141
161
const colors = main
142
162
. replace ( / ( [ a - z ] ) ( \d ) / g, '$1-$2' )
143
163
. split ( / - / g)
@@ -167,6 +187,7 @@ export function parseColor(body: string, theme: Theme) {
167
187
168
188
return {
169
189
opacity,
190
+ modifier : ( modifier && h . bracket . cssvar ( modifier ) ) || modifier ,
170
191
name,
171
192
no,
172
193
color : color ?? SpecialColorKey [ name as keyof typeof SpecialColorKey ] ,
@@ -247,7 +268,7 @@ export function colorCSSGenerator(
247
268
if ( ! data )
248
269
return
249
270
250
- const { color, keys, alpha } = data
271
+ const { color, keys, alpha, modifier } = data
251
272
const rawColorComment = ctx ?. generator . config . envMode === 'dev' && color ? ` /* ${ color } */` : ''
252
273
const css : CSSObject = { }
253
274
@@ -260,16 +281,24 @@ export function colorCSSGenerator(
260
281
else {
261
282
const alphaKey = `--un-${ varName } -opacity`
262
283
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 } `
266
287
}
267
- css [ property ] = `color-mix(in oklch, ${ value } ${ alpha ?? `var(${ alphaKey } )` } , transparent)${ rawColorComment } `
268
288
289
+ css [ property ] = `color-mix(${ method } , ${ value } ${ alpha ?? `var(${ alphaKey } )` } , transparent)${ rawColorComment } `
269
290
result . push ( defineProperty ( alphaKey , { syntax : '<percentage>' , initialValue : '100%' } ) )
270
291
271
292
if ( keys ) {
272
293
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
+ }
273
302
}
274
303
if ( ctx ?. theme ) {
275
304
detectThemeValue ( color , ctx . theme )
0 commit comments