Skip to content

Commit 108b8b5

Browse files
committed
handle identifiers, add more test cases
1 parent c2774e5 commit 108b8b5

File tree

2 files changed

+76
-7
lines changed

2 files changed

+76
-7
lines changed

src/rules/__tests__/no-color-css-vars.test.js

Lines changed: 54 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -110,8 +110,41 @@ ruleTester.run('no-color-css-vars', rule, {
110110
message: 'Replace var(--color-canvas-default) with canvas.default'
111111
}
112112
]
113+
},
114+
{
115+
name: 'variable in scope',
116+
code: `
117+
const baseStyles = { color: 'var(--color-fg-muted)' }
118+
export const Fixture = <Button sx={baseStyles}>Test</Button>
119+
`,
120+
output: `
121+
const baseStyles = { color: 'fg.muted' }
122+
export const Fixture = <Button sx={baseStyles}>Test</Button>
123+
`,
124+
errors: [
125+
{
126+
message: 'Replace var(--color-fg-muted) with fg.muted'
127+
}
128+
]
129+
},
130+
{
131+
name: 'merge in sx',
132+
code: `
133+
import {merge} from '@primer/react'
134+
export const Fixture = props => <Button sx={merge({color: 'var(--color-fg-muted)'}, props.sx)}>Test</Button>
135+
`,
136+
output: `
137+
import {merge} from '@primer/react'
138+
export const Fixture = props => <Button sx={merge({color: 'fg.muted'}, props.sx)}>Test</Button>
139+
`,
140+
errors: [
141+
{
142+
message: 'Replace var(--color-fg-muted) with fg.muted'
143+
}
144+
]
113145
}
114146
// {
147+
// name: 'variable in styled.component',
115148
// code: `
116149
// import {sx, SxProp} from '@primer/react'
117150
// export const HighlightToken = styled.span<SxProp>\`
@@ -138,15 +171,31 @@ ruleTester.run('no-color-css-vars', rule, {
138171
// }
139172
// ]
140173
// },
141-
142174
// {
175+
// name: 'MemberExpression in sx: not handled',
176+
// code: `
177+
// const colors = { muted: 'var(--color-fg-muted)' }
178+
// export const Fixture = <Button sx={colors.muted}>Test</Button>
179+
// `,
180+
// output: `
181+
// const colors = { muted: 'fg.muted' }
182+
// export const Fixture = <Button sx={colors.muted}>Test</Button>
183+
// `,
184+
// errors: [
185+
// {
186+
// message: 'Replace var(--color-fg-muted) with fg.muted'
187+
// }
188+
// ]
189+
// },
190+
// {
191+
// name: 'CallExpression in sx: not handled',
143192
// code: `
144-
// const styles = { color: 'var(--color-fg-muted)' }
145-
// export const Fixture = <Button sx={styles}>Test</Button>
193+
// const getColors = () => 'var(--color-fg-muted)'
194+
// export const Fixture = <Button sx={getColors()}>Test</Button>
146195
// `,
147196
// output: `
148-
// const styles = { color: 'fg.muted' }
149-
// export const Fixture = <Button sx={styles}>Test</Button>
197+
// const getColors = () => 'fg.muted'
198+
// export const Fixture = <Button sx={getColors()}>Test</Button>
150199
// `,
151200
// errors: [
152201
// {

src/rules/no-color-css-vars.js

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ module.exports = {
2323
}
2424
]
2525
},
26+
/** @param {import('eslint').Rule.RuleContext} context */
2627
create(context) {
2728
const styledSystemProps = [
2829
'bg',
@@ -39,10 +40,29 @@ module.exports = {
3940
]
4041

4142
return {
43+
/** @param {import('eslint').Rule.Node} node */
4244
JSXAttribute(node) {
4345
if (node.name.name === 'sx') {
44-
const rawText = context.getSourceCode().getText(node.value)
45-
checkForVariables(node.value, rawText)
46+
if (node.value.expression.type === 'ObjectExpression') {
47+
// example: sx={{ color: 'fg.default' }} or sx={{ ':hover': {color: 'fg.default'} }}
48+
const rawText = context.sourceCode.getText(node.value)
49+
checkForVariables(node.value, rawText)
50+
} else if (node.value.expression.type === 'Identifier') {
51+
// example: sx={baseStyles}
52+
const variableScope = context.sourceCode.getScope(node.value.expression)
53+
const variable = variableScope.set.get(node.value.expression.name)
54+
55+
// if variable is not defined in scope, give up (could be imported from different file)
56+
if (!variable) return
57+
58+
const variableDeclarator = variable.identifiers[0].parent
59+
const rawText = context.sourceCode.getText(variableDeclarator)
60+
checkForVariables(variableDeclarator, rawText)
61+
} else {
62+
// worth a try!
63+
const rawText = context.sourceCode.getText(node.value)
64+
checkForVariables(node.value, rawText)
65+
}
4666
} else if (
4767
styledSystemProps.includes(node.name.name) &&
4868
node.value.type === 'Literal' &&

0 commit comments

Comments
 (0)