Skip to content

Commit a18f6b0

Browse files
authored
Merge branch 'master' into allow-fieldset-to-have-role-of-radiogroup
2 parents 8064a61 + 066ccff commit a18f6b0

15 files changed

+239
-22
lines changed

.github/workflows/node-4+.yml

+81
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
name: 'Tests: node.js'
2+
3+
on: [pull_request, push]
4+
5+
jobs:
6+
matrix:
7+
runs-on: ubuntu-latest
8+
outputs:
9+
latest: ${{ steps.set-matrix.outputs.requireds }}
10+
steps:
11+
- uses: ljharb/actions/node/matrix@main
12+
id: set-matrix
13+
with:
14+
versionsAsRoot: true
15+
type: 'majors'
16+
preset: '>=4'
17+
18+
latest:
19+
needs: [matrix]
20+
name: 'latest majors'
21+
runs-on: ubuntu-latest
22+
23+
strategy:
24+
matrix:
25+
node-version: ${{ fromJson(needs.matrix.outputs.latest) }}
26+
eslint:
27+
- 7
28+
- 6
29+
- 5
30+
- 4
31+
- 3
32+
exclude:
33+
- node-version: 9
34+
eslint: 7
35+
- node-version: 8
36+
eslint: 7
37+
- node-version: 7
38+
eslint: 7
39+
- node-version: 7
40+
eslint: 6
41+
- node-version: 6
42+
eslint: 7
43+
- node-version: 6
44+
eslint: 6
45+
- node-version: 5
46+
eslint: 7
47+
- node-version: 5
48+
eslint: 6
49+
- node-version: 5
50+
eslint: 5
51+
- node-version: 5
52+
eslint: 4
53+
- node-version: 5 # TODO: fix
54+
eslint: 3
55+
- node-version: 4
56+
eslint: 7
57+
- node-version: 4
58+
eslint: 6
59+
- node-version: 4
60+
eslint: 5
61+
- node-version: 4 # TODO: fix
62+
eslint: 4
63+
- node-version: 4 # TODO: fix
64+
eslint: 3
65+
66+
steps:
67+
- uses: actions/checkout@v2
68+
- uses: ljharb/actions/node/run@main
69+
name: 'npm install && npm run tests-only'
70+
with:
71+
after_install: npm uninstall --no-save eslint-config-airbnb-base && npm install --no-save "eslint@${{ matrix.eslint }}"
72+
node-version: ${{ matrix.node-version }}
73+
command: 'test:ci'
74+
skip-ls-check: true
75+
76+
node:
77+
name: 'node 4+'
78+
needs: [latest]
79+
runs-on: ubuntu-latest
80+
steps:
81+
- run: 'echo tests completed'

.github/workflows/node-pretest.yml

+40
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
name: 'Tests: pretest/posttest'
2+
3+
on: [pull_request, push]
4+
5+
jobs:
6+
lint:
7+
runs-on: ubuntu-latest
8+
9+
steps:
10+
- uses: actions/checkout@v2
11+
- uses: ljharb/actions/node/run@main
12+
name: 'npm install && npm run lint'
13+
with:
14+
node-version: 'lts/*'
15+
command: 'lint'
16+
skip-ls-check: true
17+
18+
flow:
19+
runs-on: ubuntu-latest
20+
21+
steps:
22+
- uses: actions/checkout@v2
23+
- uses: ljharb/actions/node/run@main
24+
name: 'npm install && npm run flow'
25+
with:
26+
node-version: 'lts/*'
27+
command: 'flow'
28+
skip-ls-check: true
29+
30+
posttest:
31+
runs-on: ubuntu-latest
32+
33+
steps:
34+
- uses: actions/checkout@v2
35+
- uses: ljharb/actions/node/run@main
36+
name: 'npm install && npm run posttest'
37+
with:
38+
node-version: 'lts/*'
39+
command: 'posttest'
40+
skip-ls-check: true

.github/workflows/rebase.yml

+15
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
name: Automatic Rebase
2+
3+
on: [pull_request_target]
4+
5+
jobs:
6+
_:
7+
name: "Automatic Rebase"
8+
9+
runs-on: ubuntu-latest
10+
11+
steps:
12+
- uses: actions/checkout@v2
13+
- uses: ljharb/rebase@master
14+
env:
15+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
name: Require “Allow Edits”
2+
3+
on: [pull_request_target]
4+
5+
jobs:
6+
_:
7+
name: "Require “Allow Edits”"
8+
9+
runs-on: ubuntu-latest
10+
11+
steps:
12+
- uses: ljharb/require-allow-edits@main

.gitignore

+3-2
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
.DS_Store
2-
coverage
2+
coverage/
33
lib
44
node_modules
55
npm-debug.log
6+
7+
npm-shrinkwrap.json
68
package-lock.json
7-
reports
89
yarn-error.log
910
yarn.lock

__tests__/src/rules/label-has-associated-control-test.js

+6
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,9 @@ const htmlForValid = [
3636
{ code: '<CustomLabel htmlFor="js_id" label="A label" />', options: [{ labelAttributes: ['label'], labelComponents: ['CustomLabel'] }] },
3737
// Custom label attributes.
3838
{ code: '<label htmlFor="js_id" label="A label" />', options: [{ labelAttributes: ['label'] }] },
39+
// Glob support for controlComponents option.
40+
{ code: '<CustomLabel htmlFor="js_id" aria-label="A label" />', options: [{ controlComponents: ['Custom*'] }] },
41+
{ code: '<CustomLabel htmlFor="js_id" aria-label="A label" />', options: [{ controlComponents: ['*Label'] }] },
3942
];
4043
const nestingValid = [
4144
{ code: '<label>A label<input /></label>' },
@@ -57,6 +60,9 @@ const nestingValid = [
5760
{ code: '<label><span>A label<CustomInput /></span></label>', options: [{ controlComponents: ['CustomInput'] }] },
5861
{ code: '<CustomLabel><span>A label<CustomInput /></span></CustomLabel>', options: [{ controlComponents: ['CustomInput'], labelComponents: ['CustomLabel'] }] },
5962
{ code: '<CustomLabel><span label="A label"><CustomInput /></span></CustomLabel>', options: [{ controlComponents: ['CustomInput'], labelComponents: ['CustomLabel'], labelAttributes: ['label'] }] },
63+
// Glob support for controlComponents option.
64+
{ code: '<label><span>A label<CustomInput /></span></label>', options: [{ controlComponents: ['Custom*'] }] },
65+
{ code: '<label><span>A label<CustomInput /></span></label>', options: [{ controlComponents: ['*Input'] }] },
6066
];
6167

6268
const bothValid = [

__tests__/src/util/mayContainChildComponent-test.js

+48
Original file line numberDiff line numberDiff line change
@@ -104,4 +104,52 @@ describe('mayContainChildComponent', () => {
104104
});
105105
});
106106
});
107+
108+
describe('Glob name matching', () => {
109+
describe('component name contains question mark ? - match any single character', () => {
110+
it('should return true', () => {
111+
expect(mayContainChildComponent(
112+
JSXElementMock('div', [], [
113+
JSXElementMock('FancyComponent'),
114+
]),
115+
'Fanc?Co??onent',
116+
)).toBe(true);
117+
});
118+
it('should return false', () => {
119+
expect(mayContainChildComponent(
120+
JSXElementMock('div', [], [
121+
JSXElementMock('FancyComponent'),
122+
]),
123+
'FancyComponent?',
124+
)).toBe(false);
125+
});
126+
});
127+
128+
describe('component name contains asterisk * - match zero or more characters', () => {
129+
it('should return true', () => {
130+
expect(mayContainChildComponent(
131+
JSXElementMock('div', [], [
132+
JSXElementMock('FancyComponent'),
133+
]),
134+
'Fancy*',
135+
)).toBe(true);
136+
});
137+
it('should return true', () => {
138+
expect(mayContainChildComponent(
139+
JSXElementMock('div', [], [
140+
JSXElementMock('FancyComponent'),
141+
]),
142+
'*Component',
143+
)).toBe(true);
144+
});
145+
it('should return true', () => {
146+
expect(mayContainChildComponent(
147+
JSXElementMock('div', [], [
148+
JSXElementMock('FancyComponent'),
149+
]),
150+
'Fancy*C*t',
151+
)).toBe(true);
152+
});
153+
});
154+
});
107155
});

docs/rules/aria-role.md

+1
Original file line numberDiff line numberDiff line change
@@ -41,3 +41,4 @@ For the `ignoreNonDOM` option, this determines if developer created components a
4141
### Resources
4242
- [Chrome Audit Rules, AX_ARIA_01](https://github.com/GoogleChrome/accessibility-developer-tools/wiki/Audit-Rules#ax_aria_01)
4343
- [DPUB-ARIA roles](https://www.w3.org/TR/dpub-aria-1.0/)
44+
- [MDN: Using ARIA: Roles, states, and properties](https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/ARIA_Techniques)

docs/rules/label-has-associated-control.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,7 @@ This rule takes one optional object argument of type object:
101101

102102
`labelComponents` is a list of custom React Component names that should be checked for an associated control.
103103
`labelAttributes` is a list of attributes to check on the label component and its children for a label. Use this if you have a custom component that uses a string passed on a prop to render an HTML `label`, for example.
104-
`controlComponents` is a list of custom React Components names that will output an input element.
104+
`controlComponents` is a list of custom React Components names that will output an input element. [Glob format](https://linuxhint.com/bash_globbing_tutorial/) is also supported for specifying names (e.g., `Label*` matches `LabelComponent` but not `CustomLabel`, `????Label` matches `LinkLabel` but not `CustomLabel`).
105105
`assert` asserts that the label has htmlFor, a nested label, both or either. Available options: `'htmlFor', 'nesting', 'both', 'either'`.
106106
`depth` (default 2, max 25) is an integer that determines how deep within a `JSXElement` label the rule should look for text content or an element with a label to determine if the `label` element will have an accessible label.
107107

docs/rules/no-noninteractive-tabindex.md

+9
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,15 @@ It is not necessary to put a tabindex on an `<article>`, for instance or on `<li
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

49+
If you know that a particular element will be scrollable, you might want to add `tabindex="0"` if your website supports browsers that don't make these containers keyboard-focusable. The current status for this platform feature can be tracked in [Chrome Platform Status "Feature: Keyboard-focusable scroll containers"](https://www.chromestatus.com/feature/5231964663578624).
50+
51+
```jsx
52+
// eslint-disable-next-line no-noninteractive-tabindex
53+
<pre tabIndex="0">
54+
<code>{someLongCode}</code>
55+
</pre>
56+
```
57+
4958
## Rule details
5059

5160
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.

docs/rules/no-onchange.md

+3-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
1-
# no-onchange
1+
# [Deprecated] no-onchange
2+
3+
⚠️ **Deprecated:** This rule is based on reports of behavior of [old browsers (eg. IE 10 and below)](https://www.quirksmode.org/dom/events/change.html#t05). In the meantime, this behavior has been corrected, both in newer versions of browsers as well as [in the DOM spec](https://bugzilla.mozilla.org/show_bug.cgi?id=969068#c2).
24

35
Enforce usage of `onBlur` over/in parallel with `onChange` on select menu elements for accessibility. `onBlur` **should** be used instead of `onChange`, unless absolutely necessary and it causes no negative consequences for keyboard only or screen reader users. `onBlur` is a more declarative action by the user: for instance in a dropdown, using the arrow keys to toggle between options will trigger the `onChange` event in some browsers. Regardless, when a change of context results from an `onBlur` event or an `onChange` event, the user should be notified of the change unless it occurs below the currently focused element.
46

package.json

+16-14
Original file line numberDiff line numberDiff line change
@@ -18,27 +18,27 @@
1818
"main": "lib/index.js",
1919
"scripts": {
2020
"build": "rimraf lib && babel src --out-dir lib --copy-files",
21-
"coveralls": "cat ./reports/lcov.info | coveralls",
2221
"create": "node ./scripts/create-rule",
2322
"flow": "if [ ! -e ./.flowconfig ]; then echo \"Could not find .flowconfig\"; else flow; test $? -eq 0 -o $? -eq 2; fi",
2423
"lint:fix": "npm run lint -- --fix",
2524
"lint": "eslint --config .eslintrc src __tests__ __mocks__ scripts",
2625
"prepublish": "safe-publish-latest && not-in-publish || (npm run lint && npm run flow && npm run jest && npm run build)",
2726
"pretest": "npm run lint:fix && npm run flow",
2827
"test": "npm run jest",
28+
"posttest": "aud --production",
2929
"test:ci": "npm run jest -- --ci --runInBand",
3030
"jest": "jest --coverage __tests__/**/*"
3131
},
3232
"devDependencies": {
33-
"@babel/cli": "^7.11.6",
34-
"@babel/core": "^7.11.6",
35-
"@babel/plugin-transform-flow-strip-types": "^7.10.4",
33+
"@babel/cli": "^7.12.10",
34+
"@babel/core": "^7.12.10",
35+
"@babel/plugin-transform-flow-strip-types": "^7.12.10",
36+
"aud": "^1.1.3",
3637
"babel-eslint": "^10.1.0",
3738
"babel-jest": "^24.9.0",
3839
"babel-preset-airbnb": "^5.0.0",
39-
"coveralls": "^3.1.0",
4040
"eslint": "^3 || ^4 || ^5 || ^6 || ^7",
41-
"eslint-config-airbnb-base": "^14.2.0",
41+
"eslint-config-airbnb-base": "^14.2.1",
4242
"eslint-plugin-flowtype": "^5.2.0",
4343
"eslint-plugin-import": "^2.22.1",
4444
"estraverse": "^5.2.0",
@@ -48,7 +48,7 @@
4848
"jest": "^24.9.0",
4949
"jscodeshift": "^0.7.0",
5050
"minimist": "^1.2.5",
51-
"object.assign": "^4.1.1",
51+
"object.assign": "^4.1.2",
5252
"rimraf": "^3.0.2",
5353
"safe-publish-latest": "^1.1.4",
5454
"to-ast": "^1.0.0"
@@ -58,27 +58,29 @@
5858
},
5959
"license": "MIT",
6060
"dependencies": {
61-
"@babel/runtime": "^7.11.2",
61+
"@babel/runtime": "^7.12.5",
6262
"aria-query": "^4.2.2",
63-
"array-includes": "^3.1.1",
63+
"array-includes": "^3.1.2",
6464
"ast-types-flow": "^0.0.7",
65-
"axe-core": "^4.0.2",
65+
"axe-core": "^4.1.1",
6666
"axobject-query": "^2.2.0",
6767
"damerau-levenshtein": "^1.0.6",
68-
"emoji-regex": "^9.0.0",
68+
"emoji-regex": "^9.2.0",
6969
"has": "^1.0.3",
70-
"jsx-ast-utils": "^3.1.0",
71-
"language-tags": "^1.0.5"
70+
"jsx-ast-utils": "^3.2.0",
71+
"language-tags": "^1.0.5",
72+
"minimatch": "^3.0.4"
7273
},
7374
"peerDependencies": {
7475
"eslint": "^3 || ^4 || ^5 || ^6 || ^7"
7576
},
7677
"jest": {
7778
"coverageReporters": [
7879
"lcov",
80+
"json",
7981
"html"
8082
],
81-
"coverageDirectory": "reports",
83+
"coverageDirectory": "coverage",
8284
"roots": [
8385
"__tests__"
8486
],

src/index.js

+1-3
Original file line numberDiff line numberDiff line change
@@ -176,7 +176,6 @@ module.exports = {
176176
allowExpressionValues: true,
177177
},
178178
],
179-
'jsx-a11y/no-onchange': 'error',
180179
'jsx-a11y/no-redundant-roles': 'error',
181180
'jsx-a11y/no-static-element-interactions': [
182181
'error',
@@ -266,7 +265,7 @@ module.exports = {
266265
],
267266
},
268267
],
269-
'jsx-a11y/label-has-for': 'error',
268+
'jsx-a11y/label-has-for': 'off',
270269
'jsx-a11y/label-has-associated-control': 'error',
271270
'jsx-a11y/media-has-caption': 'error',
272271
'jsx-a11y/mouse-events-have-key-events': 'error',
@@ -284,7 +283,6 @@ module.exports = {
284283
],
285284
'jsx-a11y/no-noninteractive-element-to-interactive-role': 'error',
286285
'jsx-a11y/no-noninteractive-tabindex': 'error',
287-
'jsx-a11y/no-onchange': 'error',
288286
'jsx-a11y/no-redundant-roles': 'error',
289287
'jsx-a11y/no-static-element-interactions': 'error',
290288
'jsx-a11y/role-has-required-aria-props': 'error',

src/rules/no-onchange.js

+1
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ module.exports = {
2424
docs: {
2525
url: 'https://github.com/evcohen/eslint-plugin-jsx-a11y/tree/master/docs/rules/no-onchange.md',
2626
},
27+
deprecated: true,
2728
schema: [schema],
2829
},
2930

0 commit comments

Comments
 (0)