Skip to content

Commit 7524e0c

Browse files
V2dhaljharb
andcommittedJun 29, 2022
[Fix] no-static-element-interactions: allow role assignments using a ternary with literals on both sides
Fixes #766. Co-authored-by: Vividha <rvividha@gmail.com> Co-authored-by: Jordan Harband <ljharb@gmail.com>
1 parent 2362832 commit 7524e0c

File tree

2 files changed

+24
-1
lines changed

2 files changed

+24
-1
lines changed
 

‎__tests__/src/rules/no-static-element-interactions-test.js

+11
Original file line numberDiff line numberDiff line change
@@ -429,6 +429,11 @@ ruleTester.run(`${ruleName}:recommended`, rule, {
429429
// Expressions should pass in recommended mode
430430
{ code: '<div role={ROLE_BUTTON} onClick={() => {}} />;' },
431431
{ code: '<div {...this.props} role={this.props.role} onKeyPress={e => this.handleKeyPress(e)}>{this.props.children}</div>' },
432+
// Specific case for ternary operator with literals on both side
433+
{
434+
code: '<div role={isButton ? "button" : "link"} onClick={() => {}} />;',
435+
options: [{ allowExpressionValues: true }],
436+
},
432437
)
433438
.map(ruleOptionsMapperFactory(recommendedOptions))
434439
.map(parserOptionsMapper),
@@ -465,5 +470,11 @@ ruleTester.run(`${ruleName}:strict`, rule, {
465470
// Expressions should fail in strict mode
466471
{ code: '<div role={ROLE_BUTTON} onClick={() => {}} />;', errors: [expectedError] },
467472
{ code: '<div {...this.props} role={this.props.role} onKeyPress={e => this.handleKeyPress(e)}>{this.props.children}</div>', errors: [expectedError] },
473+
// Specific case for ternary operator with literals on both side
474+
{
475+
code: '<div role={isButton ? "button" : "link"} onClick={() => {}} />;',
476+
options: [{ allowExpressionValues: false }],
477+
errors: [expectedError],
478+
},
468479
).map(parserOptionsMapper),
469480
});

‎src/rules/no-static-element-interactions.js

+13-1
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ export default ({
5858
JSXOpeningElement: (node: JSXOpeningElement) => {
5959
const { attributes } = node;
6060
const type = elementType(node);
61+
6162
const {
6263
allowExpressionValues,
6364
handlers = defaultInteractiveProps,
@@ -99,7 +100,18 @@ export default ({
99100
allowExpressionValues === true
100101
&& isNonLiteralProperty(attributes, 'role')
101102
) {
102-
// This rule has no opinion about non-literal roles.
103+
// Special case if role is assigned using ternary with literals on both side
104+
const roleProp = getProp(attributes, 'role');
105+
if (roleProp && roleProp.type === 'JSXAttribute' && roleProp.value.type === 'JSXExpressionContainer') {
106+
if (roleProp.value.expression.type === 'ConditionalExpression') {
107+
if (
108+
roleProp.value.expression.consequent.type === 'Literal'
109+
&& roleProp.value.expression.alternate.type === 'Literal'
110+
) {
111+
return;
112+
}
113+
}
114+
}
103115
return;
104116
}
105117

0 commit comments

Comments
 (0)
Please sign in to comment.