Skip to content

Commit 2f8f9c4

Browse files
authored
Merge pull request #73 from primer/tylerjdev/tooltip-interactive-jsx-fix
Fix for `nonInteractiveLink` rule
2 parents e008dbc + 9e1bd45 commit 2f8f9c4

File tree

5 files changed

+44
-3
lines changed

5 files changed

+44
-3
lines changed

.changeset/loud-bears-wave.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
---
2+
'eslint-plugin-primer-react': patch
3+
---
4+
5+
* Fixes `nonInteractiveLink` rule for links that pass values through JSX rather than a string
6+
* Adds optional chaining to `getJSXOpeningElementAttribute` to avoid error when no `name` is present

src/rules/__tests__/a11y-explicit-heading.test.js

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,15 @@ ruleTester.run('a11y-explicit-heading', rule, {
3434
const args = {};
3535
<Heading as="h2" {...args}>Heading level 2</Heading>
3636
`,
37+
`
38+
import {Heading} from '@primer/react';
39+
<Heading
40+
{...someProps}
41+
as="h3"
42+
>
43+
Passed spread props
44+
</Heading>
45+
`
3746

3847
],
3948
invalid: [

src/rules/__tests__/a11y-tooltip-interactive-trigger.test.js

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,22 @@ ruleTester.run('non-interactive-tooltip-trigger', rule, {
5151
`import {Tooltip, Link} from '@primer/react';
5252
<Tooltip aria-label="Supplementary text" direction="e">
5353
<Link href="https://github.com">Link</Link>
54-
</Tooltip>`
54+
</Tooltip>`,
55+
`
56+
import {Tooltip, Link} from '@primer/react';
57+
<Tooltip aria-label={avatar.avatarName} direction="e">
58+
<Link href={avatar.avatarLink} underline={true}>
59+
User avatar
60+
</Link>
61+
</Tooltip>` ,
62+
`
63+
import {Tooltip, Link} from '@primer/react';
64+
<Tooltip aria-label="product" direction="e">
65+
<Link href={productLink}>
66+
Product
67+
</Link>
68+
</Tooltip>
69+
`
5570
],
5671
invalid: [
5772
{

src/rules/a11y-tooltip-interactive-trigger.js

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
const {getPropValue, propName} = require('jsx-ast-utils')
12
const {isPrimerComponent} = require('../utils/is-primer-component')
23
const {getJSXOpeningElementName} = require('../utils/get-jsx-opening-element-name')
34
const {getJSXOpeningElementAttribute} = require('../utils/get-jsx-opening-element-attribute')
@@ -21,11 +22,21 @@ const isAnchorTag = el => {
2122
return openingEl === 'a' || openingEl.toLowerCase() === 'link'
2223
}
2324

25+
const isJSXValue = (attributes) => {
26+
const node = attributes.find(attribute => propName(attribute) === 'href');
27+
const isJSXExpression = node.value.type === 'JSXExpressionContainer' && node
28+
&& typeof getPropValue(node) === 'string';
29+
30+
return isJSXExpression
31+
}
32+
2433
const isInteractiveAnchor = child => {
2534
const hasHref = getJSXOpeningElementAttribute(child.openingElement, 'href')
2635
if (!hasHref) return false
2736
const href = getJSXOpeningElementAttribute(child.openingElement, 'href').value.value
28-
const isAnchorInteractive = typeof href === 'string' && href !== ''
37+
const hasJSXValue = isJSXValue(child.openingElement.attributes);
38+
const isAnchorInteractive = (typeof href === 'string' && href !== '' || hasJSXValue)
39+
2940
return isAnchorInteractive
3041
}
3142

src/utils/get-jsx-opening-element-attribute.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
function getJSXOpeningElementAttribute(openingEl, name) {
22
const attributes = openingEl.attributes
33
const attribute = attributes.find(attribute => {
4-
return attribute.name.name === name
4+
return attribute.name && attribute.name.name === name
55
})
66

77
return attribute

0 commit comments

Comments
 (0)