Skip to content

Commit e80cf5e

Browse files
authored
Handle sx prop
1 parent 6faf125 commit e80cf5e

File tree

2 files changed

+40
-11
lines changed

2 files changed

+40
-11
lines changed

src/rules/__tests__/no-deprecated-colors.test.js

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,10 @@ ruleTester.run('no-deprecated-colors', rule, {
2828
`import {hello} from "@primer/components"; hello("colors.text.primary")`,
2929
`import {themeGet} from "@primer/components"; themeGet("space.text.primary")`,
3030
`import {themeGet} from "@other/design-system"; themeGet("colors.text.primary")`,
31-
`import {get} from "@other/constants"; get("space.text.primary")`
31+
`import {get} from "@other/constants"; get("space.text.primary")`,
32+
`import {Box} from '@primer/components'; <Box sx={styles}>Hello</Box>`,
33+
`import {Box} from '@primer/components'; <Box sx={{color: text.primary}}>Hello</Box>`,
34+
`import {Box} from '@primer/components'; <Box sx={{color: "fg.default"}}>Hello</Box>`
3235
],
3336
invalid: [
3437
{
@@ -67,6 +70,15 @@ ruleTester.run('no-deprecated-colors', rule, {
6770
}
6871
]
6972
},
73+
{
74+
code: `import {Box} from "@primer/components"; <Box sx={{bg: "bg.primary", m: 1, ...rest}} />`,
75+
output: `import {Box} from "@primer/components"; <Box sx={{bg: "canvas.default", m: 1, ...rest}} />`,
76+
errors: [
77+
{
78+
message: '"bg.primary" is deprecated. Use "canvas.default" instead.'
79+
}
80+
]
81+
},
7082
{
7183
code: `import {Box} from "@primer/components"; <Box color="auto.green.5" />`,
7284
errors: [

src/rules/no-deprecated-colors.js

Lines changed: 27 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,22 @@ module.exports = {
2222
const propName = attribute.name.name
2323
const propValue = attribute.value.value
2424

25-
// TODO: handle sx prop
25+
// Check for the sx prop
26+
if (propName === 'sx' && attribute.value.expression.type === 'ObjectExpression') {
27+
// Ignore non-literal properties
28+
const sxProperties = attribute.value.expression.properties.filter(
29+
property => property.type === 'Property' && property.value.type === 'Literal'
30+
)
31+
32+
for (const prop of sxProperties) {
33+
const propName = prop.key.name
34+
const propValue = prop.value.value
35+
36+
if (styledSystemColorProps.includes(propName) && Object.keys(deprecations).includes(propValue)) {
37+
replaceDeprecatedColor(context, prop.value, propValue)
38+
}
39+
}
40+
}
2641

2742
// Check if styled-system color prop is using a deprecated color
2843
if (styledSystemColorProps.includes(propName) && Object.keys(deprecations).includes(propValue)) {
@@ -31,7 +46,8 @@ module.exports = {
3146
}
3247
},
3348
CallExpression(node) {
34-
// Skip if not `themeGet` or `get` function
49+
// Skip if not calling the `themeGet` or `get` function
50+
// `get` is the internal version of `themeGet` that's used in the primer/react repository
3551
if (!isThemeGet(node.callee, context.getScope(node)) && !isGet(node.callee, context.getScope(node))) {
3652
return
3753
}
@@ -86,35 +102,36 @@ function isGet(identifier, scope) {
86102
return isImportedFrom(/^\.\.?\/constants$/, identifier, scope) && identifier.name === 'get'
87103
}
88104

89-
function replaceDeprecatedColor(context, node, deprecatedName, transformName = str => str) {
105+
function replaceDeprecatedColor(context, node, deprecatedName, getDisplayName = str => str) {
90106
const replacement = deprecations[deprecatedName]
91-
const transformedDeprecatedName = transformName(deprecatedName)
92107

93108
if (replacement === null) {
94109
// No replacement
95110
context.report({
96111
node,
97-
message: `"${transformedDeprecatedName}" is deprecated. Go to https://primer.style/primitives or reach out in the #primer channel on Slack to find a suitable replacement.`
112+
message: `"${getDisplayName(
113+
deprecatedName
114+
)}" is deprecated. Go to https://primer.style/primitives or reach out in the #primer channel on Slack to find a suitable replacement.`
98115
})
99116
} else if (Array.isArray(replacement)) {
100117
// Multiple possible replacements
101118
context.report({
102119
node,
103-
message: `"${transformedDeprecatedName}" is deprecated.`,
120+
message: `"${getDisplayName(deprecatedName)}" is deprecated.`,
104121
suggest: replacement.map(replacementValue => ({
105-
desc: `Use "${transformName(replacementValue)}" instead.`,
122+
desc: `Use "${getDisplayName(replacementValue)}" instead.`,
106123
fix(fixer) {
107-
return fixer.replaceText(node, JSON.stringify(transformName(replacementValue)))
124+
return fixer.replaceText(node, JSON.stringify(getDisplayName(replacementValue)))
108125
}
109126
}))
110127
})
111128
} else {
112129
// One replacement
113130
context.report({
114131
node,
115-
message: `"${transformedDeprecatedName}" is deprecated. Use "${transformName(replacement)}" instead.`,
132+
message: `"${getDisplayName(deprecatedName)}" is deprecated. Use "${getDisplayName(replacement)}" instead.`,
116133
fix(fixer) {
117-
return fixer.replaceText(node, JSON.stringify(transformName(replacement)))
134+
return fixer.replaceText(node, JSON.stringify(getDisplayName(replacement)))
118135
}
119136
})
120137
}

0 commit comments

Comments
 (0)