-
Notifications
You must be signed in to change notification settings - Fork 9
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* add no deprecated props rule * update the tests and remove the space after title node is removed * export the rule and add docs * Add new test cases to discuss about the fix * auto fix for JSX expressions * add the rule to readme * add cahngeset * make the rule suggestion
- Loading branch information
1 parent
2f8e27b
commit 15cfbb4
Showing
7 changed files
with
239 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
--- | ||
'eslint-plugin-primer-react': minor | ||
--- | ||
|
||
Add no-deprecated-props rule |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
## Rule Details | ||
|
||
This rule enforces to use the recommended API (`ActionList.GroupHeading`) component over the deprecated prop (`title` prop on `ActionList.Group`) for ActionList component. | ||
|
||
👎 Examples of **incorrect** code for this rule: | ||
|
||
```jsx | ||
/* eslint primer-react/no-deprecated-props: "error" */ | ||
import {ActionList} from '@primer/react' | ||
|
||
const App = () => ( | ||
<ActionList> | ||
<ActionList.Group title="Group heading"> | ||
<ActionList.Item>Item 1</ActionList.Item> | ||
</ActionList.Group> | ||
</ActionList> | ||
) | ||
``` | ||
|
||
👍 Examples of **correct** code for this rule: | ||
|
||
```jsx | ||
/* eslint primer-react/no-deprecated-props: "error" */ | ||
import {ActionList} from '@primer/react' | ||
|
||
const App = () => ( | ||
<ActionList> | ||
<ActionList.Group> | ||
<ActionList.GroupHeading as="h2">Group heading</ActionList.GroupHeading> | ||
<ActionList.Item>Item 1</ActionList.Item> | ||
</ActionList.Group> | ||
</ActionList> | ||
) | ||
``` | ||
|
||
```jsx | ||
/* eslint primer-react/no-deprecated-props: "error" */ | ||
import {ActionList} from '@primer/react' | ||
|
||
const App = () => ( | ||
<ActionList role="lisbox"> | ||
<ActionList.Group> | ||
<ActionList.GroupHeading>Group heading</ActionList.GroupHeading> | ||
<ActionList.Item>Item 1</ActionList.Item> | ||
</ActionList.Group> | ||
</ActionList> | ||
) | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,121 @@ | ||
'use strict' | ||
|
||
const {RuleTester} = require('eslint') | ||
const rule = require('../no-deprecated-props') | ||
|
||
const ruleTester = new RuleTester({ | ||
parserOptions: { | ||
ecmaVersion: 'latest', | ||
sourceType: 'module', | ||
ecmaFeatures: { | ||
jsx: true, | ||
}, | ||
}, | ||
}) | ||
|
||
ruleTester.run('no-deprecated-props', rule, { | ||
valid: [ | ||
`import {ActionList} from '@primer/react'; | ||
<ActionList> | ||
<ActionList.Group> | ||
<ActionList.GroupHeading as="h3">Group heading 1</ActionList.GroupHeading> | ||
<ActionList.Item>Item</ActionList.Item> | ||
</ActionList.Group> | ||
<ActionList.Group> | ||
<ActionList.GroupHeading as="h3">Group heading 2</ActionList.GroupHeading> | ||
<ActionList.Item>Item 2</ActionList.Item> | ||
</ActionList.Group> | ||
</ActionList>`, | ||
`import {ActionList} from '@primer/react'; | ||
<ActionList> | ||
<ActionList.Group> | ||
<ActionList.GroupHeading>Group heading 1</ActionList.GroupHeading> | ||
<ActionList.Item>Item</ActionList.Item> | ||
</ActionList.Group> | ||
<ActionList.Group> | ||
<ActionList.GroupHeading>Group heading 2</ActionList.GroupHeading> | ||
<ActionList.Item>Item 2</ActionList.Item> | ||
</ActionList.Group> | ||
</ActionList>`, | ||
`import {ActionList} from '@primer/react'; | ||
<ActionList> | ||
<ActionList.Group> | ||
<ActionList.GroupHeading as="h3">Group heading</ActionList.GroupHeading> | ||
<ActionList.Item>Item</ActionList.Item> | ||
</ActionList.Group> | ||
<ActionList.Item>Item 2</ActionList.Item> | ||
</ActionList>`, | ||
`import {ActionList} from '@primer/react'; | ||
<ActionList role="listbox"> | ||
<ActionList.Group> | ||
<ActionList.GroupHeading>Group heading</ActionList.GroupHeading> | ||
<ActionList.Item>Item</ActionList.Item> | ||
</ActionList.Group> | ||
<ActionList.Item>Item 2</ActionList.Item> | ||
</ActionList>`, | ||
`import {ActionList} from '@primer/react'; | ||
<ActionList role="menu"> | ||
<ActionList.Item>Item</ActionList.Item> | ||
<ActionList.Group> | ||
<ActionList.GroupHeading>Group heading</ActionList.GroupHeading> | ||
<ActionList.Item>Group item</ActionList.Item> | ||
</ActionList.Group> | ||
</ActionList>`, | ||
], | ||
invalid: [ | ||
{ | ||
code: `<ActionList.Group title="Group heading 1"></ActionList.Group>`, | ||
output: `<ActionList.Group><ActionList.GroupHeading>Group heading 1</ActionList.GroupHeading></ActionList.Group>`, | ||
errors: [ | ||
{ | ||
messageId: 'titlePropDeprecated', | ||
}, | ||
], | ||
}, | ||
{ | ||
code: `<ActionList.Group title="Group heading 1" sx={{padding: 2}}></ActionList.Group>`, | ||
output: `<ActionList.Group sx={{padding: 2}}><ActionList.GroupHeading>Group heading 1</ActionList.GroupHeading></ActionList.Group>`, | ||
errors: [ | ||
{ | ||
messageId: 'titlePropDeprecated', | ||
}, | ||
], | ||
}, | ||
{ | ||
code: `<ActionList.Group variant="filled" title="Group heading 1"></ActionList.Group>`, | ||
output: `<ActionList.Group variant="filled"><ActionList.GroupHeading>Group heading 1</ActionList.GroupHeading></ActionList.Group>`, | ||
errors: [ | ||
{ | ||
messageId: 'titlePropDeprecated', | ||
}, | ||
], | ||
}, | ||
{ | ||
code: `<ActionList.Group title={titleVariable}></ActionList.Group>`, | ||
output: `<ActionList.Group><ActionList.GroupHeading>{titleVariable}</ActionList.GroupHeading></ActionList.Group>`, | ||
errors: [ | ||
{ | ||
messageId: 'titlePropDeprecated', | ||
}, | ||
], | ||
}, | ||
{ | ||
code: `<ActionList.Group title={'Title'}></ActionList.Group>`, | ||
output: `<ActionList.Group><ActionList.GroupHeading>{'Title'}</ActionList.GroupHeading></ActionList.Group>`, | ||
errors: [ | ||
{ | ||
messageId: 'titlePropDeprecated', | ||
}, | ||
], | ||
}, | ||
{ | ||
code: `<ActionList.Group title={condition ? 'Title' : undefined}></ActionList.Group>`, | ||
output: `<ActionList.Group><ActionList.GroupHeading>{condition ? 'Title' : undefined}</ActionList.GroupHeading></ActionList.Group>`, | ||
errors: [ | ||
{ | ||
messageId: 'titlePropDeprecated', | ||
}, | ||
], | ||
}, | ||
], | ||
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
'use strict' | ||
const {getJSXOpeningElementAttribute} = require('../utils/get-jsx-opening-element-attribute') | ||
const {getJSXOpeningElementName} = require('../utils/get-jsx-opening-element-name') | ||
|
||
/** | ||
* @type {import('eslint').Rule.RuleModule} | ||
*/ | ||
module.exports = { | ||
meta: { | ||
type: 'suggestion', | ||
docs: { | ||
description: | ||
'Avoid using deprecated `title` prop on `ActionList.Group` component. Use `ActionList.GroupHeading` instead.', | ||
recommended: true, | ||
url: 'https://primer.style/components/action-list/react/beta#actionlistgroupheading', | ||
}, | ||
fixable: 'code', | ||
schema: [], | ||
messages: { | ||
titlePropDeprecated: 'The `title` prop is deprecated. Please use `ActionList.GroupHeading` instead.', | ||
}, | ||
}, | ||
create(context) { | ||
return { | ||
JSXOpeningElement(node) { | ||
const openingElName = getJSXOpeningElementName(node) | ||
if (openingElName !== 'ActionList.Group') { | ||
return | ||
} | ||
const title = getJSXOpeningElementAttribute(node, 'title') | ||
let groupTitle = '' | ||
if (title !== undefined) { | ||
context.report({ | ||
node, | ||
messageId: 'titlePropDeprecated', | ||
fix(fixer) { | ||
// Group title is a string literal i.e. title="title" | ||
if (title.value.type === 'Literal') { | ||
groupTitle = title.value.value | ||
// Group title is a JSX expression i.e. title={title} | ||
} else if (title.value.type === 'JSXExpressionContainer') { | ||
groupTitle = context.sourceCode.getText(title.value) | ||
} else { | ||
// we don't provide fix for cases where the title prop is not a string literal or JSX expression | ||
return [] | ||
} | ||
const start = title.range[0] | ||
const end = title.range[1] | ||
return [ | ||
fixer.removeRange([start - 1, end]), // remove the space before the title as well | ||
fixer.insertTextAfterRange( | ||
[node.range[1], node.range[1]], | ||
`<ActionList.GroupHeading>${groupTitle}</ActionList.GroupHeading>`, | ||
), | ||
] | ||
}, | ||
}) | ||
} | ||
}, | ||
} | ||
}, | ||
} |