Skip to content

Commit

Permalink
Add no-unnecessary-components (#207)
Browse files Browse the repository at this point in the history
* Add and enable `no-unnecessary-components` rule

* Add documentation

* Add `skipImportCheck` option

* Add return type annotation

* Add changeset
  • Loading branch information
iansan5653 authored Aug 23, 2024
1 parent e2cab87 commit baff792
Show file tree
Hide file tree
Showing 13 changed files with 906 additions and 47 deletions.
5 changes: 5 additions & 0 deletions .changeset/kind-schools-retire.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'eslint-plugin-primer-react': major
---

[Breaking] Adds `no-unnecessary-components` lint rule and enables it by default. This may raise new (typically autofixable) lint errors in existing codebases.
69 changes: 69 additions & 0 deletions docs/rules/no-unnecessary-components.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
# Disallow unnecessary use of `Box` and `Text` components (no-unnecessary-components)

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

## Rule details

The [`Box`](https://primer.style/components/box) and [`Text`](https://primer.style/components/text)
Primer React components are utilities that exist solely to provide access to `sx` or styled-system
props.

If these props are not being used, plain HTML element provide better performance, simpler code,
and improved linting support.

This rule is auto-fixable in nearly all cases. Autofixing respects the presence of an `as` prop.

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

```jsx
/* eslint primer-react/no-unnecessary-components: "error" */
import {Box, Text} from '@primer/react'

<Box>Content</Box>
<Box style={{padding: '16px'}} className="danger-box">Content</Box>
<Box as="section">Content</Box>

<Text>Content</Text>
<Text style={{fontSize: '24px'}} className="large-text">Content</Text>
<Text as="p">Content</Text>
```

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

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

// Prefer plain HTML elements (autofixable)
<div>Content</div>
<div style={{padding: '16px'}} className="danger-box">Content</div>
<section>Content</section>

<span>Content</span>
<span style={{fontSize: '24px'}} className="large-text">Content</span>
<p>Content</p>

// sx props are allowed
<Box sx={{p: 2}}>Content</Box>
<Text sx={{mt: 2}} as="p">Content</Text>

// styled-system props are allowed
<Box p={2}>Content</Box>
<Text mt={2} as="p">Content</Text>
```

```jsx
/* eslint primer-react/no-system-props: ["error", {skipImportCheck: false}] */
import {Box, Text} from '@primer/brand'

// Other components with the same name are allowed
<Box>Content</Box>
<Text>Content</Text>
```

## Options

- `skipImportCheck` (default: `false`)

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`.
7 changes: 7 additions & 0 deletions jest.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
// @ts-check

/** @type {import('jest').Config} **/
module.exports = {
testEnvironment: 'node',
testMatch: ['**/__tests__/*.test.js'],
}
Loading

0 comments on commit baff792

Please sign in to comment.