Skip to content

Commit dd8ebd5

Browse files
committed
Treat the toolbar role as if it descended from widget
1 parent f991346 commit dd8ebd5

File tree

4 files changed

+29
-8
lines changed

4 files changed

+29
-8
lines changed

__mocks__/genInteractives.js

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,13 @@ const abstractRoles = roleNames
104104
const nonAbstractRoles = roleNames
105105
.filter(role => !roles.get(role).abstract);
106106

107-
const interactiveRoles = roleNames
107+
const interactiveRoles = []
108+
.concat(
109+
roleNames,
110+
// 'toolbar' does not descend from widget, but it does support
111+
// aria-activedescendant, thus in practice we treat it as a widget.
112+
'toolbar',
113+
)
108114
.filter(role => !roles.get(role).abstract)
109115
.filter(role => roles.get(role).superClass.some(
110116
klasses => klasses.includes('widget')),
@@ -114,7 +120,10 @@ const nonInteractiveRoles = roleNames
114120
.filter(role => !roles.get(role).abstract)
115121
.filter(role => !roles.get(role).superClass.some(
116122
klasses => klasses.includes('widget')),
117-
);
123+
)
124+
// 'toolbar' does not descend from widget, but it does support
125+
// aria-activedescendant, thus in practice we treat it as a widget.
126+
.filter(role => !['toolbar'].includes(role));
118127

119128
export function genElementSymbol (
120129
openingElement: Object,

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -207,6 +207,7 @@ ruleTester.run('no-noninteractive-element-handlers', rule, {
207207
{ code: '<div role="select" onClick={() => {}} />;' },
208208
{ code: '<div role="structure" onClick={() => {}} />;' },
209209
{ code: '<div role="tablist" onClick={() => {}} />;' },
210+
{ code: '<div role="toolbar" onClick={() => {}} />;' },
210211
{ code: '<div role="tree" onClick={() => {}} />;' },
211212
{ code: '<div role="treegrid" onClick={() => {}} />;' },
212213
{ code: '<div role="widget" onClick={() => {}} />;' },
@@ -281,7 +282,6 @@ ruleTester.run('no-noninteractive-element-handlers', rule, {
281282
{ code: '<div role="tabpanel" onClick={() => {}} />;', errors: [expectedError] },
282283
{ code: '<div role="term" onClick={() => {}} />;', errors: [expectedError] },
283284
{ code: '<div role="timer" onClick={() => {}} />;', errors: [expectedError] },
284-
{ code: '<div role="toolbar" onClick={() => {}} />;', errors: [expectedError] },
285285
{ code: '<div role="tooltip" onClick={() => {}} />;', errors: [expectedError] },
286286
].map(parserOptionsMapper),
287287
});

src/util/isInteractiveElement.js

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,12 @@ type ElementCallbackMap = {
1919
};
2020

2121
const interactiveRoles = new Set(
22-
[...roles.keys()]
22+
[].concat(
23+
[...roles.keys()],
24+
// 'toolbar' does not descend from widget, but it does support
25+
// aria-activedescendant, thus in practice we treat it as a widget.
26+
'toolbar',
27+
)
2328
.filter(name => !roles.get(name).abstract)
2429
.filter(name => roles.get(name).superClass.some(
2530
klasses => klasses.includes('widget')),

src/util/isInteractiveRole.js

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,15 @@ import {
44
import type { Node } from 'ast-types-flow';
55
import { getProp, getLiteralPropValue } from 'jsx-ast-utils';
66

7-
const VALID_ROLES = [...roles.keys()]
7+
const interactiveRoles = [...roles.keys()]
88
.filter(name => !roles.get(name).abstract)
99
.filter(name => roles.get(name).superClass.some(
1010
klasses => klasses.includes('widget')),
1111
);
12+
13+
// 'toolbar' does not descend from widget, but it does support
14+
// aria-activedescendant, thus in practice we treat it as a widget.
15+
interactiveRoles.push('toolbar');
1216
/**
1317
* Returns boolean indicating whether the given element has a role
1418
* that is associated with an interactive component. Used when an element
@@ -33,10 +37,13 @@ const isInteractiveRole = (
3337
return false;
3438
}
3539

40+
let isInteractive = false;
3641
const normalizedValues = String(value).toLowerCase().split(' ');
37-
const isInteractive = normalizedValues.every(
38-
val => VALID_ROLES.indexOf(val) > -1,
39-
);
42+
if (normalizedValues.length > 0) {
43+
// The last role value is a series takes precedence.
44+
let val = normalizedValues[normalizedValues.length - 1];
45+
isInteractive = interactiveRoles.indexOf(val) > -1;
46+
}
4047

4148
return isInteractive;
4249
};

0 commit comments

Comments
 (0)