Skip to content

Commit 6bbafca

Browse files
authored
Merge pull request #7 from primer/check-import-option
[no-deprecated-colors] Add `skipImportCheck` option
2 parents 56557b4 + d9dfb8d commit 6bbafca

File tree

4 files changed

+58
-9
lines changed

4 files changed

+58
-9
lines changed

.changeset/curly-carrots-tickle.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"eslint-plugin-primer-react": patch
3+
---
4+
5+
Add `skipImportCheck` option. By default, the `no-deprecated-colors` rule will only check for deprecated colors used in functions and components that are imported from `@primer/components`. You can disable this behavior by setting `skipImportCheck` to `true`. This is useful for linting custom components that pass color-related props down to Primer React components.

docs/rules/no-deprecated-colors.md

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,12 @@
22

33
🔧 The `--fix` option on the [ESLint CLI](https://eslint.org/docs/user-guide/command-line-interface#fixing-problems) can automatically fix some of the problems reported by this rule.
44

5-
[Theming](https://primer.style/react/theming) in Primer React is made possible by a theme object that defines your application's colors, spacing, fonts, and more. The color variables in Primer React's [default theme object](https://primer.style/react/theme-reference) are pulled from [Primer Primitives](https://github.com/primer/primitives). When a color variable is deprecated in Primer Primitives, it's important to remove references to that color variable in your application before it's removed from the library.
5+
[Theming](https://primer.style/react/theming) in Primer React is made possible by a theme object that defines your application's colors, spacing, fonts, and more. The color variables in Primer React's [default theme object](https://primer.style/react/theme-reference) are pulled from [Primer Primitives](https://github.com/primer/primitives). When a color variable is deprecated in Primer Primitives, it's important to remove references to that color variable in your application before it's removed from the library.
66

77
## Rule details
88

99
This rule disallows references to color variables that are deprecated in [Primer Primitives](https://github.com/primer/primitives).
1010

11-
1211
👎 Examples of **incorrect** code for this rule:
1312

1413
```jsx
@@ -21,7 +20,7 @@ const SystemPropExample() = () => <Box color="some.deprecated.color">Incorrect</
2120
const SxPropExample() = () => <Box sx={{color: 'some.deprecated.color'}}>Incorrect</Box>
2221

2322
const ThemeGetExample = styled.div`
24-
color: ${themeGet('some.deprecated.color')};
23+
color: ${themeGet('colors.some.deprecated.color')};
2524
`
2625
```
2726

@@ -37,6 +36,17 @@ const SystemPropExample() = () => <Box color="some.color">Incorrect</Box>
3736
const SxPropExample() = () => <Box sx={{color: 'some.color'}}>Incorrect</Box>
3837

3938
const ThemeGetExample = styled.div`
40-
color: ${themeGet('some.color')};
39+
color: ${themeGet('colors.some.color')};
4140
`
4241
```
42+
43+
## Options
44+
45+
- `skipImportCheck` (default: `false`)
46+
47+
By default, the `no-deprecated-colors` rule will only check for deprecated colors used in functions and components that are imported from `@primer/components`. You can disable this behavior by setting `skipImportCheck` to `true`. This is useful for linting custom components that pass color-related props down to Primer React components.
48+
49+
50+
```
51+
"primer-react/no-deprecated-colors": ["warn", {"skipImportCheck": true}]
52+
```

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

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,16 @@ ruleTester.run('no-deprecated-colors', rule, {
4343
}
4444
]
4545
},
46+
{
47+
code: `import {Box} from "../components"; function Example() { return <Box color="text.primary">Hello</Box> }`,
48+
output: `import {Box} from "../components"; function Example() { return <Box color="fg.default">Hello</Box> }`,
49+
options: [{skipImportCheck: true}],
50+
errors: [
51+
{
52+
message: '"text.primary" is deprecated. Use "fg.default" instead.'
53+
}
54+
]
55+
},
4656
{
4757
code: `import Box from '@primer/components/lib-esm/Box'; function Example() { return <Box color="text.primary">Hello</Box> }`,
4858
output: `import Box from '@primer/components/lib-esm/Box'; function Example() { return <Box color="fg.default">Hello</Box> }`,

src/rules/no-deprecated-colors.js

Lines changed: 29 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,28 @@ const styledSystemColorProps = ['color', 'bg', 'backgroundColor', 'borderColor',
66
module.exports = {
77
meta: {
88
type: 'suggestion',
9-
fixable: 'code'
9+
fixable: 'code',
10+
schema: [
11+
{
12+
type: 'object',
13+
properties: {
14+
skipImportCheck: {
15+
type: 'boolean'
16+
}
17+
},
18+
additionalProperties: false
19+
}
20+
]
1021
},
1122
create(context) {
23+
// If `skipImportCheck` is true, this rule will check for deprecated colors
24+
// used in any components (not just ones that are imported from `@primer/components`).
25+
const skipImportCheck = context.options[0] ? context.options[0].skipImportCheck : false
26+
1227
return {
1328
JSXOpeningElement(node) {
1429
// Skip if component was not imported from @primer/components
15-
if (!isPrimerComponent(node.name, context.getScope(node))) {
30+
if (!skipImportCheck && !isPrimerComponent(node.name, context.getScope(node))) {
1631
return
1732
}
1833

@@ -77,7 +92,10 @@ module.exports = {
7792
CallExpression(node) {
7893
// Skip if not calling the `themeGet` or `get` function
7994
// `get` is the internal version of `themeGet` that's used in the primer/react repository
80-
if (!isThemeGet(node.callee, context.getScope(node)) && !isGet(node.callee, context.getScope(node))) {
95+
if (
96+
!isThemeGet(node.callee, context.getScope(node), skipImportCheck) &&
97+
!isGet(node.callee, context.getScope(node))
98+
) {
8199
return
82100
}
83101

@@ -123,11 +141,17 @@ function isPrimerComponent(identifier, scope) {
123141
return isImportedFrom(/^@primer\/components/, identifier, scope)
124142
}
125143

126-
function isThemeGet(identifier, scope) {
127-
return isImportedFrom(/^@primer\/components/, identifier, scope) && identifier.name === 'themeGet'
144+
function isThemeGet(identifier, scope, skipImportCheck = false) {
145+
if (!skipImportCheck) {
146+
return isImportedFrom(/^@primer\/components/, identifier, scope) && identifier.name === 'themeGet'
147+
}
148+
149+
return identifier.name === 'themeGet'
128150
}
129151

152+
// `get` is the internal version of `themeGet` that's used in the primer/react repository.
130153
function isGet(identifier, scope) {
154+
// This is a flaky way to check for the `get` function and should probably be improved.
131155
return isImportedFrom(/^\.\.?\/constants$/, identifier, scope) && identifier.name === 'get'
132156
}
133157

0 commit comments

Comments
 (0)