Skip to content

Commit 307e4e8

Browse files
committed
Treat <a /> as a static element
1 parent cbdfeb8 commit 307e4e8

7 files changed

+16
-14
lines changed

__mocks__/genInteractives.js

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,6 @@ const interactiveElementsMap = {
4949
};
5050

5151
const nonInteractiveElementsMap = {
52-
a: [],
5352
area: [],
5453
article: [],
5554
dd: [],

__tests__/src/rules/no-interactive-element-to-noninteractive-role-test.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,8 @@ ruleTester.run('no-interactive-element-to-noninteractive-role', rule, {
6868
{ code: '<textarea className="foo" role="button" />' },
6969
{ code: '<tr role="button" />;' },
7070
/* HTML elements with neither an interactive or non-interactive valence (static) */
71+
{ code: '<a role="button" />' },
72+
{ code: '<a role="button" />;' },
7173
{ code: '<acronym role="button" />;' },
7274
{ code: '<address role="button" />;' },
7375
{ code: '<applet role="button" />;' },
@@ -217,8 +219,6 @@ ruleTester.run('no-interactive-element-to-noninteractive-role', rule, {
217219
/* HTML elements with an inherent, non-interactive role, assigned an
218220
* interactive role. */
219221
{ code: '<main role="button" />;' },
220-
{ code: '<a role="button" />' },
221-
{ code: '<a role="button" />;' },
222222
{ code: '<area role="button" />;' },
223223
{ code: '<article role="button" />;' },
224224
{ code: '<article role="button" />;' },

__tests__/src/rules/no-noninteractive-element-interactions-test.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,8 @@ ruleTester.run('no-noninteractive-element-handlers', rule, {
5656
{ code: '<input type="week" onClick={() => void 0} />' },
5757
{ code: '<input type="hidden" onClick={() => void 0} />' },
5858
/* End all flavors of input */
59+
{ code: '<a onClick={() => void 0} />' },
60+
{ code: '<a onClick={() => {}} />;' },
5961
{ code: '<a tabIndex="0" onClick={() => void 0} />' },
6062
{ code: '<a onClick={() => void 0} href="http://x.y.z" />' },
6163
{ code: '<a onClick={() => void 0} href="http://x.y.z" tabIndex="0" />' },
@@ -216,8 +218,6 @@ ruleTester.run('no-noninteractive-element-handlers', rule, {
216218
invalid: [
217219
/* HTML elements with an inherent, non-interactive role */
218220
{ code: '<main onClick={() => void 0} />;', errors: [expectedError] },
219-
{ code: '<a onClick={() => void 0} />', errors: [expectedError] },
220-
{ code: '<a onClick={() => {}} />;', errors: [expectedError] },
221221
{ code: '<area onClick={() => {}} />;', errors: [expectedError] },
222222
{ code: '<article onClick={() => {}} />;', errors: [expectedError] },
223223
{ code: '<article onDblClick={() => void 0} />;', errors: [expectedError] },

__tests__/src/rules/no-noninteractive-element-to-interactive-role-test.js

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -288,6 +288,10 @@ ruleTester.run('no-noninteractive-element-to-interactive-role', rule, {
288288
{ code: '<main role="listitem" />;' },
289289
{ code: '<a role="listitem" />' },
290290
{ code: '<a role="listitem" />;' },
291+
{ code: '<a role="button" />' },
292+
{ code: '<a role="button" />;' },
293+
{ code: '<a role="menuitem" />' },
294+
{ code: '<a role="menuitem" />;' },
291295
{ code: '<area role="listitem" />;' },
292296
{ code: '<article role="listitem" />;' },
293297
{ code: '<article role="listitem" />;' },
@@ -358,8 +362,6 @@ ruleTester.run('no-noninteractive-element-to-interactive-role', rule, {
358362
/* HTML elements with an inherent non-interactive role, assigned an
359363
* interactive role. */
360364
{ code: '<main role="button" />;', errors: [expectedError] },
361-
{ code: '<a role="button" />', errors: [expectedError] },
362-
{ code: '<a role="button" />;', errors: [expectedError] },
363365
{ code: '<area role="button" />;', errors: [expectedError] },
364366
{ code: '<article role="button" />;', errors: [expectedError] },
365367
{ code: '<article role="button" />;', errors: [expectedError] },
@@ -391,8 +393,6 @@ ruleTester.run('no-noninteractive-element-to-interactive-role', rule, {
391393
/* HTML elements with an inherent non-interactive role, assigned an
392394
* interactive role. */
393395
{ code: '<main role="menuitem" />;', errors: [expectedError] },
394-
{ code: '<a role="menuitem" />', errors: [expectedError] },
395-
{ code: '<a role="menuitem" />;', errors: [expectedError] },
396396
{ code: '<area role="menuitem" />;', errors: [expectedError] },
397397
{ code: '<article role="menuitem" />;', errors: [expectedError] },
398398
{ code: '<article role="menuitem" />;', errors: [expectedError] },

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -96,8 +96,6 @@ ruleTester.run('no-static-element-interactions', rule, {
9696
{ code: '<div role="presentation" onClick={() => {}} />;' },
9797
/* HTML elements with an inherent, non-interactive role */
9898
{ code: '<main onClick={() => void 0} />;' },
99-
{ code: '<a onClick={() => void 0} />' },
100-
{ code: '<a onClick={() => {}} />;' },
10199
{ code: '<area onClick={() => {}} />;' },
102100
{ code: '<article onClick={() => {}} />;' },
103101
{ code: '<article onDblClick={() => void 0} />;' },
@@ -193,6 +191,8 @@ ruleTester.run('no-static-element-interactions', rule, {
193191
{ code: '<div onClick={() => void 0} {...props} />;', errors: [expectedError] },
194192
{ code: '<div onKeyUp={() => void 0} aria-hidden={false} />;', errors: [expectedError] },
195193
/* Static elements; no inherent role */
194+
{ code: '<a onClick={() => void 0} />', errors: [expectedError] },
195+
{ code: '<a onClick={() => {}} />;', errors: [expectedError] },
196196
{ code: '<acronym onClick={() => {}} />;', errors: [expectedError] },
197197
{ code: '<address onClick={() => {}} />;', errors: [expectedError] },
198198
{ code: '<applet onClick={() => {}} />;', errors: [expectedError] },

src/rules/interactive-supports-focus.js

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@ import { generateObjSchema } from '../util/schemas';
1616
import isHiddenFromScreenReader from '../util/isHiddenFromScreenReader';
1717
import isInteractiveElement from '../util/isInteractiveElement';
1818
import isInteractiveRole from '../util/isInteractiveRole';
19+
import isNonInteractiveElement from '../util/isNonInteractiveElement';
20+
import isNonInteractiveRole from '../util/isNonInteractiveRole';
1921
import isPresentationRole from '../util/isPresentationRole';
2022
import getTabIndex from '../util/getTabIndex';
2123

@@ -47,7 +49,7 @@ module.exports = {
4749
JSXOpeningElement: (
4850
node: JSXOpeningElement,
4951
) => {
50-
const attributes = node.attributes
52+
const attributes = node.attributes;
5153
const type = elementType(node);
5254
const hasInteractiveProps = hasAnyProp(attributes, interactiveProps);
5355
const hasTabindex = getTabIndex(
@@ -71,8 +73,10 @@ module.exports = {
7173

7274
if (
7375
hasInteractiveProps
74-
&& !isInteractiveElement(type, attributes)
7576
&& isInteractiveRole(type, attributes)
77+
&& !isInteractiveElement(type, attributes)
78+
&& !isNonInteractiveElement(type, attributes)
79+
&& !isNonInteractiveRole(type, attributes)
7680
&& !hasTabindex
7781
) {
7882
context.report({

src/util/isNonInteractiveElement.js

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,6 @@ const isNotLink = function isNotLink(attributes) {
6868

6969
export const nonInteractiveElementsMap = {
7070
...pureNonInteractiveElements,
71-
a: isNotLink,
7271
area: isNotLink,
7372
input: (attributes) => {
7473
const typeAttr = getLiteralPropValue(getProp(attributes, 'type'));

0 commit comments

Comments
 (0)