Skip to content

Commit f3e47b1

Browse files
authored
Fix for deprecated and experimental import paths (#410)
* Fix for deprecated and experimental import paths * Update eslint-plugin-primer-react import paths Fixes deprecated and experimental import paths in eslint-plugin-primer-react.
1 parent 14b388e commit f3e47b1

File tree

3 files changed

+56
-26
lines changed

3 files changed

+56
-26
lines changed

.changeset/cyan-carrots-boil.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 for deprecated and experimental import paths

src/rules/__tests__/use-styled-react-import.test.js

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,26 @@ ruleTester.run('use-styled-react-import', rule, {
5656
],
5757
},
5858

59+
// Invalid: Imports from /experimental and /deprecated paths
60+
{
61+
code: `import { Button } from '@primer/react/experimental'
62+
import { Box } from '@primer/react/deprecated'
63+
const Component = () => <Box sx={{ color: 'red' }}><Button sx={{ margin: 2 }}>Click me</Button></Box>`,
64+
output: `import { Button } from '@primer/styled-react/experimental'
65+
import { Box } from '@primer/styled-react/deprecated'
66+
const Component = () => <Box sx={{ color: 'red' }}><Button sx={{ margin: 2 }}>Click me</Button></Box>`,
67+
errors: [
68+
{
69+
messageId: 'useStyledReactImport',
70+
data: {componentName: 'Button'},
71+
},
72+
{
73+
messageId: 'useStyledReactImport',
74+
data: {componentName: 'Box'},
75+
},
76+
],
77+
},
78+
5979
// Invalid: ActionList.Item with sx prop and ActionList imported from @primer/react
6080
{
6181
code: `import { ActionList } from '@primer/react'

src/rules/use-styled-react-import.js

Lines changed: 31 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -88,8 +88,8 @@ module.exports = {
8888
ImportDeclaration(node) {
8989
const importSource = node.source.value
9090

91-
if (importSource === '@primer/react') {
92-
// Track imports from @primer/react
91+
if (importSource === '@primer/react' || importSource.startsWith('@primer/react/')) {
92+
// Track imports from @primer/react and its subpaths
9393
for (const specifier of node.specifiers) {
9494
if (specifier.type === 'ImportSpecifier') {
9595
const importedName = specifier.imported.name
@@ -98,16 +98,16 @@ module.exports = {
9898
styledTypes.has(importedName) ||
9999
styledUtilities.has(importedName)
100100
) {
101-
primerReactImports.set(importedName, {node, specifier})
101+
primerReactImports.set(importedName, {node, specifier, importSource})
102102
}
103103
}
104104
}
105-
} else if (importSource === '@primer/styled-react') {
106-
// Track what's imported from styled-react
105+
} else if (importSource === '@primer/styled-react' || importSource.startsWith('@primer/styled-react/')) {
106+
// Track what's imported from styled-react and its subpaths
107107
for (const specifier of node.specifiers) {
108108
if (specifier.type === 'ImportSpecifier') {
109109
const importedName = specifier.imported.name
110-
styledReactImports.set(importedName, {node, specifier})
110+
styledReactImports.set(importedName, {node, specifier, importSource})
111111
}
112112
}
113113
}
@@ -167,7 +167,7 @@ module.exports = {
167167
messageId: 'useStyledReactImport',
168168
data: {componentName},
169169
fix(fixer) {
170-
const {node: importNode} = importInfo
170+
const {node: importNode, importSource} = importInfo
171171
const changes = importNodeChanges.get(importNode)
172172

173173
if (!changes) {
@@ -190,21 +190,24 @@ module.exports = {
190190
return !componentsToMove.has(name)
191191
})
192192

193+
// Convert @primer/react path to @primer/styled-react path
194+
const styledReactPath = importSource.replace('@primer/react', '@primer/styled-react')
195+
193196
// If no components remain, replace with new import directly
194197
if (remainingSpecifiers.length === 0) {
195198
const movedComponents = changes.toMove.join(', ')
196-
fixes.push(fixer.replaceText(importNode, `import { ${movedComponents} } from '@primer/styled-react'`))
199+
fixes.push(fixer.replaceText(importNode, `import { ${movedComponents} } from '${styledReactPath}'`))
197200
} else {
198201
// Otherwise, update the import to only include remaining components
199202
const remainingNames = remainingSpecifiers.map(spec => spec.imported.name)
200203
fixes.push(
201-
fixer.replaceText(importNode, `import { ${remainingNames.join(', ')} } from '@primer/react'`),
204+
fixer.replaceText(importNode, `import { ${remainingNames.join(', ')} } from '${importSource}'`),
202205
)
203206

204207
// Add new styled-react import
205208
const movedComponents = changes.toMove.join(', ')
206209
fixes.push(
207-
fixer.insertTextAfter(importNode, `\nimport { ${movedComponents} } from '@primer/styled-react'`),
210+
fixer.insertTextAfter(importNode, `\nimport { ${movedComponents} } from '${styledReactPath}'`),
208211
)
209212
}
210213

@@ -250,7 +253,7 @@ module.exports = {
250253
messageId: 'usePrimerReactImport',
251254
data: {componentName},
252255
fix(fixer) {
253-
const {node: importNode} = importInfo
256+
const {node: importNode, importSource} = importInfo
254257
const changes = styledReactImportNodeChanges.get(importNode)
255258

256259
if (!changes) {
@@ -273,6 +276,9 @@ module.exports = {
273276
return !componentsToMove.has(name)
274277
})
275278

279+
// Convert @primer/styled-react path to @primer/react path
280+
const primerReactPath = importSource.replace('@primer/styled-react', '@primer/react')
281+
276282
// Check if there's an existing primer-react import to merge with
277283
const existingPrimerReactImport = Array.from(primerReactImportNodes)[0]
278284

@@ -286,7 +292,7 @@ module.exports = {
286292
fixes.push(
287293
fixer.replaceText(
288294
existingPrimerReactImport,
289-
`import { ${newSpecifiers.join(', ')} } from '@primer/react'`,
295+
`import { ${newSpecifiers.join(', ')} } from '${primerReactPath}'`,
290296
),
291297
)
292298
fixes.push(fixer.remove(importNode))
@@ -300,33 +306,29 @@ module.exports = {
300306
fixes.push(
301307
fixer.replaceText(
302308
existingPrimerReactImport,
303-
`import { ${newSpecifiers.join(', ')} } from '@primer/react'`,
309+
`import { ${newSpecifiers.join(', ')} } from '${primerReactPath}'`,
304310
),
305311
)
306312

307313
const remainingNames = remainingSpecifiers.map(spec => spec.imported.name)
308314
fixes.push(
309-
fixer.replaceText(
310-
importNode,
311-
`import { ${remainingNames.join(', ')} } from '@primer/styled-react'`,
312-
),
315+
fixer.replaceText(importNode, `import { ${remainingNames.join(', ')} } from '${importSource}'`),
313316
)
314317
} else if (remainingSpecifiers.length === 0) {
315318
// Case: No existing primer-react import, no remaining styled-react imports
316319
const movedComponents = changes.toMove.join(', ')
317-
fixes.push(fixer.replaceText(importNode, `import { ${movedComponents} } from '@primer/react'`))
320+
fixes.push(fixer.replaceText(importNode, `import { ${movedComponents} } from '${primerReactPath}'`))
318321
} else {
319322
// Case: No existing primer-react import, some styled-react imports remain
320323
const remainingNames = remainingSpecifiers.map(spec => spec.imported.name)
321324
fixes.push(
322-
fixer.replaceText(
323-
importNode,
324-
`import { ${remainingNames.join(', ')} } from '@primer/styled-react'`,
325-
),
325+
fixer.replaceText(importNode, `import { ${remainingNames.join(', ')} } from '${importSource}'`),
326326
)
327327

328328
const movedComponents = changes.toMove.join(', ')
329-
fixes.push(fixer.insertTextAfter(importNode, `\nimport { ${movedComponents} } from '@primer/react'`))
329+
fixes.push(
330+
fixer.insertTextAfter(importNode, `\nimport { ${movedComponents} } from '${primerReactPath}'`),
331+
)
330332
}
331333

332334
return fixes
@@ -343,13 +345,16 @@ module.exports = {
343345
messageId: 'moveToStyledReact',
344346
data: {importName},
345347
fix(fixer) {
346-
const {node: importNode, specifier} = importInfo
348+
const {node: importNode, specifier, importSource} = importInfo
347349
const otherSpecifiers = importNode.specifiers.filter(s => s !== specifier)
348350

351+
// Convert @primer/react path to @primer/styled-react path
352+
const styledReactPath = importSource.replace('@primer/react', '@primer/styled-react')
353+
349354
// If this is the only import, replace the whole import
350355
if (otherSpecifiers.length === 0) {
351356
const prefix = styledTypes.has(importName) ? 'type ' : ''
352-
return fixer.replaceText(importNode, `import { ${prefix}${importName} } from '@primer/styled-react'`)
357+
return fixer.replaceText(importNode, `import { ${prefix}${importName} } from '${styledReactPath}'`)
353358
}
354359

355360
// Otherwise, remove from current import and add new import
@@ -377,7 +382,7 @@ module.exports = {
377382
// Add new import
378383
const prefix = styledTypes.has(importName) ? 'type ' : ''
379384
fixes.push(
380-
fixer.insertTextAfter(importNode, `\nimport { ${prefix}${importName} } from '@primer/styled-react'`),
385+
fixer.insertTextAfter(importNode, `\nimport { ${prefix}${importName} } from '${styledReactPath}'`),
381386
)
382387

383388
return fixes

0 commit comments

Comments
 (0)