Skip to content

Commit 287cff8

Browse files
chore: adds support to parse "transparent" token references (#3452)
* feat(tokens): add transparent token handling * adds transparent mapping into rgb-mapping plugin - custom properties that reference transparent tokens will now be mapped to their corresponding transparent rgb/opacity tokens - extends the work that the rgb-mapping plugin already does * test: add plugin test cases * chore(plugins/postcss-rgb-mapping): update README.md * chore: add changeset
1 parent 132cab6 commit 287cff8

File tree

6 files changed

+139
-2
lines changed

6 files changed

+139
-2
lines changed

.changeset/curly-jokes-design.md

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
---
2+
"@spectrum-tools/postcss-rgb-mapping": minor
3+
---
4+
5+
Adds new functionality to better handle tokens that reference other transparent tokens.
6+
7+
When a custom properties below is defined as another, specifically "transparent," variable, such as:
8+
9+
```css
10+
--disabled-static-white-background-color: var(--spectrum-transparent-white-100);
11+
```
12+
13+
...the plugin can now convert this single custom property into its `-rgb` and `-opacity` postfixed variables, that each correspond to the `-rgb` and `-opacity` variables of the definition's transparent token. It then reassembles the original, using and referencing these newly created variables.
14+
15+
```css
16+
--disabled-static-white-background-color-rgb: var(
17+
--spectrum-transparent-white-100-rgb
18+
);
19+
--disabled-static-white-background-color-opacity: var(
20+
--spectrum-transparent-white-100-opacity
21+
);
22+
--disabled-static-white-background-color: rgba(
23+
var(--disabled-static-white-background-color-rgb),
24+
var(--disabled-static-white-background-color-opacity)
25+
);
26+
```

plugins/postcss-rgb-mapping/README.md

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
# postcss-rgb-mapping
22

33
> Remaps rgb(a) values to an `rgb` postfixed variable. If an opacity is found, creates a separate `opacity` postfixed variable.
4+
> Also remaps values that reference a transparent token (for example, `transparent-black-300`) to `rgb` and `opacity` postfixed variables.
45
56
## Installation
67

@@ -11,6 +12,8 @@ postcss -u postcss-rgb-mapping -o dist/index.css src/index.css
1112

1213
## Usage
1314

15+
### Example 1: RGB and opacity postfixed variables
16+
1417
This plugin turns this:
1518

1619
```css
@@ -24,13 +27,63 @@ Into this:
2427

2528
```css
2629
.spectrum--lightest {
30+
/* Both --spectrum-seafoam-100 and --spectrum-seafoam-200 get split into separate
31+
"-rgb" and "-opacity" values when applicable. */
2732
--spectrum-seafoam-100-rgb: 206, 247, 243;
2833
--spectrum-seafoam-100: rgba(var(--spectrum-seafoam-100-rgb));
2934
--spectrum-seafoam-200-rgb: 170, 241, 234;
3035
--spectrum-seafoam-200-opacity: 0.5;
36+
/* The plugin then redefines the original custom variable to use the newly created
37+
"-rgb" and/or "-opacity" custom variables. */
3138
--spectrum-seafoam-200: rgba(
3239
var(--spectrum-seafoam-200-rgb),
3340
var(--spectrum-seafoam-200-opacity)
3441
);
3542
}
3643
```
44+
45+
### Example 2: Remapping of transparent tokens
46+
47+
This plugin turns this:
48+
49+
```css
50+
.spectrum--lightest {
51+
--spectrum-transparent-white-100-rgb: 100, 100, 100;
52+
--spectrum-transparent-white-100-opacity: 0.5;
53+
--spectrum-transparent-white-100: rgba(
54+
var(--spectrum-transparent-white-100-rgb),
55+
var(--spectrum-transparent-white-100-opacity)
56+
);
57+
/* The custom properties below is defined as another, specifically "transparent," variable. */
58+
--disabled-static-white-background-color: var(
59+
--spectrum-transparent-white-100
60+
);
61+
}
62+
```
63+
64+
Into this:
65+
66+
```css
67+
.spectrum--lightest {
68+
--spectrum-transparent-white-100-rgb: 100, 100, 100;
69+
--spectrum-transparent-white-100-opacity: 0.5;
70+
--spectrum-transparent-white-100: rgba(
71+
var(--spectrum-transparent-white-100-rgb),
72+
var(--spectrum-transparent-white-100-opacity)
73+
);
74+
/* In a similar fashion, the plugin creates new "-rgb" and "-opacity" postfixed custom
75+
variables, that correspond to the definition's transparent "-rgb" and "-opacity"
76+
postfixed custom variables. */
77+
--disabled-static-white-background-color-rgb: var(
78+
--spectrum-transparent-white-100-rgb
79+
);
80+
--disabled-static-white-background-color-opacity: var(
81+
--spectrum-transparent-white-100-opacity
82+
);
83+
/* Then reassembles the original to use and reference these newly created variables. */
84+
--disabled-static-white-background-color: rgba(
85+
var(--disabled-static-white-background-color-rgb),
86+
var(--disabled-static-white-background-color-opacity)
87+
);
88+
}
89+
```

plugins/postcss-rgb-mapping/expected/basic.css

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,4 +6,10 @@
66
--seafoam-200: rgba(var(--seafoam-200-rgb), var(--seafoam-200-opacity));
77
--seafoam-300-rgb: 206, 247, 243;
88
--seafoam-300: rgba(var(--seafoam-300-rgb));
9+
--spectrum-transparent-white-100-rgb: 100, 100, 100;
10+
--spectrum-transparent-white-100-opacity: 0.5;
11+
--spectrum-transparent-white-100: rgba(var(--spectrum-transparent-white-100-rgb), var(--spectrum-transparent-white-100-opacity));
12+
--disabled-static-white-background-color-rgb: var(--spectrum-transparent-white-100-rgb);
13+
--disabled-static-white-background-color-opacity: var(--spectrum-transparent-white-100-opacity);
14+
--disabled-static-white-background-color: rgba(var(--disabled-static-white-background-color-rgb), var(--disabled-static-white-background-color-opacity));
915
}

plugins/postcss-rgb-mapping/expected/modern.css

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,4 +6,10 @@
66
--seafoam-200: rgba(var(--seafoam-200-rgb) / var(--seafoam-200-opacity));
77
--seafoam-300-rgb: 206 247 243;
88
--seafoam-300: rgba(var(--seafoam-300-rgb));
9+
--spectrum-transparent-white-100-rgb: 100 100 100;
10+
--spectrum-transparent-white-100-opacity: 50%;
11+
--spectrum-transparent-white-100: rgba(var(--spectrum-transparent-white-100-rgb) / var(--spectrum-transparent-white-100-opacity));
12+
--disabled-static-white-background-color-rgb: var(--spectrum-transparent-white-100-rgb);
13+
--disabled-static-white-background-color-opacity: var(--spectrum-transparent-white-100-opacity);
14+
--disabled-static-white-background-color: rgba(var(--disabled-static-white-background-color-rgb) / var(--disabled-static-white-background-color-opacity));
915
}

plugins/postcss-rgb-mapping/fixtures/basic.css

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,6 @@
22
--seafoam-100: rgba(206, 247, 243);
33
--seafoam-200: rgba(206, 247, 243, 0.5);
44
--seafoam-300: rgb(206, 247, 243);
5+
--spectrum-transparent-white-100: rgba(100, 100, 100, 0.5);
6+
--disabled-static-white-background-color: var(--spectrum-transparent-white-100);
57
}

plugins/postcss-rgb-mapping/index.js

Lines changed: 46 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,18 +23,63 @@ const valuesParser = require("postcss-values-parser");
2323
function rgbMappingFunction ({
2424
colorFunctionalNotation = false,
2525
}) {
26+
2627
return {
2728
postcssPlugin: "postcss-rgb-mapping",
29+
/** @type {import('postcss').RootProcessor} */
30+
Root(root) {
31+
/* Gather all the custom properties that reference "unprocessed" transparent tokens (i.e. transparent-white-200) */
32+
const transparentTokens = new Set();
33+
root.walkDecls(decl => {
34+
if (decl.prop.startsWith('--spectrum-transparent-') && !decl.prop.endsWith('rgb') && !decl.prop.endsWith('opacity')) {
35+
transparentTokens.add(decl.prop);
36+
}
37+
});
38+
39+
root.walkDecls(decl => {
40+
const { prop, value } = decl;
41+
42+
/* Determine if this property is a custom property */
43+
const isCustomProp = prop.startsWith("--");
44+
45+
/* Determine if this property has already been processed */
46+
const isProcessed = prop.endsWith("rgb") || prop.endsWith("opacity");
47+
48+
/* Check for transparent token reference */
49+
const transparentMatch = value.match(/var\((--spectrum-transparent-[^\s)]+)\)/);
50+
if (isCustomProp && !isProcessed && transparentMatch) {
51+
const referencedToken = transparentMatch[1];
52+
53+
if (transparentTokens.has(referencedToken)) {
54+
/* Create the new RGB and opacity properties */
55+
decl.cloneBefore({
56+
prop: `${prop}-rgb`,
57+
value: `var(${referencedToken}-rgb)`
58+
});
59+
decl.cloneBefore({
60+
prop: `${prop}-opacity`,
61+
value: `var(${referencedToken}-opacity)`
62+
});
63+
64+
/* Update the original declaration */
65+
decl.value = `rgba(var(${prop}-rgb)${colorFunctionalNotation ? " / " : ", "}var(${prop}-opacity))`;
66+
}
67+
}
68+
return;
69+
});
70+
},
71+
2872
/** @type {import('postcss').DeclarationProcessor} */
2973
Declaration(decl, { Warning }) {
3074
const { prop, value } = decl;
3175

3276
/* Determine if this property is a custom property */
3377
const isCustomProp = prop.startsWith("--");
78+
3479
/* Determine if this property has already been processed */
3580
const isProcessed = prop.endsWith("rgb") || prop.endsWith("opacity");
3681

37-
/* Parse the value for it's parts */
82+
/* Parse the value for its parts */
3883
const parsedValue = valuesParser.parse(value) || [];
3984

4085
/* Determine if the value has an rgb or rgba value */
@@ -114,7 +159,6 @@ function rgbMappingFunction ({
114159
decl.assign({
115160
value: `rgba(var(${prop}-rgb)${a ? `${colorFunctionalNotation ? " /" : ","} var(${prop}-opacity)` : ""})`,
116161
});
117-
118162
return;
119163
},
120164
};

0 commit comments

Comments
 (0)