Skip to content

Commit be67dc2

Browse files
authored
Merge pull request #41 from primer/skip-import-check
Add `skipImportCheck` to `direct-slot-children` rule
2 parents 8041452 + 3d219c2 commit be67dc2

File tree

5 files changed

+63
-5
lines changed

5 files changed

+63
-5
lines changed

docs/rules/direct-slot-children.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,3 +37,10 @@ const App = () => (
3737
</PageLayout>
3838
)
3939
```
40+
41+
## Options
42+
43+
- `skipImportCheck` (default: `false`)
44+
45+
By default, the `direct-slot-children` rule will only check for direct slot children in components that are imported from `@primer/react`. You can disable this behavior by setting `skipImportCheck` to `true`. This is used for internal linting in the [primer/react](https://github.com/prime/react) repository.
46+

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

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,11 @@ 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 'some-library'; <PageLayout.Header>Header</PageLayout.Header>`
18+
`import {PageLayout} from './PageLayout'; <PageLayout.Header>Header</PageLayout.Header>`,
19+
{
20+
code: `import {Foo} from './Foo'; <Foo><div><Foo.Bar></Foo.Bar></div></Foo>`,
21+
options: [{skipImportCheck: true}]
22+
}
1923
],
2024
invalid: [
2125
{
@@ -62,6 +66,16 @@ ruleTester.run('direct-slot-children', rule, {
6266
data: {childName: 'TreeView.LeadingVisual', parentName: 'TreeView.Item'}
6367
}
6468
]
69+
},
70+
{
71+
code: `import {PageLayout} from './PageLayout'; <PageLayout><div><PageLayout.Header>Header</PageLayout.Header></div></PageLayout>`,
72+
options: [{skipImportCheck: true}],
73+
errors: [
74+
{
75+
messageId: 'directSlotChildren',
76+
data: {childName: 'PageLayout.Header', parentName: 'PageLayout'}
77+
}
78+
]
6579
}
6680
]
6781
})

src/rules/__tests__/no-system-props.test.js

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ ruleTester.run('no-system-props', rule, {
2020
`import {ProgressBar} from '@primer/react'; <ProgressBar bg="howdy" />`,
2121
`import {Button} from '@primer/react'; <Button {...someExpression()} />`,
2222
`import {Button} from '@primer/react'; <Button variant="large" />`,
23-
`import {Button} from '@primer/react'; <Button size="large" />`,
23+
`import {Button} from '@primer/react'; <Button size="large" />`
2424
],
2525
invalid: [
2626
{
@@ -144,6 +144,28 @@ ruleTester.run('no-system-props', rule, {
144144
data: {propNames: 'width', componentName: 'Text'}
145145
}
146146
]
147+
},
148+
{
149+
code: `import {Button} from '../Button'; <Button width={200} />`,
150+
options: [{skipImportCheck: true}],
151+
output: `import {Button} from '../Button'; <Button sx={{width: 200}} />`,
152+
errors: [
153+
{
154+
messageId: 'noSystemProps',
155+
data: {propNames: 'width', componentName: 'Button'}
156+
}
157+
]
158+
},
159+
{
160+
code: `import {Foo} from '../Foo'; <Foo width={200} />`,
161+
options: [{skipImportCheck: true}],
162+
output: `import {Foo} from '../Foo'; <Foo sx={{width: 200}} />`,
163+
errors: [
164+
{
165+
messageId: 'noSystemProps',
166+
data: {propNames: 'width', componentName: 'Foo'}
167+
}
168+
]
147169
}
148170
]
149171
})

src/rules/direct-slot-children.js

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,15 @@ const slotChildToParentMap = Object.entries(slotParentToChildMap).reduce((acc, [
2020
module.exports = {
2121
meta: {
2222
type: 'problem',
23-
schema: [],
23+
schema: [
24+
{
25+
properties: {
26+
skipImportCheck: {
27+
type: 'boolean'
28+
}
29+
}
30+
}
31+
],
2432
messages: {
2533
directSlotChildren: '{{childName}} must be a direct child of {{parentName}}.'
2634
}
@@ -30,9 +38,16 @@ module.exports = {
3038
JSXOpeningElement(jsxNode) {
3139
const name = getJSXOpeningElementName(jsxNode)
3240

41+
// If `skipImportCheck` is true, this rule will check for direct slot children
42+
// in any components (not just ones that are imported from `@primer/react`).
43+
const skipImportCheck = context.options[0] ? context.options[0].skipImportCheck : false
44+
3345
// If component is a Primer component and a slot child,
3446
// check if it's a direct child of the slot parent
35-
if (isPrimerComponent(jsxNode.name, context.getScope(jsxNode)) && slotChildToParentMap[name]) {
47+
if (
48+
(skipImportCheck || isPrimerComponent(jsxNode.name, context.getScope(jsxNode))) &&
49+
slotChildToParentMap[name]
50+
) {
3651
const JSXElement = jsxNode.parent
3752
const parent = JSXElement.parent
3853

src/rules/no-system-props.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ module.exports = {
5252
},
5353
create(context) {
5454
// If `skipImportCheck` is true, this rule will check for deprecated styled system props
55-
// used in any components (not just ones that are imported from `@primer/components`).
55+
// used in any components (not just ones that are imported from `@primer/react`).
5656
const skipImportCheck = context.options[0] ? context.options[0].skipImportCheck : false
5757

5858
const includeUtilityComponents = context.options[0] ? context.options[0].includeUtilityComponents : false

0 commit comments

Comments
 (0)