Skip to content

Commit fbf2f88

Browse files
Add migration to replace static mixins with declarations (#7216)
1 parent b31f51f commit fbf2f88

File tree

8 files changed

+164
-0
lines changed

8 files changed

+164
-0
lines changed

.changeset/lovely-boats-relate.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'@shopify/polaris-migrator': minor
3+
---
4+
5+
Add migration to replace static mixins with declarations

polaris-migrator/README.md

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,20 @@ Replace legacy static breakpoint mixins with the new Polaris [media query variab
8585
npx @shopify/polaris-migrator replace-static-breakpoint-mixins <path>
8686
```
8787

88+
### `replace-static-mixins-with-declarations`
89+
90+
Replace legacy static mixins with their corresponding declarations and CSS custom properties.
91+
92+
```diff
93+
- @include text-emphasis-normal;
94+
+ color: var(--p-text);
95+
+ font-weight: var(--p-font-weight-regular);
96+
```
97+
98+
```sh
99+
npx @shopify/polaris-migrator replace-static-mixins-with-declarations <path>
100+
```
101+
88102
## Creating a migration
89103

90104
### Setup
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
import {FileInfo, API, Options} from 'jscodeshift';
2+
import postcss, {Plugin} from 'postcss';
3+
4+
import {NamespaceOptions, getNamespacePattern} from '../../utilities/sass';
5+
import {isKeyOf} from '../../utilities/type-guards';
6+
7+
/** Mapping of static mixins to replacement declarations */
8+
const staticMixins = {
9+
// Note: The below mixins do accept arguments, but the logic has
10+
// since been removed from the mixins.
11+
'text-emphasis-subdued': {
12+
color: 'var(--p-text-subdued)',
13+
},
14+
'text-emphasis-strong': {
15+
'font-weight': 'var(--p-font-weight-semibold)',
16+
},
17+
'text-emphasis-normal': {
18+
color: 'var(--p-text)',
19+
'font-weight': 'var(--p-font-weight-regular)',
20+
},
21+
};
22+
23+
interface PluginOptions extends Options, NamespaceOptions {}
24+
25+
const plugin = (options: PluginOptions = {}): Plugin => {
26+
const namespacePattern = getNamespacePattern(options);
27+
28+
const namespacedMixinRegExp = new RegExp(
29+
String.raw`^${namespacePattern}([\w-]+)`,
30+
);
31+
32+
return {
33+
postcssPlugin: 'replace-static-mixins-with-declarations',
34+
AtRule(atRule) {
35+
if (atRule.name !== 'include') return;
36+
37+
// Extract mixin name e.g. name from `@include name;` or `@include name();`
38+
const mixinName = atRule.params.match(namespacedMixinRegExp)?.[1];
39+
40+
if (!isKeyOf(staticMixins, mixinName)) return;
41+
42+
atRule.replaceWith(
43+
...Object.entries(staticMixins[mixinName]).map(([prop, value]) =>
44+
postcss.decl({
45+
prop,
46+
value,
47+
}),
48+
),
49+
);
50+
},
51+
};
52+
};
53+
54+
export default function replaceStaticMixinsWithDeclarations(
55+
fileInfo: FileInfo,
56+
_: API,
57+
options: Options,
58+
) {
59+
return postcss(plugin(options)).process(fileInfo.source, {
60+
syntax: require('postcss-scss'),
61+
}).css;
62+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
.normal {
2+
@include text-emphasis-normal;
3+
}
4+
5+
.strong {
6+
@include text-emphasis-strong;
7+
}
8+
9+
.subdued {
10+
@include text-emphasis-subdued;
11+
}
12+
13+
.subdued-with-args {
14+
@include text-emphasis-subdued(green);
15+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
.normal {
2+
color: var(--p-text);
3+
font-weight: var(--p-font-weight-regular);
4+
}
5+
6+
.strong {
7+
font-weight: var(--p-font-weight-semibold);
8+
}
9+
10+
.subdued {
11+
color: var(--p-text-subdued);
12+
}
13+
14+
.subdued-with-args {
15+
color: var(--p-text-subdued);
16+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
import {check} from '../../../utilities/testUtils';
2+
3+
const migration = 'replace-static-mixins-with-declarations';
4+
const fixtures = ['replace-static-mixins-with-declarations', 'with-namespace'];
5+
6+
for (const fixture of fixtures) {
7+
check(__dirname, {
8+
fixture,
9+
migration,
10+
extension: 'scss',
11+
options: {
12+
namespace: fixture.includes('with-namespace')
13+
? 'legacy-polaris-v8'
14+
: undefined,
15+
},
16+
});
17+
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
@use 'global-styles/legacy-polaris-v8';
2+
3+
.normal {
4+
@include legacy-polaris-v8.text-emphasis-normal;
5+
}
6+
7+
.strong {
8+
@include legacy-polaris-v8.text-emphasis-strong;
9+
}
10+
11+
.subdued {
12+
@include legacy-polaris-v8.text-emphasis-subdued;
13+
}
14+
15+
.subdued-with-args {
16+
@include legacy-polaris-v8.text-emphasis-subdued(green);
17+
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
@use 'global-styles/legacy-polaris-v8';
2+
3+
.normal {
4+
color: var(--p-text);
5+
font-weight: var(--p-font-weight-regular);
6+
}
7+
8+
.strong {
9+
font-weight: var(--p-font-weight-semibold);
10+
}
11+
12+
.subdued {
13+
color: var(--p-text-subdued);
14+
}
15+
16+
.subdued-with-args {
17+
color: var(--p-text-subdued);
18+
}

0 commit comments

Comments
 (0)