Skip to content

Commit

Permalink
Improve(CSS): Make CSS variable syntax support color tokens, resolved #…
Browse files Browse the repository at this point in the history
  • Loading branch information
BenSeage committed Sep 20, 2023
1 parent 2e97d64 commit 5fa9fa5
Show file tree
Hide file tree
Showing 6 changed files with 36 additions and 84 deletions.
2 changes: 1 addition & 1 deletion packages/css/src/config/functions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ const functions: Functions = {
+ (functionConfig.name ?? newFunctionName)
+ '('
// @ts-ignore
+ (functionConfig.transform?.(functionValue) ?? functionValue)
+ (functionConfig.transform?.call(instance, functionValue) ?? functionValue)
+ ')'
}
}
Expand Down
15 changes: 15 additions & 0 deletions packages/css/src/config/rules.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import cssEscape from 'shared/utils/css-escape'
import { START_SYMBOLS } from '../constants/start-symbol'
import { Declarations, Rule, RuleConfig } from '../rule'
import { transformColorWithOpacity } from '../functions/transform-color-with-opacity'

const defaultRules = {
group: {
Expand Down Expand Up @@ -145,6 +146,20 @@ const defaultRules = {
} as RuleConfig,
variable: {
match: '^\\$[^ (){}A-Z]+:[^ ]', // don't use 'rem' as default, because css variable is common API
transform(value) {
const regexp = new RegExp(`^((?:${this.css.colorNames.join('|')})(?:-(?:[0-9A-Za-z-]+))?)(?:\\/(\\.?[0-9]+%?))?(?:@(.*?))?$`, 'm')
const result = regexp.exec(value)
if (result) {
const [, colorName, opacityStr, themeName] = result
const color = this.css.colorThemesMap[colorName]?.[themeName || '']
if (color)
return (opacityStr
? transformColorWithOpacity(color, opacityStr)
: color)
}

return value
},
declare(value) {
return {
['--' + this.prefix.slice(1, -1)]: value
Expand Down
11 changes: 11 additions & 0 deletions packages/css/src/functions/transform-color-with-opacity.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
export function transformColorWithOpacity(color: string, opacityStr: string) {
let opacity = opacityStr.endsWith('%')
? parseFloat(opacityStr) / 100.0
: +opacityStr

opacity = isNaN(opacity)
? 1
: Math.min(Math.max(opacity, 0), 1)

return color + Math.round(opacity * 255).toString(16).toUpperCase().padStart(2, '0')
}
18 changes: 4 additions & 14 deletions packages/css/src/rule.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import type { MasterCSS } from './core'
import { START_SYMBOLS } from './constants/start-symbol'
import cssEscape from 'shared/utils/css-escape'
import { extend } from '@techor/extend'
import { transformColorWithOpacity } from './functions/transform-color-with-opacity'

const defaultConfig: RuleConfig = {
unit: '',
Expand Down Expand Up @@ -620,20 +621,9 @@ export class Rule {
anyColorMatched = anyMatched
}

let newValue = color
if (opacityStr) {
let opacity = opacityStr.endsWith('%')
? parseFloat(opacityStr) / 100.0
: +opacityStr

opacity = isNaN(opacity)
? 1
: Math.min(Math.max(opacity, 0), 1)

newValue += Math.round(opacity * 255).toString(16).toUpperCase().padStart(2, '0')
}

return prefix + newValue
return prefix + (opacityStr
? transformColorWithOpacity(color, opacityStr)
: color)
} else {
anyColorMismatched = true
}
Expand Down
69 changes: 0 additions & 69 deletions packages/css/src/utils/parse-rule-value.ts

This file was deleted.

5 changes: 5 additions & 0 deletions packages/css/tests/functions.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,4 +20,9 @@ test('functions', () => {
testCSS('mt:calc($(g-y)*(-.1))', '.mt\\:calc\\(\\$\\(g-y\\)\\*\\(-\\.1\\)\\){margin-top:calc(var(--g-y) * (-0.00625rem))}')
testCSS('mt:calc($(g-y)--.1)', '.mt\\:calc\\(\\$\\(g-y\\)--\\.1\\){margin-top:calc(var(--g-y) - -0.00625rem)}')
testCSS('mr:calc($(g-x)/(-2px))', '.mr\\:calc\\(\\$\\(g-x\\)\\/\\(-2px\\)\\){margin-right:calc(var(--g-x) / (-2px))}')

testCSS('$primary:red', '.\\$primary\\:red{--primary:#d11a1e}')
testCSS('$primary:red-80', '.\\$primary\\:red-80{--primary:#fdcfcf}')
testCSS('$primary:red/.5', '.\\$primary\\:red\\/\\.5{--primary:#d11a1e80}')
testCSS('$primary:red-80/.5', '.\\$primary\\:red-80\\/\\.5{--primary:#fdcfcf80}')
})

0 comments on commit 5fa9fa5

Please sign in to comment.