Skip to content

Commit 1b063ce

Browse files
committed
Responding to feedback about test schema definition
1 parent 48c1890 commit 1b063ce

File tree

3 files changed

+29
-11
lines changed

3 files changed

+29
-11
lines changed

docs/rules/no-noninteractive-tabindex.md

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# no-noninteractive-tabindex
22

3-
Tab key navigation should be limited to elements on the page that can be interacted with. Thus it is not necessary to add a tabindex to items in an unordered list, for example, to make them navigable through assistive technology. These applications already afford page traversal mechanisms based on the HTML of the page. Generally, we should try to reduce the size of the page's tab ring rather than increasing it.
3+
Tab key navigation should be limited to elements on the page that can be interacted with. Thus it is not necessary to add a tabindex to items in an unordered list, for example, to make them navigable through assistive technology. These applications already afford page traversal mechanisms based on the HTML of the page. Generally, we should try to reduce the size of the page's tab ring rather than increasing it.
44

55
## How do I resolve this error?
66

@@ -18,7 +18,7 @@ The bare `<a>` tag is an _anchor_. It has no semantic AX API mapping in either A
1818

1919
### Case: I am using "semantic" HTML. Isn't that interactive?
2020

21-
If we take a step back into the field of linguistics for a moment, let's consider what it means for something to be "semantic". Nothing, in and of itself, has meaning. Meaning is constructed through dialogue. A speaker intends a meaning and a listener/observer interprets a meaning. Each participant constructs their own meaning through dialogue. There is no intrinsic or isolated meaning outside of interaction. Thus, we must ask, given that have a "speaker" who communicates via "semantic" HTML, who is listening/observing?
21+
If we take a step back into the field of linguistics for a moment, let's consider what it means for something to be "semantic". Nothing, in and of itself, has meaning. Meaning is constructed through dialogue. A speaker intends a meaning and a listener/observer interprets a meaning. Each participant constructs their own meaning through dialogue. There is no intrinsic or isolated meaning outside of interaction. Thus, we must ask, given that we have a "speaker" who communicates via "semantic" HTML, who is listening/observing?
2222

2323
In our case, the observer is the Accessibility (AX) API. Browsers interpret HTML (inflected at times by ARIA) to construct a meaning (AX Tree) of the page. Whatever the semantic HTML intends has only the force of suggestion to the AX API. Therefore, we have inconsistencies. For example, there is not yet an ARIA role for `text` or `label` and thus no way to change a `<label>` into plain text or a `<span>` into a label via ARIA. '<div>' has an AXObject correpondant `DivRole`, but no such object maps to `<span>`.
2424

@@ -42,7 +42,7 @@ Endeavor to limit tabbable elements to those that a user can act upon.
4242

4343
### Case: Shouldn't I add a tabindex so that users can navigate to this item?
4444

45-
It is not necessary to put a tabindex or an `<article>`, for instance or on `<li>` items; assistive technologies provide affordances to users to find and traverse these containers. Most elements that require a tabindex -- `<a href>`, `<button>`, `<input>`, `<textarea>` -- have it already.
45+
It is not necessary to put a tabindex on an `<article>`, for instance or on `<li>` items; assistive technologies provide affordances to users to find and traverse these containers. Most elements that require a tabindex -- `<a href>`, `<button>`, `<input>`, `<textarea>` -- have it already.
4646

4747
Your application might require an exception to this rule in the case of an element that captures incoming tab traversal for a composite widget. In that case, turn off this rule on a per instance basis. This is an uncommon case.
4848

@@ -52,7 +52,17 @@ Your application might require an exception to this rule in the case of an eleme
5252

5353
## Rule details
5454

55-
This rule takes no arguments.
55+
The recommended options for this rule allow `tabIndex` on elements with the noninteractive `tabpanel` role. Adding `tabIndex` to a tabpanel is a recommended practice in some instances.
56+
57+
```javascript
58+
'jsx-a11y/no-noninteractive-tabindex': [
59+
'error',
60+
{
61+
tags: [],
62+
roles: ['tabpanel'],
63+
},
64+
]
65+
```
5666

5767
### Succeed
5868
```jsx

src/rules/no-noninteractive-tabindex.js

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -18,12 +18,22 @@ import {
1818
} from 'jsx-ast-utils';
1919
import isInteractiveElement from '../util/isInteractiveElement';
2020
import isInteractiveRole from '../util/isInteractiveRole';
21-
import { generateObjSchema } from '../util/schemas';
21+
import { generateObjSchema, arraySchema } from '../util/schemas';
22+
import getTabIndex from '../util/getTabIndex';
2223

2324
const errorMessage =
2425
'`tabIndex` should only be declared on interactive elements.';
2526

26-
const schema = generateObjSchema();
27+
const schema = generateObjSchema({
28+
roles: {
29+
...arraySchema,
30+
description: 'An array of ARIA roles',
31+
},
32+
tags: {
33+
...arraySchema,
34+
description: 'An array of HTML tag names',
35+
},
36+
});
2737

2838
module.exports = {
2939
meta: {
@@ -40,7 +50,7 @@ module.exports = {
4050
const type = elementType(node);
4151
const attributes = node.attributes;
4252
const tabIndexProp = getProp(attributes, 'tabIndex');
43-
const tabIndex = getLiteralPropValue(tabIndexProp);
53+
const tabIndex = getTabIndex(tabIndexProp);
4454
// Early return;
4555
if (typeof tabIndex === 'undefined') {
4656
return;
@@ -73,9 +83,8 @@ module.exports = {
7383
return;
7484
}
7585
if (
76-
!isNaN(Number.parseInt(tabIndex, 10))
77-
&& tabIndex >= 0
78-
) {
86+
tabIndex >= 0
87+
) {
7988
context.report({
8089
node: tabIndexProp,
8190
message: errorMessage,

src/util/schemas.js

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ export const arraySchema = {
66
items: {
77
type: 'string',
88
},
9-
minItems: 1,
109
uniqueItems: true,
1110
additionalItems: false,
1211
};

0 commit comments

Comments
 (0)