Skip to content

Commit ca2c8e1

Browse files
authored
Merge branch 'main' into dependabot/npm_and_yarn/markdownlint-cli2-0.17.2
2 parents b4c72b3 + 7edce9c commit ca2c8e1

9 files changed

+406
-216
lines changed

.changeset/wicked-areas-jog.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': minor
3+
---
4+
5+
Add `no-deprecated-experimental-components` rule

.github/workflows/release_tracking.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,6 @@ on:
1414
jobs:
1515
release-tracking:
1616
name: Release Tracking
17-
uses: primer/.github/.github/workflows/release_tracking.yml@v2.1.1
17+
uses: primer/.github/.github/workflows/release_tracking.yml@v2.2.0
1818
secrets:
1919
datadog_api_key: ${{ secrets.DATADOG_API_KEY }}

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,3 +40,4 @@ ESLint rules for Primer React
4040
- [a11y-link-in-text-block](https://github.com/primer/eslint-plugin-primer-react/blob/main/docs/rules/a11y-link-in-text-block.md)
4141
- [a11y-remove-disable-tooltip](https://github.com/primer/eslint-plugin-primer-react/blob/main/docs/rules/a11y-remove-disable-tooltip.md)
4242
- [a11y-use-accessible-tooltip](https://github.com/primer/eslint-plugin-primer-react/blob/main/docs/rules/a11y-use-accessible-tooltip.md)
43+
- [no-deprecated-experimental-components](https://github.com/primer/eslint-plugin-primer-react/blob/main/docs/rules/no-deprecated-experimental-components.md)
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
# No deprecated experimental components
2+
3+
## Rule Details
4+
5+
This rule discourages the usage of specific imports from `@primer/react/experimental`.
6+
7+
👎 Examples of **incorrect** code for this rule
8+
9+
```jsx
10+
import {SelectPanel} from '@primer/react/experimental'
11+
12+
function ExampleComponent() {
13+
return <SelectPanel />
14+
}
15+
```
16+
17+
👍 Examples of **correct** code for this rule:
18+
19+
You can satisfy the rule by either converting to the non-experimental version:
20+
21+
```jsx
22+
import {SelectPanel} from '@primer/react'
23+
24+
function ExampleComponent() {
25+
return <SelectPanel />
26+
}
27+
```
28+
29+
Or by removing usage of the component.

package-lock.json

Lines changed: 257 additions & 215 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/configs/recommended.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ module.exports = {
1212
rules: {
1313
'primer-react/direct-slot-children': 'error',
1414
'primer-react/no-system-props': 'warn',
15+
'primer-react/no-deprecated-experimental-components': 'warn',
1516
'primer-react/a11y-tooltip-interactive-trigger': 'error',
1617
'primer-react/new-color-css-vars': 'error',
1718
'primer-react/a11y-explicit-heading': 'error',

src/index.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ module.exports = {
33
'direct-slot-children': require('./rules/direct-slot-children'),
44
'no-deprecated-entrypoints': require('./rules/no-deprecated-entrypoints'),
55
'no-system-props': require('./rules/no-system-props'),
6+
'no-deprecated-experimental-components': require('./rules/no-deprecated-experimental-components'),
67
'a11y-tooltip-interactive-trigger': require('./rules/a11y-tooltip-interactive-trigger'),
78
'new-color-css-vars': require('./rules/new-color-css-vars'),
89
'a11y-explicit-heading': require('./rules/a11y-explicit-heading'),
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
'use strict'
2+
3+
const {RuleTester} = require('eslint')
4+
const rule = require('../no-deprecated-experimental-components')
5+
6+
const ruleTester = new RuleTester({
7+
parserOptions: {
8+
ecmaVersion: 'latest',
9+
sourceType: 'module',
10+
ecmaFeatures: {
11+
jsx: true,
12+
},
13+
},
14+
})
15+
16+
ruleTester.run('no-deprecated-experimental-components', rule, {
17+
valid: [
18+
{
19+
code: `import {SelectPanel} from '@primer/react'`,
20+
},
21+
{
22+
code: `import {DataTable} from '@primer/react/experimental'`,
23+
},
24+
{
25+
code: `import {DataTable, ActionBar} from '@primer/react/experimental'`,
26+
},
27+
],
28+
invalid: [
29+
// Single experimental import
30+
{
31+
code: `import {SelectPanel} from '@primer/react/experimental'`,
32+
errors: [
33+
'SelectPanel is deprecated. Please import from the stable entrypoint (@primer/react) if available, or check https://primer.style/product/components/ for alternative components.',
34+
],
35+
},
36+
// Multiple experimental import
37+
{
38+
code: `import {SelectPanel, DataTable, ActionBar} from '@primer/react/experimental'`,
39+
errors: [
40+
'SelectPanel is deprecated. Please import from the stable entrypoint (@primer/react) if available, or check https://primer.style/product/components/ for alternative components.',
41+
],
42+
},
43+
],
44+
})
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
'use strict'
2+
3+
const url = require('../url')
4+
5+
const components = [
6+
{
7+
identifier: 'SelectPanel',
8+
entrypoint: '@primer/react/experimental',
9+
},
10+
]
11+
12+
const entrypoints = new Map()
13+
14+
for (const component of components) {
15+
if (!entrypoints.has(component.entrypoint)) {
16+
entrypoints.set(component.entrypoint, new Set())
17+
}
18+
entrypoints.get(component.entrypoint).add(component.identifier)
19+
}
20+
21+
/**
22+
* @type {import('eslint').Rule.RuleModule}
23+
*/
24+
module.exports = {
25+
meta: {
26+
type: 'problem',
27+
docs: {
28+
description: 'Use a stable component from the `@primer/react` entrypoint, or check the docs for alternatives',
29+
recommended: true,
30+
url: url(module),
31+
},
32+
fixable: true,
33+
schema: [],
34+
},
35+
create(context) {
36+
return {
37+
ImportDeclaration(node) {
38+
if (!entrypoints.has(node.source.value)) {
39+
return
40+
}
41+
42+
const entrypoint = entrypoints.get(node.source.value)
43+
44+
const experimental = node.specifiers.filter(specifier => {
45+
return entrypoint.has(specifier.imported.name)
46+
})
47+
48+
const components = experimental.map(specifier => specifier.imported.name)
49+
50+
if (experimental.length === 0) {
51+
return
52+
}
53+
54+
if (experimental.length > 0) {
55+
const message = `${components.join(', ')} ${
56+
components.length > 1 ? 'are' : 'is'
57+
} deprecated. Please import from the stable entrypoint (@primer/react) if available, or check https://primer.style/product/components/ for alternative components.`
58+
59+
context.report({
60+
node,
61+
message,
62+
})
63+
}
64+
},
65+
}
66+
},
67+
}

0 commit comments

Comments
 (0)