eslint-plugin-primer-react 2.0.1 → 2.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,15 @@
|
|
|
1
1
|
# eslint-plugin-primer-react
|
|
2
2
|
|
|
3
|
+
## 2.0.2
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- [#45](https://github.com/primer/eslint-plugin-primer-react/pull/45) [`a39e34d`](https://github.com/primer/eslint-plugin-primer-react/commit/a39e34d26e72cc4b64a35627a6c4f700fae93fe2) Thanks [@colebemis](https://github.com/colebemis)! - More `direct-slot-children` fixes:
|
|
8
|
+
- Fix bug related self-closing JSX tags
|
|
9
|
+
- Allow slot children to accept multiple parents (ex: `ActionList.Item` or `ActionList.LinkItem`)
|
|
10
|
+
- Add `SplitPageLayout` and `NavList` to the slot map
|
|
11
|
+
- Ignore `MarkdownEditor` because it's still a draft
|
|
12
|
+
|
|
3
13
|
## 2.0.1
|
|
4
14
|
|
|
5
15
|
### Patch Changes
|
package/package.json
CHANGED
|
@@ -17,10 +17,12 @@ ruleTester.run('direct-slot-children', rule, {
|
|
|
17
17
|
`import {PageLayout} from '@primer/react'; <PageLayout><div><PageLayout.Pane>Header</PageLayout.Pane></div></PageLayout>`,
|
|
18
18
|
`import {PageLayout} from '@primer/react'; <PageLayout>{true ? <PageLayout.Header>Header</PageLayout.Header> : null}</PageLayout>`,
|
|
19
19
|
`import {PageLayout} from './PageLayout'; <PageLayout.Header>Header</PageLayout.Header>`,
|
|
20
|
-
{
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
}
|
|
20
|
+
`import {FormControl, Radio} from '@primer/react'; <FormControl><Radio value="one" /><FormControl.Label>Choice one</FormControl.Label></FormControl>`,
|
|
21
|
+
`import {ActionList} from '@primer/react';
|
|
22
|
+
<ActionList.Item><ActionList.LeadingVisual> <Avatar src="https://github.com/mona.png" /></ActionList.LeadingVisual>mona<ActionList.Description>Monalisa Octocat</ActionList.Description></ActionList.Item>`,
|
|
23
|
+
`import {ActionList} from '@primer/react';
|
|
24
|
+
<ActionList.LinkItem><ActionList.LeadingVisual></ActionList.LeadingVisual>mona<ActionList.Description>Monalisa Octocat</ActionList.Description></ActionList.LinkItem>`,
|
|
25
|
+
{code: `import {Foo} from './Foo'; <Foo><div><Foo.Bar></Foo.Bar></div></Foo>`, options: [{skipImportCheck: true}]}
|
|
24
26
|
],
|
|
25
27
|
invalid: [
|
|
26
28
|
{
|
|
@@ -32,6 +34,15 @@ ruleTester.run('direct-slot-children', rule, {
|
|
|
32
34
|
}
|
|
33
35
|
]
|
|
34
36
|
},
|
|
37
|
+
{
|
|
38
|
+
code: `import {PageLayout} from '@primer/react'; function Header() { return <PageLayout.Header>Header</PageLayout.Header>; }`,
|
|
39
|
+
errors: [
|
|
40
|
+
{
|
|
41
|
+
messageId: 'directSlotChildren',
|
|
42
|
+
data: {childName: 'PageLayout.Header', parentName: 'PageLayout'}
|
|
43
|
+
}
|
|
44
|
+
]
|
|
45
|
+
},
|
|
35
46
|
{
|
|
36
47
|
code: `import {PageLayout} from '@primer/react/drafts'; <PageLayout.Header>Header</PageLayout.Header>`,
|
|
37
48
|
errors: [
|
|
@@ -77,6 +88,15 @@ ruleTester.run('direct-slot-children', rule, {
|
|
|
77
88
|
data: {childName: 'PageLayout.Header', parentName: 'PageLayout'}
|
|
78
89
|
}
|
|
79
90
|
]
|
|
91
|
+
},
|
|
92
|
+
{
|
|
93
|
+
code: `import {ActionList} from '@primer/react'; <ActionList.Item><div><ActionList.LeadingVisual>Visual</ActionList.LeadingVisual></div></ActionList.Item>`,
|
|
94
|
+
errors: [
|
|
95
|
+
{
|
|
96
|
+
messageId: 'directSlotChildren',
|
|
97
|
+
data: {childName: 'ActionList.LeadingVisual', parentName: 'ActionList.Item or ActionList.LinkItem'}
|
|
98
|
+
}
|
|
99
|
+
]
|
|
80
100
|
}
|
|
81
101
|
]
|
|
82
102
|
})
|
|
@@ -3,17 +3,25 @@ const {last} = require('lodash')
|
|
|
3
3
|
|
|
4
4
|
const slotParentToChildMap = {
|
|
5
5
|
PageLayout: ['PageLayout.Header', 'PageLayout.Footer'],
|
|
6
|
+
SplitPageLayout: ['SplitPageLayout.Header', 'SplitPageLayout.Footer'],
|
|
6
7
|
FormControl: ['FormControl.Label', 'FormControl.Caption', 'FormControl.LeadingVisual', 'FormControl.TrailingVisual'],
|
|
7
|
-
MarkdownEditor: ['MarkdownEditor.Toolbar', 'MarkdownEditor.Actions', 'MarkdownEditor.Label'],
|
|
8
8
|
'ActionList.Item': ['ActionList.LeadingVisual', 'ActionList.TrailingVisual', 'ActionList.Description'],
|
|
9
|
+
'ActionList.LinkItem': ['ActionList.LeadingVisual', 'ActionList.TrailingVisual', 'ActionList.Description'],
|
|
10
|
+
'NavList.Item': ['NavList.LeadingVisual', 'NavList.TrailingVisual'],
|
|
9
11
|
'TreeView.Item': ['TreeView.LeadingVisual', 'TreeView.TrailingVisual'],
|
|
10
12
|
RadioGroup: ['RadioGroup.Label', 'RadioGroup.Caption', 'RadioGroup.Validation'],
|
|
11
13
|
CheckboxGroup: ['CheckboxGroup.Label', 'CheckboxGroup.Caption', 'CheckboxGroup.Validation']
|
|
14
|
+
// Ignore `MarkdownEditor` for now because it's still in drafts
|
|
15
|
+
// MarkdownEditor: ['MarkdownEditor.Toolbar', 'MarkdownEditor.Actions', 'MarkdownEditor.Label'],
|
|
12
16
|
}
|
|
13
17
|
|
|
14
18
|
const slotChildToParentMap = Object.entries(slotParentToChildMap).reduce((acc, [parent, children]) => {
|
|
15
19
|
for (const child of children) {
|
|
16
|
-
acc[child]
|
|
20
|
+
if (acc[child]) {
|
|
21
|
+
acc[child].push(parent)
|
|
22
|
+
} else {
|
|
23
|
+
acc[child] = [parent]
|
|
24
|
+
}
|
|
17
25
|
}
|
|
18
26
|
return acc
|
|
19
27
|
}, {})
|
|
@@ -50,19 +58,24 @@ module.exports = {
|
|
|
50
58
|
(skipImportCheck || isPrimerComponent(jsxNode.name, context.getScope(jsxNode))) &&
|
|
51
59
|
slotChildToParentMap[name]
|
|
52
60
|
) {
|
|
53
|
-
const
|
|
61
|
+
const expectedParentNames = slotChildToParentMap[name]
|
|
54
62
|
const parent = last(stack)
|
|
55
|
-
if (parent
|
|
63
|
+
if (!expectedParentNames.includes(parent)) {
|
|
56
64
|
context.report({
|
|
57
65
|
node: jsxNode,
|
|
58
66
|
messageId: 'directSlotChildren',
|
|
59
|
-
data: {
|
|
67
|
+
data: {
|
|
68
|
+
childName: name,
|
|
69
|
+
parentName: expectedParentNames.length > 1 ? expectedParentNames.join(' or ') : expectedParentNames[0]
|
|
70
|
+
}
|
|
60
71
|
})
|
|
61
72
|
}
|
|
62
73
|
}
|
|
63
74
|
|
|
64
|
-
//
|
|
65
|
-
|
|
75
|
+
// If tag is not self-closing, push it onto the stack
|
|
76
|
+
if (!jsxNode.selfClosing) {
|
|
77
|
+
stack.push(name)
|
|
78
|
+
}
|
|
66
79
|
},
|
|
67
80
|
JSXClosingElement() {
|
|
68
81
|
// Pop the current element off the stack
|