Skip to content

Commit 1e0f943

Browse files
authored
Support @primer/styled-react imports in no-unnecessary-components rule (#474)
* add styled- * add changeset * more tests
1 parent 00674b2 commit 1e0f943

File tree

3 files changed

+93
-3
lines changed

3 files changed

+93
-3
lines changed

.changeset/dark-jobs-type.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+
Fix `no-unnecessary-components` rule to support `@primer/styled-react` imports.

src/rules/__tests__/no-unnecessary-components.test.js

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ const rule = require('../no-unnecessary-components')
77
const {components} = require('../no-unnecessary-components')
88

99
const prcImport = 'import React from "react"; import {Box, Text} from "@primer/react";'
10+
const styledReactImport = 'import React from "react"; import {Box, Text} from "@primer/styled-react";'
1011
const brandImport = 'import React from "react"; import {Box, Text} from "@primer/react-brand";'
1112

1213
/** @param {string} content */
@@ -66,6 +67,26 @@ ruleTester.run('unnecessary-components', rule, {
6667
code: `${prcImport}${stringRecordDeclaration}${jsx(`<${component} {...props}>Hello World</${component}>`)}`,
6768
filename,
6869
},
70+
{
71+
name: `${component} from @primer/styled-react with sx prop`,
72+
code: `${styledReactImport}${jsx(`<${component} sx={{color: "red"}}>Hello World</${component}>`)}`,
73+
filename,
74+
},
75+
{
76+
name: `${component} from @primer/styled-react with any styled-system prop`,
77+
code: `${styledReactImport}${jsx(`<${component} flex="row">Hello World</${component}>`)}`,
78+
filename,
79+
},
80+
{
81+
name: `${component} from @primer/styled-react with spread sx prop`,
82+
code: `${styledReactImport}${sxObjectDeclaration}${jsx(`<${component} {...props}>Hello World</${component}>`)}`,
83+
filename,
84+
},
85+
{
86+
name: `${component} from @primer/styled-react with string index spread props`,
87+
code: `${styledReactImport}${stringRecordDeclaration}${jsx(`<${component} {...props}>Hello World</${component}>`)}`,
88+
filename,
89+
},
6990
]),
7091
{
7192
name: `Text with weight prop`,
@@ -151,5 +172,69 @@ ruleTester.run('unnecessary-components', rule, {
151172
errors: [{messageId}],
152173
options: [{skipImportCheck: true}],
153174
},
175+
{
176+
name: `${component} from @primer/styled-react without any styled-system props`,
177+
code: `${styledReactImport}${jsx(`<${component}>Hello World</${component}>`)}`,
178+
output: `${styledReactImport}${jsx(`<${replacement}>Hello World</${replacement}>`)}`,
179+
errors: [{messageId}],
180+
filename,
181+
},
182+
{
183+
name: `Self-closing ${component} from @primer/styled-react without any styled-system props`,
184+
code: `${styledReactImport}${jsx(`<${component} />`)}`,
185+
output: `${styledReactImport}${jsx(`<${replacement} />`)}`,
186+
errors: [{messageId}],
187+
filename,
188+
},
189+
{
190+
name: `${component} from @primer/styled-react with spread props without sx`,
191+
code: `${styledReactImport}${testIdObjectDeclaration}${jsx(`<${component} {...props}>Hello World</${component}>`)}`,
192+
output: `${styledReactImport}${testIdObjectDeclaration}${jsx(`<${replacement} {...props}>Hello World</${replacement}>`)}`,
193+
errors: [{messageId}],
194+
filename,
195+
},
196+
{
197+
name: `${component} from @primer/styled-react with string element 'as' prop`,
198+
code: `${styledReactImport}${jsx(`<${component} as="code">Hello world</${component}>`)}`,
199+
// There is extra whitespace here we don't worry about since formatters would get rid of it
200+
output: `${styledReactImport}${jsx(`<code >Hello world</code>`)}`,
201+
errors: [{messageId}],
202+
filename,
203+
},
204+
{
205+
name: `${component} from @primer/styled-react with single-character 'as' prop`,
206+
code: `${styledReactImport}${jsx(`<${component} as="p">Hello world</${component}>`)}`,
207+
output: `${styledReactImport}${jsx(`<p >Hello world</p>`)}`,
208+
errors: [{messageId}],
209+
filename,
210+
},
211+
{
212+
name: `${component} from @primer/styled-react with string element 'as' prop surrounded by unnecessary braces`,
213+
code: `${styledReactImport}${jsx(`<${component} as={"code"}>Hello world</${component}>`)}`,
214+
output: `${styledReactImport}${jsx(`<code >Hello world</code>`)}`,
215+
errors: [{messageId}],
216+
filename,
217+
},
218+
{
219+
name: `${component} from @primer/styled-react with component reference 'as' prop`,
220+
code: `${styledReactImport}${componentDeclaration}${jsx(`<${component} as={OtherComponent}>Hello world</${component}>`)}`,
221+
output: `${styledReactImport}${componentDeclaration}${jsx(`<OtherComponent >Hello world</OtherComponent>`)}`,
222+
errors: [{messageId}],
223+
filename,
224+
},
225+
{
226+
name: `${component} from @primer/styled-react with spread 'as' prop`,
227+
code: `${styledReactImport}${asObjectDeclaration}${jsx(`<${component} {...props}>Hello world</${component}>`)}`,
228+
output: null,
229+
errors: [{messageId}],
230+
filename,
231+
},
232+
{
233+
name: `${component} from @primer/styled-react with unusable lowercase reference 'as' prop`,
234+
code: `${styledReactImport}${asConstDeclaration}${jsx(`<${component} as={as}>Hello world</${component}>`)}`,
235+
output: null,
236+
errors: [{messageId}],
237+
filename,
238+
},
154239
]),
155240
})

src/utils/is-primer-component.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
const {isImportedFrom} = require('./is-imported-from')
22

33
/**
4-
* Check if `name` is a JSX component that is imported from `@primer/react` or
5-
* a subpath `@primer/react/*`.
4+
* Check if `name` is a JSX component that is imported from `@primer/react`,
5+
* `@primer/styled-react`, or a subpath of either.
66
* @returns {boolean}
77
*/
88
function isPrimerComponent(name, scope) {
@@ -18,6 +18,6 @@ function isPrimerComponent(name, scope) {
1818
default:
1919
return false
2020
}
21-
return isImportedFrom(/^@primer\/react(?:$|\/)/, identifier, scope)
21+
return isImportedFrom(/^@primer\/(?:styled-)?react(?:$|\/)/, identifier, scope)
2222
}
2323
exports.isPrimerComponent = isPrimerComponent

0 commit comments

Comments
 (0)