Skip to content

Commit 82b4381

Browse files
authored
feat: add postcss codemod (#893)
* feat: add postcss codemod
1 parent 0ba2441 commit 82b4381

8 files changed

+262
-182
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
#### Custom Property Replacer
2+
3+
The purpose of this PostCSS plugin is to replace deprecated custom properties with the new custom properties. To use this plugin, follow the following instructions.
4+
5+
First create a file called `postcss.config.js` in the root of your project.
6+
7+
```js
8+
module.exports = {
9+
plugins: [
10+
require('@commercetools-frontend/ui-kit/codemods/custom-property-replacer')(
11+
{
12+
file: require.resolve(
13+
'@commercetools-frontend/ui-kit/codemods/custom-property-replacer/v10/variable-mapping.json'
14+
),
15+
}
16+
),
17+
],
18+
};
19+
```
20+
21+
Note: if you are using SCSS instead of CSS, you may need to change the parser. Please check the `postcss-cli` [documentation](https://github.com/postcss/postcss-cli) for more information.
22+
23+
Next, use the command line to run the code transformation.
24+
25+
`npx postcss-cli **/*.css -r`
26+
27+
This will replace your usage of deprecated custom properties with the new custom properties.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
const fs = require('fs');
2+
const postcss = require('postcss');
3+
const parser = require('postcss-value-parser');
4+
5+
module.exports = postcss.plugin('postcss-var-replacer', opts => {
6+
let variables;
7+
8+
if (opts && opts.file) {
9+
variables = JSON.parse(fs.readFileSync(opts.file));
10+
}
11+
12+
if (!variables) {
13+
throw new Error(
14+
'postcss-var-replacer must be configured with the JSON file to use'
15+
);
16+
}
17+
18+
return css => {
19+
css.walkDecls(decl => {
20+
let variableFound = false;
21+
22+
const parsedValue = parser(decl.value);
23+
parsedValue.walk(node => {
24+
if (node.type === 'word' && variables[node.value]) {
25+
variableFound = true;
26+
// eslint-disable-next-line no-param-reassign
27+
node.value = variables[node.value];
28+
}
29+
});
30+
if (variableFound) {
31+
decl.replaceWith(decl.clone({ value: parsedValue.toString() }));
32+
}
33+
});
34+
};
35+
});
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
import path from 'path';
2+
import postcss from 'postcss';
3+
import plugin from '.';
4+
5+
const processor = postcss([
6+
plugin({ file: path.resolve(__dirname, './v10/variable-mapping.json') }),
7+
]);
8+
9+
const process = input => processor.process(input).css;
10+
11+
describe('custom-property-replacer', () => {
12+
describe('with nested selectors', () => {
13+
it('should replace known variables', () => {
14+
expect(process('a { span { color: var(--color-green) }}')).toEqual(
15+
'a { span { color: var(--color-primary) }}'
16+
);
17+
});
18+
});
19+
it('should replace known variables', () => {
20+
expect(process('a { color: var(--color-green) }')).toEqual(
21+
'a { color: var(--color-primary) }'
22+
);
23+
});
24+
it('should ignore unknown variables', () => {
25+
expect(process('a { color: var(--color-green-99) }')).toEqual(
26+
'a { color: var(--color-green-99) }'
27+
);
28+
});
29+
30+
it('throws an error if the file option is not defined', () => {
31+
expect(() => {
32+
postcss(plugin());
33+
}).toThrow(
34+
'postcss-var-replacer must be configured with the JSON file to use'
35+
);
36+
});
37+
});
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
const customPropertyReplacer = require('./custom-property-replacer');
2+
3+
module.exports = customPropertyReplacer;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
{
2+
"--color-green": "--color-primary",
3+
"--color-green-25": "--color-primary-25",
4+
"--color-green-40": "--color-primary-40",
5+
"--color-green-85": "--color-primary-85",
6+
"--color-green-95": "--color-primary-95",
7+
"--color-navy": "--color-accent",
8+
"--color-navy-30": "--color-accent-30",
9+
"--color-navy-40": "--color-accent-40",
10+
"--color-navy-95": "--color-accent-95",
11+
"--color-navy-98": "--color-accent-98",
12+
"--color-gray": "--color-neutral",
13+
"--color-gray-60": "--color-neutral-60",
14+
"--color-gray-90": "--color-neutral-90",
15+
"--color-gray-95": "--color-neutral-95",
16+
"--color-blue": "--color-info",
17+
"--color-blue-85": "--color-info-95",
18+
"--color-blue-95": "--color-info-95",
19+
"--color-orange": "--color-warning",
20+
"--color-orange-95": "--color-warning-95",
21+
"--color-red": "--color-error",
22+
"--color-red-95": "--color-error-95",
23+
"--color-black": "--color-solid",
24+
"--color-white": "--color-surface",
25+
"--spacing-4": "--spacing-xs",
26+
"--spacing-8": "--spacing-s",
27+
"--spacing-16": "--spacing-m",
28+
"--spacing-24": "--spacing-l",
29+
"--spacing-32": "--spacing-xl",
30+
"--background-color-input-pristine": "--background-color-for-input",
31+
"--background-color-input-disabled": "--background-color-for-input-when-disabled",
32+
"--background-color-input-hover": "--background-color-for-input-when-hovered",
33+
"--background-color-input-selected": "--background-color-for-input-when-selected",
34+
"--background-color-tag-pristine": "--background-color-for-tag",
35+
"--background-color-tag-warning": "--background-color-for-tag-warning",
36+
"--border-color-input-pristine": "--border-color-for-input",
37+
"--border-color-input-focus": "--border-color-for-input-when-focused",
38+
"--border-color-input-disabled": "--border-color-for-input-when-disabled",
39+
"--border-color-input-readonly": "--border-color-for-input-when-readonly",
40+
"--border-color-input-error": "--border-color-for-input-when-error",
41+
"--border-color-input-warning": "--border-color-for-input-when-warning",
42+
"--border-color-tag-pristine": "--border-color-for-tag",
43+
"--border-color-tag-warning": "--border-color-for-tag-warning",
44+
"--border-color-tag-focus": "--border-color-for-tag-when-focused",
45+
"--border-color-tag-warning-hover": "--border-color-for-tag-warning"
46+
}

0 commit comments

Comments
 (0)