Skip to content

Commit

Permalink
Merge pull request #43 from primer/fix-direct-slot-children
Browse files Browse the repository at this point in the history
`direct-slot-children` hot fixes
  • Loading branch information
colebemis authored Mar 22, 2023
2 parents 0a845c7 + 943e49a commit 7235c3a
Show file tree
Hide file tree
Showing 5 changed files with 21 additions and 6 deletions.
5 changes: 5 additions & 0 deletions .changeset/real-rules-count.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"eslint-plugin-primer-react": patch
---

`direct-slot-children` fixes
5 changes: 3 additions & 2 deletions src/configs/recommended.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,15 @@ module.exports = {
plugins: ['primer-react', 'github'],
extends: ['plugin:github/react'],
rules: {
'primer-react/direct-slot-children': 'error',
'primer-react/no-deprecated-colors': 'warn',
'primer-react/no-system-props': 'warn'
},
settings: {
github: {
components: {
Link: { props: { as: { undefined: 'a', 'a': 'a', 'button': 'button'}}},
Button: { default: 'button' },
Link: {props: {as: {undefined: 'a', a: 'a', button: 'button'}}},
Button: {default: 'button'}
}
},
'jsx-a11y': {
Expand Down
1 change: 1 addition & 0 deletions src/index.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
module.exports = {
rules: {
'direct-slot-children': require('./rules/direct-slot-children'),
'no-deprecated-colors': require('./rules/no-deprecated-colors'),
'no-system-props': require('./rules/no-system-props')
},
Expand Down
1 change: 1 addition & 0 deletions src/rules/__tests__/direct-slot-children.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ ruleTester.run('direct-slot-children', rule, {
valid: [
`import {PageLayout} from '@primer/react'; <PageLayout><PageLayout.Header>Header</PageLayout.Header><PageLayout.Footer>Footer</PageLayout.Footer></PageLayout>`,
`import {PageLayout} from '@primer/react'; <PageLayout><div><PageLayout.Pane>Header</PageLayout.Pane></div></PageLayout>`,
`import {PageLayout} from '@primer/react'; <PageLayout>{true ? <PageLayout.Header>Header</PageLayout.Header> : null}</PageLayout>`,
`import {PageLayout} from './PageLayout'; <PageLayout.Header>Header</PageLayout.Header>`,
{
code: `import {Foo} from './Foo'; <Foo><div><Foo.Bar></Foo.Bar></div></Foo>`,
Expand Down
15 changes: 11 additions & 4 deletions src/rules/direct-slot-children.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
const {isPrimerComponent} = require('../utils/is-primer-component')
const {last} = require('lodash')

const slotParentToChildMap = {
PageLayout: ['PageLayout.Header', 'PageLayout.Footer'],
Expand Down Expand Up @@ -34,6 +35,7 @@ module.exports = {
}
},
create(context) {
const stack = []
return {
JSXOpeningElement(jsxNode) {
const name = getJSXOpeningElementName(jsxNode)
Expand All @@ -48,18 +50,23 @@ module.exports = {
(skipImportCheck || isPrimerComponent(jsxNode.name, context.getScope(jsxNode))) &&
slotChildToParentMap[name]
) {
const JSXElement = jsxNode.parent
const parent = JSXElement.parent

const expectedParentName = slotChildToParentMap[name]
if (parent.type !== 'JSXElement' || getJSXOpeningElementName(parent.openingElement) !== expectedParentName) {
const parent = last(stack)
if (parent !== expectedParentName) {
context.report({
node: jsxNode,
messageId: 'directSlotChildren',
data: {childName: name, parentName: expectedParentName}
})
}
}

// Push the current element onto the stack
stack.push(name)
},
JSXClosingElement() {
// Pop the current element off the stack
stack.pop()
}
}
}
Expand Down

0 comments on commit 7235c3a

Please sign in to comment.