eslint-plugin-primer-react 8.2.0 → 8.2.1-rc.18197a2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "eslint-plugin-primer-react",
3
- "version": "8.2.0",
3
+ "version": "8.2.1-rc.18197a2",
4
4
  "description": "ESLint rules for Primer React",
5
5
  "main": "src/index.js",
6
6
  "engines": {
@@ -46,7 +46,7 @@
46
46
  "@github/markdownlint-github": "^0.6.3",
47
47
  "@github/prettier-config": "0.0.6",
48
48
  "@types/jest": "^30.0.0",
49
- "@typescript-eslint/rule-tester": "8.42.0",
49
+ "@typescript-eslint/rule-tester": "8.44.0",
50
50
  "eslint": "^9.0.0",
51
51
  "eslint-plugin-eslint-comments": "^3.2.0",
52
52
  "eslint-plugin-filenames": "^1.3.2",
@@ -56,6 +56,26 @@ ruleTester.run('use-styled-react-import', rule, {
56
56
  ],
57
57
  },
58
58
 
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
+
59
79
  // Invalid: ActionList.Item with sx prop and ActionList imported from @primer/react
60
80
  {
61
81
  code: `import { ActionList } from '@primer/react'
@@ -88,8 +88,8 @@ module.exports = {
88
88
  ImportDeclaration(node) {
89
89
  const importSource = node.source.value
90
90
 
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
93
93
  for (const specifier of node.specifiers) {
94
94
  if (specifier.type === 'ImportSpecifier') {
95
95
  const importedName = specifier.imported.name
@@ -98,16 +98,16 @@ module.exports = {
98
98
  styledTypes.has(importedName) ||
99
99
  styledUtilities.has(importedName)
100
100
  ) {
101
- primerReactImports.set(importedName, {node, specifier})
101
+ primerReactImports.set(importedName, {node, specifier, importSource})
102
102
  }
103
103
  }
104
104
  }
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
107
107
  for (const specifier of node.specifiers) {
108
108
  if (specifier.type === 'ImportSpecifier') {
109
109
  const importedName = specifier.imported.name
110
- styledReactImports.set(importedName, {node, specifier})
110
+ styledReactImports.set(importedName, {node, specifier, importSource})
111
111
  }
112
112
  }
113
113
  }
@@ -167,7 +167,7 @@ module.exports = {
167
167
  messageId: 'useStyledReactImport',
168
168
  data: {componentName},
169
169
  fix(fixer) {
170
- const {node: importNode} = importInfo
170
+ const {node: importNode, importSource} = importInfo
171
171
  const changes = importNodeChanges.get(importNode)
172
172
 
173
173
  if (!changes) {
@@ -190,21 +190,24 @@ module.exports = {
190
190
  return !componentsToMove.has(name)
191
191
  })
192
192
 
193
+ // Convert @primer/react path to @primer/styled-react path
194
+ const styledReactPath = importSource.replace('@primer/react', '@primer/styled-react')
195
+
193
196
  // If no components remain, replace with new import directly
194
197
  if (remainingSpecifiers.length === 0) {
195
198
  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}'`))
197
200
  } else {
198
201
  // Otherwise, update the import to only include remaining components
199
202
  const remainingNames = remainingSpecifiers.map(spec => spec.imported.name)
200
203
  fixes.push(
201
- fixer.replaceText(importNode, `import { ${remainingNames.join(', ')} } from '@primer/react'`),
204
+ fixer.replaceText(importNode, `import { ${remainingNames.join(', ')} } from '${importSource}'`),
202
205
  )
203
206
 
204
207
  // Add new styled-react import
205
208
  const movedComponents = changes.toMove.join(', ')
206
209
  fixes.push(
207
- fixer.insertTextAfter(importNode, `\nimport { ${movedComponents} } from '@primer/styled-react'`),
210
+ fixer.insertTextAfter(importNode, `\nimport { ${movedComponents} } from '${styledReactPath}'`),
208
211
  )
209
212
  }
210
213
 
@@ -250,7 +253,7 @@ module.exports = {
250
253
  messageId: 'usePrimerReactImport',
251
254
  data: {componentName},
252
255
  fix(fixer) {
253
- const {node: importNode} = importInfo
256
+ const {node: importNode, importSource} = importInfo
254
257
  const changes = styledReactImportNodeChanges.get(importNode)
255
258
 
256
259
  if (!changes) {
@@ -273,6 +276,9 @@ module.exports = {
273
276
  return !componentsToMove.has(name)
274
277
  })
275
278
 
279
+ // Convert @primer/styled-react path to @primer/react path
280
+ const primerReactPath = importSource.replace('@primer/styled-react', '@primer/react')
281
+
276
282
  // Check if there's an existing primer-react import to merge with
277
283
  const existingPrimerReactImport = Array.from(primerReactImportNodes)[0]
278
284
 
@@ -286,7 +292,7 @@ module.exports = {
286
292
  fixes.push(
287
293
  fixer.replaceText(
288
294
  existingPrimerReactImport,
289
- `import { ${newSpecifiers.join(', ')} } from '@primer/react'`,
295
+ `import { ${newSpecifiers.join(', ')} } from '${primerReactPath}'`,
290
296
  ),
291
297
  )
292
298
  fixes.push(fixer.remove(importNode))
@@ -300,33 +306,29 @@ module.exports = {
300
306
  fixes.push(
301
307
  fixer.replaceText(
302
308
  existingPrimerReactImport,
303
- `import { ${newSpecifiers.join(', ')} } from '@primer/react'`,
309
+ `import { ${newSpecifiers.join(', ')} } from '${primerReactPath}'`,
304
310
  ),
305
311
  )
306
312
 
307
313
  const remainingNames = remainingSpecifiers.map(spec => spec.imported.name)
308
314
  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}'`),
313
316
  )
314
317
  } else if (remainingSpecifiers.length === 0) {
315
318
  // Case: No existing primer-react import, no remaining styled-react imports
316
319
  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}'`))
318
321
  } else {
319
322
  // Case: No existing primer-react import, some styled-react imports remain
320
323
  const remainingNames = remainingSpecifiers.map(spec => spec.imported.name)
321
324
  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}'`),
326
326
  )
327
327
 
328
328
  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
+ )
330
332
  }
331
333
 
332
334
  return fixes
@@ -343,13 +345,16 @@ module.exports = {
343
345
  messageId: 'moveToStyledReact',
344
346
  data: {importName},
345
347
  fix(fixer) {
346
- const {node: importNode, specifier} = importInfo
348
+ const {node: importNode, specifier, importSource} = importInfo
347
349
  const otherSpecifiers = importNode.specifiers.filter(s => s !== specifier)
348
350
 
351
+ // Convert @primer/react path to @primer/styled-react path
352
+ const styledReactPath = importSource.replace('@primer/react', '@primer/styled-react')
353
+
349
354
  // If this is the only import, replace the whole import
350
355
  if (otherSpecifiers.length === 0) {
351
356
  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}'`)
353
358
  }
354
359
 
355
360
  // Otherwise, remove from current import and add new import
@@ -377,7 +382,7 @@ module.exports = {
377
382
  // Add new import
378
383
  const prefix = styledTypes.has(importName) ? 'type ' : ''
379
384
  fixes.push(
380
- fixer.insertTextAfter(importNode, `\nimport { ${prefix}${importName} } from '@primer/styled-react'`),
385
+ fixer.insertTextAfter(importNode, `\nimport { ${prefix}${importName} } from '${styledReactPath}'`),
381
386
  )
382
387
 
383
388
  return fixes