Skip to content

Commit ec3ca30

Browse files
fix attribute checker to only look for in Tooltip
1 parent b584b8a commit ec3ca30

File tree

4 files changed

+49
-15
lines changed

4 files changed

+49
-15
lines changed

src/configs/recommended.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ module.exports = {
1717
'primer-react/new-color-css-vars': 'error',
1818
'primer-react/a11y-explicit-heading': 'error',
1919
'primer-react/new-color-css-vars-have-fallback': 'error',
20+
'primer-react/use-next-tooltip': 'error',
2021
},
2122
settings: {
2223
github: {

src/index.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ module.exports = {
77
'new-color-css-vars': require('./rules/new-color-css-vars'),
88
'a11y-explicit-heading': require('./rules/a11y-explicit-heading'),
99
'new-color-css-vars-have-fallback': require('./rules/new-color-css-vars-have-fallback'),
10+
'use-next-tooltip': require('./rules/use-next-tooltip'),
1011
},
1112
configs: {
1213
recommended: require('./configs/recommended'),

src/rules/__tests__/use-next-tooltip.test.js

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,14 @@ ruleTester.run('use-next-tooltip', rule, {
3838
],
3939
output: `import {ActionList, ActionMenu, Button} from '@primer/react';\nimport {Tooltip} from '@primer/react/experimental';\n<Tooltip text="tooltip text"><Button>Button</Button></Tooltip>`,
4040
},
41+
{
42+
code: `import {ActionList, ActionMenu, Button, Tooltip} from '@primer/react';\n<Tooltip aria-label="tooltip text"><Button aria-label="test">Button</Button></Tooltip>`,
43+
errors: [
44+
{messageId: 'useNextTooltip', line: 1},
45+
{messageId: 'useTextProp', line: 2},
46+
],
47+
output: `import {ActionList, ActionMenu, Button} from '@primer/react';\nimport {Tooltip} from '@primer/react/experimental';\n<Tooltip text="tooltip text"><Button aria-label="test">Button</Button></Tooltip>`,
48+
},
4149
{
4250
code: `import {ActionList, ActionMenu, Tooltip, Button} from '@primer/react';\n<Tooltip aria-label="tooltip text" noDelay={true} wrap={true} align="left"><Button>Button</Button></Tooltip>`,
4351
errors: [
@@ -47,7 +55,7 @@ ruleTester.run('use-next-tooltip', rule, {
4755
{messageId: 'wrapRemoved', line: 2},
4856
{messageId: 'alignRemoved', line: 2},
4957
],
50-
output: `import {ActionList, ActionMenu, Button} from '@primer/react';\nimport {Tooltip} from '@primer/react/experimental';\n<Tooltip text="tooltip text" ><Button>Button</Button></Tooltip>`,
58+
output: `import {ActionList, ActionMenu, Button} from '@primer/react';\nimport {Tooltip} from '@primer/react/experimental';\n<Tooltip text="tooltip text" ><Button>Button</Button></Tooltip>`,
5159
},
5260
],
5361
})

src/rules/use-next-tooltip.js

Lines changed: 38 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
'use strict'
2+
const {getJSXOpeningElementAttribute} = require('../utils/get-jsx-opening-element-attribute')
3+
const {getJSXOpeningElementName} = require('../utils/get-jsx-opening-element-name')
24

35
module.exports = {
46
meta: {
@@ -28,9 +30,7 @@ module.exports = {
2830
specifier => specifier.imported && specifier.imported.name === 'Tooltip',
2931
)
3032

31-
const hasOtherImports = node.specifiers.some(
32-
specifier => specifier.imported && specifier.imported.name !== 'Tooltip',
33-
)
33+
const hasOtherImports = node.specifiers.length > 1
3434
if (!hasTooltip) {
3535
return
3636
}
@@ -46,10 +46,26 @@ module.exports = {
4646
const tooltipSpecifier = node.specifiers.find(
4747
specifier => specifier.imported && specifier.imported.name === 'Tooltip',
4848
)
49+
50+
const tokensToRemove = [' ', ',']
51+
const tooltipIsFirstImport = tooltipSpecifier === node.specifiers[0]
52+
const tooltipIsLastImport = tooltipSpecifier === node.specifiers[node.specifiers.length - 1]
53+
const tooltipIsNotFirstOrLastImport = !tooltipIsFirstImport && !tooltipIsLastImport
54+
55+
const sourceCode = context.getSourceCode()
56+
const canRemoveBefore = tooltipIsNotFirstOrLastImport
57+
? false
58+
: tokensToRemove.includes(sourceCode.getTokenBefore(tooltipSpecifier).value)
59+
const canRemoveAfter = tokensToRemove.includes(sourceCode.getTokenAfter(tooltipSpecifier).value)
60+
const start = canRemoveBefore
61+
? sourceCode.getTokenBefore(tooltipSpecifier).range[0]
62+
: tooltipSpecifier.range[0]
63+
const end = canRemoveAfter
64+
? sourceCode.getTokenAfter(tooltipSpecifier).range[1] + 1
65+
: tooltipSpecifier.range[1]
4966
return [
5067
// remove tooltip specifier and the space and comma after it
51-
fixer.removeRange([tooltipSpecifier.range[0], tooltipSpecifier.range[1] + 2]),
52-
// fixer.remove(tooltipSpecifier),
68+
fixer.removeRange([start, end]),
5369
fixer.insertTextAfterRange(
5470
[node.range[1], node.range[1]],
5571
`\nimport {Tooltip} from '@primer/react/experimental';`,
@@ -59,40 +75,48 @@ module.exports = {
5975
},
6076
})
6177
},
62-
JSXAttribute(node) {
63-
if (node.name.name === 'aria-label') {
78+
JSXOpeningElement(node) {
79+
const openingElName = getJSXOpeningElementName(node)
80+
if (openingElName !== 'Tooltip') {
81+
return
82+
}
83+
const ariaLabel = getJSXOpeningElementAttribute(node, 'aria-label')
84+
if (ariaLabel !== undefined) {
6485
context.report({
6586
node,
6687
messageId: 'useTextProp',
6788
fix(fixer) {
68-
return fixer.replaceText(node.name, 'text')
89+
return fixer.replaceText(ariaLabel.name, 'text')
6990
},
7091
})
7192
}
72-
if (node.name.name === 'noDelay') {
93+
const noDelay = getJSXOpeningElementAttribute(node, 'noDelay')
94+
if (noDelay !== undefined) {
7395
context.report({
7496
node,
7597
messageId: 'noDelayRemoved',
7698
fix(fixer) {
77-
return fixer.remove(node)
99+
return fixer.remove(noDelay)
78100
},
79101
})
80102
}
81-
if (node.name.name === 'wrap') {
103+
const wrap = getJSXOpeningElementAttribute(node, 'wrap')
104+
if (wrap !== undefined) {
82105
context.report({
83106
node,
84107
messageId: 'wrapRemoved',
85108
fix(fixer) {
86-
return fixer.remove(node)
109+
return fixer.remove(wrap)
87110
},
88111
})
89112
}
90-
if (node.name.name === 'align') {
113+
const align = getJSXOpeningElementAttribute(node, 'align')
114+
if (align !== undefined) {
91115
context.report({
92116
node,
93117
messageId: 'alignRemoved',
94118
fix(fixer) {
95-
return fixer.remove(node)
119+
return fixer.remove(align)
96120
},
97121
})
98122
}

0 commit comments

Comments
 (0)