Skip to content

Commit baff792

Browse files
authored
Add no-unnecessary-components (#207)
* Add and enable `no-unnecessary-components` rule * Add documentation * Add `skipImportCheck` option * Add return type annotation * Add changeset
1 parent e2cab87 commit baff792

13 files changed

+906
-47
lines changed

.changeset/kind-schools-retire.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': major
3+
---
4+
5+
[Breaking] Adds `no-unnecessary-components` lint rule and enables it by default. This may raise new (typically autofixable) lint errors in existing codebases.
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
# Disallow unnecessary use of `Box` and `Text` components (no-unnecessary-components)
2+
3+
🔧 The `--fix` option on the [ESLint CLI](https://eslint.org/docs/user-guide/command-line-interface#fixing-problems) can
4+
automatically fix some of the problems reported by this rule.
5+
6+
## Rule details
7+
8+
The [`Box`](https://primer.style/components/box) and [`Text`](https://primer.style/components/text)
9+
Primer React components are utilities that exist solely to provide access to `sx` or styled-system
10+
props.
11+
12+
If these props are not being used, plain HTML element provide better performance, simpler code,
13+
and improved linting support.
14+
15+
This rule is auto-fixable in nearly all cases. Autofixing respects the presence of an `as` prop.
16+
17+
👎 Examples of **incorrect** code for this rule:
18+
19+
```jsx
20+
/* eslint primer-react/no-unnecessary-components: "error" */
21+
import {Box, Text} from '@primer/react'
22+
23+
<Box>Content</Box>
24+
<Box style={{padding: '16px'}} className="danger-box">Content</Box>
25+
<Box as="section">Content</Box>
26+
27+
<Text>Content</Text>
28+
<Text style={{fontSize: '24px'}} className="large-text">Content</Text>
29+
<Text as="p">Content</Text>
30+
```
31+
32+
👍 Examples of **correct** code for this rule:
33+
34+
```jsx
35+
/* eslint primer-react/no-system-props: "error" */
36+
import {Box, Text} from '@primer/react'
37+
38+
// Prefer plain HTML elements (autofixable)
39+
<div>Content</div>
40+
<div style={{padding: '16px'}} className="danger-box">Content</div>
41+
<section>Content</section>
42+
43+
<span>Content</span>
44+
<span style={{fontSize: '24px'}} className="large-text">Content</span>
45+
<p>Content</p>
46+
47+
// sx props are allowed
48+
<Box sx={{p: 2}}>Content</Box>
49+
<Text sx={{mt: 2}} as="p">Content</Text>
50+
51+
// styled-system props are allowed
52+
<Box p={2}>Content</Box>
53+
<Text mt={2} as="p">Content</Text>
54+
```
55+
56+
```jsx
57+
/* eslint primer-react/no-system-props: ["error", {skipImportCheck: false}] */
58+
import {Box, Text} from '@primer/brand'
59+
60+
// Other components with the same name are allowed
61+
<Box>Content</Box>
62+
<Text>Content</Text>
63+
```
64+
65+
## Options
66+
67+
- `skipImportCheck` (default: `false`)
68+
69+
By default, the rule will only check for incorrect uses of `Box` and `Text` components that are are imported from `@primer/react`. You can disable this behavior (checking all components with these names regardless of import source) by setting `skipImportCheck` to `true`.

jest.config.js

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
// @ts-check
2+
3+
/** @type {import('jest').Config} **/
4+
module.exports = {
5+
testEnvironment: 'node',
6+
testMatch: ['**/__tests__/*.test.js'],
7+
}

0 commit comments

Comments
 (0)