diff --git a/.changeset/curvy-pears-perform.md b/.changeset/curvy-pears-perform.md
new file mode 100644
index 00000000..5895b4c9
--- /dev/null
+++ b/.changeset/curvy-pears-perform.md
@@ -0,0 +1,20 @@
+---
+"eslint-plugin-primer-react": minor
+---
+
+Add a `checkAllStrings` option to the `no-deprecated-colors` rule.
+
+If `checkAllStrings` is set to `true`, the `no-deprecated-colors` rule will check for deprecated colors in all strings. This is useful for catching uses of deprecated colors outside system props and the `sx` prop.
+
+ ```js
+ /* eslint primer-react/no-deprecated-colors: ["warn", {"checkAllStrings": true}] */
+ import {Box} from '@primer/components'
+
+ function ExampleComponent() {
+ const styles = {
+ // Enabling `checkAllStrings` will find deprecated colors used like this:
+ color: 'text.primary'
+ }
+ return Hello
+ }
+ ```
diff --git a/docs/rules/no-deprecated-colors.md b/docs/rules/no-deprecated-colors.md
index f85806bb..98468d9f 100644
--- a/docs/rules/no-deprecated-colors.md
+++ b/docs/rules/no-deprecated-colors.md
@@ -19,6 +19,8 @@ const SystemPropExample() = () => Incorrect
const SxPropExample() = () => Incorrect
+const SxPropExample2() = () => `0 1px 2px ${theme.colors.some.deprecated.color}`}}>Incorrect
+
const ThemeGetExample = styled.div`
color: ${themeGet('colors.some.deprecated.color')};
`
@@ -31,9 +33,11 @@ const ThemeGetExample = styled.div`
import {Box, themeGet} from '@primer/components'
import styled from 'styled-components'
-const SystemPropExample() = () => Incorrect
+const SystemPropExample() = () => Correct
+
+const SxPropExample() = () => Correct
-const SxPropExample() = () => Incorrect
+const SxPropExample2() = () => `0 1px 2px ${theme.colors.some.color}`}}>Correct
const ThemeGetExample = styled.div`
color: ${themeGet('colors.some.color')};
@@ -46,7 +50,33 @@ const ThemeGetExample = styled.div`
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.
+ ```js
+ /* eslint primer-react/no-deprecated-colors: ["warn", {"skipImportCheck": true}] */
+ import {Box} from '@primer/components'
+ function MyBox({color, children}) {
+ return {children}
+ }
+
+ function App() {
+ // Enabling `skipImportCheck` will find deprecated colors used like this:
+ return Hello
+ }
```
- "primer-react/no-deprecated-colors": ["warn", {"skipImportCheck": true}]
+
+- `checkAllStrings` (default: `false`)
+
+ If `checkAllStrings` is set to `true`, the `no-deprecated-colors` rule will check for deprecated colors in all strings. This is useful for catching uses of deprecated colors outside system props and the `sx` prop.
+
+ ```js
+ /* eslint primer-react/no-deprecated-colors: ["warn", {"checkAllStrings": true}] */
+ import {Box} from '@primer/components'
+
+ function ExampleComponent() {
+ const styles = {
+ // Enabling `checkAllStrings` will find deprecated colors used like this:
+ color: 'text.primary'
+ }
+ return Hello
+ }
```
diff --git a/src/rules/__tests__/no-deprecated-colors.test.js b/src/rules/__tests__/no-deprecated-colors.test.js
index 9973a599..fdd8ed00 100644
--- a/src/rules/__tests__/no-deprecated-colors.test.js
+++ b/src/rules/__tests__/no-deprecated-colors.test.js
@@ -31,9 +31,20 @@ ruleTester.run('no-deprecated-colors', rule, {
`import {get} from "@other/constants"; get("space.text.primary")`,
`import {Box} from '@primer/components'; Hello`,
`import {Box} from '@primer/components'; Hello`,
- `import {Box} from '@primer/components'; Hello`
+ `import {Box} from '@primer/components'; Hello`,
+ `{color: 'text.primary'}`
],
invalid: [
+ {
+ code: `{color: 'text.primary'}`,
+ output: `{color: "fg.default"}`,
+ options: [{checkAllStrings: true}],
+ errors: [
+ {
+ message: '"text.primary" is deprecated. Use "fg.default" instead.'
+ }
+ ]
+ },
{
code: `import {Box} from "@primer/components"; function Example() { return Hello }`,
output: `import {Box} from "@primer/components"; function Example() { return Hello }`,
diff --git a/src/rules/no-deprecated-colors.js b/src/rules/no-deprecated-colors.js
index d23c068f..c4509ced 100644
--- a/src/rules/no-deprecated-colors.js
+++ b/src/rules/no-deprecated-colors.js
@@ -13,6 +13,9 @@ module.exports = {
properties: {
skipImportCheck: {
type: 'boolean'
+ },
+ checkAllStrings: {
+ type: 'boolean'
}
},
additionalProperties: false
@@ -24,7 +27,17 @@ module.exports = {
// used in any components (not just ones that are imported from `@primer/components`).
const skipImportCheck = context.options[0] ? context.options[0].skipImportCheck : false
+ const checkAllStrings = context.options[0] ? context.options[0].checkAllStrings : false
+
+ // Track visited string literals to avoid reporting the same string multiple times
+ const visitedStrings = new Set()
+
return {
+ Literal(node) {
+ if (checkAllStrings && Object.keys(deprecations).includes(node.value) && !visitedStrings.has(node)) {
+ replaceDeprecatedColor(context, node, node.value)
+ }
+ },
JSXOpeningElement(node) {
// Skip if component was not imported from @primer/components
if (!skipImportCheck && !isPrimerComponent(node.name, context.getScope(node))) {
@@ -50,6 +63,7 @@ module.exports = {
if (styledSystemColorProps.includes(propName) && Object.keys(deprecations).includes(propValue)) {
replaceDeprecatedColor(context, prop.value, propValue)
+ visitedStrings.add(prop.value)
}
}
@@ -86,6 +100,7 @@ module.exports = {
// Check if styled-system color prop is using a deprecated color
if (styledSystemColorProps.includes(propName) && Object.keys(deprecations).includes(propValue)) {
replaceDeprecatedColor(context, attribute.value, propValue)
+ visitedStrings.add(attribute.value)
}
}
},