Skip to content

Commit 7235c3a

Browse files
authored
Merge pull request #43 from primer/fix-direct-slot-children
`direct-slot-children` hot fixes
2 parents 0a845c7 + 943e49a commit 7235c3a

File tree

5 files changed

+21
-6
lines changed

5 files changed

+21
-6
lines changed

.changeset/real-rules-count.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": patch
3+
---
4+
5+
`direct-slot-children` fixes

src/configs/recommended.js

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,14 +8,15 @@ module.exports = {
88
plugins: ['primer-react', 'github'],
99
extends: ['plugin:github/react'],
1010
rules: {
11+
'primer-react/direct-slot-children': 'error',
1112
'primer-react/no-deprecated-colors': 'warn',
1213
'primer-react/no-system-props': 'warn'
1314
},
1415
settings: {
1516
github: {
1617
components: {
17-
Link: { props: { as: { undefined: 'a', 'a': 'a', 'button': 'button'}}},
18-
Button: { default: 'button' },
18+
Link: {props: {as: {undefined: 'a', a: 'a', button: 'button'}}},
19+
Button: {default: 'button'}
1920
}
2021
},
2122
'jsx-a11y': {

src/index.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
module.exports = {
22
rules: {
3+
'direct-slot-children': require('./rules/direct-slot-children'),
34
'no-deprecated-colors': require('./rules/no-deprecated-colors'),
45
'no-system-props': require('./rules/no-system-props')
56
},

src/rules/__tests__/direct-slot-children.test.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ ruleTester.run('direct-slot-children', rule, {
1515
valid: [
1616
`import {PageLayout} from '@primer/react'; <PageLayout><PageLayout.Header>Header</PageLayout.Header><PageLayout.Footer>Footer</PageLayout.Footer></PageLayout>`,
1717
`import {PageLayout} from '@primer/react'; <PageLayout><div><PageLayout.Pane>Header</PageLayout.Pane></div></PageLayout>`,
18+
`import {PageLayout} from '@primer/react'; <PageLayout>{true ? <PageLayout.Header>Header</PageLayout.Header> : null}</PageLayout>`,
1819
`import {PageLayout} from './PageLayout'; <PageLayout.Header>Header</PageLayout.Header>`,
1920
{
2021
code: `import {Foo} from './Foo'; <Foo><div><Foo.Bar></Foo.Bar></div></Foo>`,

src/rules/direct-slot-children.js

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
const {isPrimerComponent} = require('../utils/is-primer-component')
2+
const {last} = require('lodash')
23

34
const slotParentToChildMap = {
45
PageLayout: ['PageLayout.Header', 'PageLayout.Footer'],
@@ -34,6 +35,7 @@ module.exports = {
3435
}
3536
},
3637
create(context) {
38+
const stack = []
3739
return {
3840
JSXOpeningElement(jsxNode) {
3941
const name = getJSXOpeningElementName(jsxNode)
@@ -48,18 +50,23 @@ module.exports = {
4850
(skipImportCheck || isPrimerComponent(jsxNode.name, context.getScope(jsxNode))) &&
4951
slotChildToParentMap[name]
5052
) {
51-
const JSXElement = jsxNode.parent
52-
const parent = JSXElement.parent
53-
5453
const expectedParentName = slotChildToParentMap[name]
55-
if (parent.type !== 'JSXElement' || getJSXOpeningElementName(parent.openingElement) !== expectedParentName) {
54+
const parent = last(stack)
55+
if (parent !== expectedParentName) {
5656
context.report({
5757
node: jsxNode,
5858
messageId: 'directSlotChildren',
5959
data: {childName: name, parentName: expectedParentName}
6060
})
6161
}
6262
}
63+
64+
// Push the current element onto the stack
65+
stack.push(name)
66+
},
67+
JSXClosingElement() {
68+
// Pop the current element off the stack
69+
stack.pop()
6370
}
6471
}
6572
}

0 commit comments

Comments
 (0)