Skip to content

Commit

Permalink
Merge pull request #12 from primer/jfuchs/no-styled-system-props
Browse files Browse the repository at this point in the history
Adds a no-system-props rule
  • Loading branch information
jfuchs authored Oct 1, 2021
2 parents f408f42 + 0555c31 commit e32a1f9
Show file tree
Hide file tree
Showing 12 changed files with 491 additions and 37 deletions.
5 changes: 5 additions & 0 deletions .changeset/gorgeous-games-confess.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'eslint-plugin-primer-react': minor
---

Added a no-system-props rule
40 changes: 40 additions & 0 deletions docs/rules/no-system-props.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
# Disallow use of styled-system props (no-system-colors)

🔧 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.

[Styled-system](https://styled-system.com/table) props are deprecated in Primer components (excluding utility components).

## Rule details

This rule disallows the use of any styled-system prop on Primer components, as the `sx` prop is now the prefered way to apply additional styling.

\*The two non-deprecated utility components (`Box` and `Text`) are allowed to use system props.

👎 Examples of **incorrect** code for this rule:

```jsx
/* eslint primer-react/no-system-props: "error" */
import {Button} from '@primer/components'

<Button width={200} />
<Button width={200} sx={{height: 300}} />
```

👍 Examples of **correct** code for this rule:

```jsx
/* eslint primer-react/no-system-props: "error" */
import {Box, Button, ProgressBar} from '@primer/components'
import {Avatar} from 'some-other-library'
// Non-system props are allowed
<Button someOtherProp="foo" />
// If you need to override styles, use the `sx` prop instead of system props
<Button sx={{mr: 2}} />
// Some component prop names overlap with styled-system prop names.
// These props are still allowed
<ProgressBar bg="success.emphasis" />
// Utility components like Box and Text still accept system props
<Box mr={2} />
// System props passed to non-Primer components are allowed
<Avatar mr={2} />
```
140 changes: 137 additions & 3 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 4 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,9 @@
},
"prettier": "@github/prettier-config",
"dependencies": {
"eslint-traverse": "^1.0.0"
"@styled-system/props": "^5.1.5",
"eslint-traverse": "^1.0.0",
"lodash": "^4.17.21",
"styled-system": "^5.1.5"
}
}
3 changes: 2 additions & 1 deletion src/configs/recommended.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ module.exports = {
},
plugins: ['primer-react'],
rules: {
'primer-react/no-deprecated-colors': 'warn'
'primer-react/no-deprecated-colors': 'warn',
'primer-react/no-system-props': 'warn'
}
}
3 changes: 2 additions & 1 deletion src/index.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
module.exports = {
rules: {
'no-deprecated-colors': require('./rules/no-deprecated-colors')
'no-deprecated-colors': require('./rules/no-deprecated-colors'),
'no-system-props': require('./rules/no-system-props')
},
configs: {
recommended: require('./configs/recommended')
Expand Down
125 changes: 125 additions & 0 deletions src/rules/__tests__/no-system-props.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
const rule = require('../no-system-props')
const {RuleTester} = require('eslint')

const ruleTester = new RuleTester({
parserOptions: {
ecmaVersion: 'latest',
sourceType: 'module',
ecmaFeatures: {
jsx: true
}
}
})

ruleTester.run('no-system-props', rule, {
valid: [
`import {Button} from '@primer/components'; <Button sx={{width: 200}} />`,
`import {Button} from 'coles-cool-design-system'; <Button width={200} />`,
`import {Button} from '@primer/components'; <Button someOtherProp="foo" />`,
`import {Box} from '@primer/components'; <Box width={200} />`,
`import {ProgressBar} from '@primer/components'; <ProgressBar bg="howdy" />`,
`import {Button} from '@primer/components'; <Button {...someExpression()} />`
],
invalid: [
{
code: `import {Button} from '@primer/components'; <Button width={200} />`,
output: `import {Button} from '@primer/components'; <Button sx={{width: 200}} />`,
errors: [
{
messageId: 'noSystemProps',
data: {propNames: 'width', componentName: 'Button'}
}
]
},
{
code: `import {Button} from '@primer/components'; <Button width="200" />`,
output: `import {Button} from '@primer/components'; <Button sx={{width: "200"}} />`,
errors: [
{
messageId: 'noSystemProps',
data: {propNames: 'width', componentName: 'Button'}
}
]
},
{
code: `import {Button} from '@primer/components'; <Button width={"200"} />`,
output: `import {Button} from '@primer/components'; <Button sx={{width: "200"}} />`,
errors: [
{
messageId: 'noSystemProps',
data: {propNames: 'width', componentName: 'Button'}
}
]
},
{
code: `import {Button} from '@primer/components'; <Button width={myWidth} />`,
output: `import {Button} from '@primer/components'; <Button sx={{width: myWidth}} />`,
errors: [
{
messageId: 'noSystemProps',
data: {propNames: 'width', componentName: 'Button'}
}
]
},
{
code: `import {Button} from '@primer/components'; <Button width={200} height={100} />`,
output: `import {Button} from '@primer/components'; <Button sx={{width: 200, height: 100}} />`,
errors: [
{
messageId: 'noSystemProps',
data: {propNames: 'width, height', componentName: 'Button'}
}
]
},
{
code: `import {Button} from '@primer/components'; <Button width={200} sx={{height: 200}} />`,
output: `import {Button} from '@primer/components'; <Button sx={{height: 200, width: 200}} />`,
errors: [
{
messageId: 'noSystemProps',
data: {propNames: 'width', componentName: 'Button'}
}
]
},
{
code: `import {Button} from '@primer/components'; <Button width={200} sx={{width: 300}} />`,
output: `import {Button} from '@primer/components'; <Button sx={{width: 300}} />`,
errors: [
{
messageId: 'noSystemProps',
data: {propNames: 'width', componentName: 'Button'}
}
]
},
{
code: `import {Button} from '@primer/components'; <Button width={200} sx={myStylez} />`,
output: `import {Button} from '@primer/components'; <Button width={200} sx={myStylez} />`,
errors: [
{
messageId: 'noSystemProps',
data: {propNames: 'width', componentName: 'Button'}
}
]
},
{
code: `import {Button} from '@primer/components'; <Button width={200} sx={{...partialStyles, width: 100}} />`,
output: `import {Button} from '@primer/components'; <Button sx={{...partialStyles, width: 100}} />`,
errors: [
{
messageId: 'noSystemProps',
data: {propNames: 'width', componentName: 'Button'}
}
]
},
{
code: `import {Label} from '@primer/components'; <Label width={200} outline />`,
output: `import {Label} from '@primer/components'; <Label outline sx={{width: 200}} />`,
errors: [
{
messageId: 'noSystemProps',
data: {propNames: 'width', componentName: 'Label'}
}
]
}
]
})
Loading

0 comments on commit e32a1f9

Please sign in to comment.