Skip to content

Commit

Permalink
Merge branch 'master' into allow-fieldset-to-have-role-of-radiogroup
Browse files Browse the repository at this point in the history
  • Loading branch information
hallzac2 committed Jan 15, 2021
2 parents 8064a61 + 066ccff commit a18f6b0
Show file tree
Hide file tree
Showing 15 changed files with 239 additions and 22 deletions.
81 changes: 81 additions & 0 deletions .github/workflows/node-4+.yml
@@ -0,0 +1,81 @@
name: 'Tests: node.js'

on: [pull_request, push]

jobs:
matrix:
runs-on: ubuntu-latest
outputs:
latest: ${{ steps.set-matrix.outputs.requireds }}
steps:
- uses: ljharb/actions/node/matrix@main
id: set-matrix
with:
versionsAsRoot: true
type: 'majors'
preset: '>=4'

latest:
needs: [matrix]
name: 'latest majors'
runs-on: ubuntu-latest

strategy:
matrix:
node-version: ${{ fromJson(needs.matrix.outputs.latest) }}
eslint:
- 7
- 6
- 5
- 4
- 3
exclude:
- node-version: 9
eslint: 7
- node-version: 8
eslint: 7
- node-version: 7
eslint: 7
- node-version: 7
eslint: 6
- node-version: 6
eslint: 7
- node-version: 6
eslint: 6
- node-version: 5
eslint: 7
- node-version: 5
eslint: 6
- node-version: 5
eslint: 5
- node-version: 5
eslint: 4
- node-version: 5 # TODO: fix
eslint: 3
- node-version: 4
eslint: 7
- node-version: 4
eslint: 6
- node-version: 4
eslint: 5
- node-version: 4 # TODO: fix
eslint: 4
- node-version: 4 # TODO: fix
eslint: 3

steps:
- uses: actions/checkout@v2
- uses: ljharb/actions/node/run@main
name: 'npm install && npm run tests-only'
with:
after_install: npm uninstall --no-save eslint-config-airbnb-base && npm install --no-save "eslint@${{ matrix.eslint }}"
node-version: ${{ matrix.node-version }}
command: 'test:ci'
skip-ls-check: true

node:
name: 'node 4+'
needs: [latest]
runs-on: ubuntu-latest
steps:
- run: 'echo tests completed'
40 changes: 40 additions & 0 deletions .github/workflows/node-pretest.yml
@@ -0,0 +1,40 @@
name: 'Tests: pretest/posttest'

on: [pull_request, push]

jobs:
lint:
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v2
- uses: ljharb/actions/node/run@main
name: 'npm install && npm run lint'
with:
node-version: 'lts/*'
command: 'lint'
skip-ls-check: true

flow:
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v2
- uses: ljharb/actions/node/run@main
name: 'npm install && npm run flow'
with:
node-version: 'lts/*'
command: 'flow'
skip-ls-check: true

posttest:
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v2
- uses: ljharb/actions/node/run@main
name: 'npm install && npm run posttest'
with:
node-version: 'lts/*'
command: 'posttest'
skip-ls-check: true
15 changes: 15 additions & 0 deletions .github/workflows/rebase.yml
@@ -0,0 +1,15 @@
name: Automatic Rebase

on: [pull_request_target]

jobs:
_:
name: "Automatic Rebase"

runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v2
- uses: ljharb/rebase@master
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
12 changes: 12 additions & 0 deletions .github/workflows/require-allow-edits.yml
@@ -0,0 +1,12 @@
name: Require “Allow Edits”

on: [pull_request_target]

jobs:
_:
name: "Require “Allow Edits”"

runs-on: ubuntu-latest

steps:
- uses: ljharb/require-allow-edits@main
5 changes: 3 additions & 2 deletions .gitignore
@@ -1,9 +1,10 @@
.DS_Store
coverage
coverage/
lib
node_modules
npm-debug.log

npm-shrinkwrap.json
package-lock.json
reports
yarn-error.log
yarn.lock
6 changes: 6 additions & 0 deletions __tests__/src/rules/label-has-associated-control-test.js
Expand Up @@ -36,6 +36,9 @@ const htmlForValid = [
{ code: '<CustomLabel htmlFor="js_id" label="A label" />', options: [{ labelAttributes: ['label'], labelComponents: ['CustomLabel'] }] },
// Custom label attributes.
{ code: '<label htmlFor="js_id" label="A label" />', options: [{ labelAttributes: ['label'] }] },
// Glob support for controlComponents option.
{ code: '<CustomLabel htmlFor="js_id" aria-label="A label" />', options: [{ controlComponents: ['Custom*'] }] },
{ code: '<CustomLabel htmlFor="js_id" aria-label="A label" />', options: [{ controlComponents: ['*Label'] }] },
];
const nestingValid = [
{ code: '<label>A label<input /></label>' },
Expand All @@ -57,6 +60,9 @@ const nestingValid = [
{ code: '<label><span>A label<CustomInput /></span></label>', options: [{ controlComponents: ['CustomInput'] }] },
{ code: '<CustomLabel><span>A label<CustomInput /></span></CustomLabel>', options: [{ controlComponents: ['CustomInput'], labelComponents: ['CustomLabel'] }] },
{ code: '<CustomLabel><span label="A label"><CustomInput /></span></CustomLabel>', options: [{ controlComponents: ['CustomInput'], labelComponents: ['CustomLabel'], labelAttributes: ['label'] }] },
// Glob support for controlComponents option.
{ code: '<label><span>A label<CustomInput /></span></label>', options: [{ controlComponents: ['Custom*'] }] },
{ code: '<label><span>A label<CustomInput /></span></label>', options: [{ controlComponents: ['*Input'] }] },
];

const bothValid = [
Expand Down
48 changes: 48 additions & 0 deletions __tests__/src/util/mayContainChildComponent-test.js
Expand Up @@ -104,4 +104,52 @@ describe('mayContainChildComponent', () => {
});
});
});

describe('Glob name matching', () => {
describe('component name contains question mark ? - match any single character', () => {
it('should return true', () => {
expect(mayContainChildComponent(
JSXElementMock('div', [], [
JSXElementMock('FancyComponent'),
]),
'Fanc?Co??onent',
)).toBe(true);
});
it('should return false', () => {
expect(mayContainChildComponent(
JSXElementMock('div', [], [
JSXElementMock('FancyComponent'),
]),
'FancyComponent?',
)).toBe(false);
});
});

describe('component name contains asterisk * - match zero or more characters', () => {
it('should return true', () => {
expect(mayContainChildComponent(
JSXElementMock('div', [], [
JSXElementMock('FancyComponent'),
]),
'Fancy*',
)).toBe(true);
});
it('should return true', () => {
expect(mayContainChildComponent(
JSXElementMock('div', [], [
JSXElementMock('FancyComponent'),
]),
'*Component',
)).toBe(true);
});
it('should return true', () => {
expect(mayContainChildComponent(
JSXElementMock('div', [], [
JSXElementMock('FancyComponent'),
]),
'Fancy*C*t',
)).toBe(true);
});
});
});
});
1 change: 1 addition & 0 deletions docs/rules/aria-role.md
Expand Up @@ -41,3 +41,4 @@ For the `ignoreNonDOM` option, this determines if developer created components a
### Resources
- [Chrome Audit Rules, AX_ARIA_01](https://github.com/GoogleChrome/accessibility-developer-tools/wiki/Audit-Rules#ax_aria_01)
- [DPUB-ARIA roles](https://www.w3.org/TR/dpub-aria-1.0/)
- [MDN: Using ARIA: Roles, states, and properties](https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/ARIA_Techniques)
2 changes: 1 addition & 1 deletion docs/rules/label-has-associated-control.md
Expand Up @@ -101,7 +101,7 @@ This rule takes one optional object argument of type object:

`labelComponents` is a list of custom React Component names that should be checked for an associated control.
`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.
`controlComponents` is a list of custom React Components names that will output an input element.
`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`).
`assert` asserts that the label has htmlFor, a nested label, both or either. Available options: `'htmlFor', 'nesting', 'both', 'either'`.
`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.

Expand Down
9 changes: 9 additions & 0 deletions docs/rules/no-noninteractive-tabindex.md
Expand Up @@ -46,6 +46,15 @@ It is not necessary to put a tabindex on an `<article>`, for instance or on `<li

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.

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

```jsx
// eslint-disable-next-line no-noninteractive-tabindex
<pre tabIndex="0">
<code>{someLongCode}</code>
</pre>
```

## Rule details

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.
Expand Down
4 changes: 3 additions & 1 deletion docs/rules/no-onchange.md
@@ -1,4 +1,6 @@
# no-onchange
# [Deprecated] no-onchange

⚠️ **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).

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.

Expand Down
30 changes: 16 additions & 14 deletions package.json
Expand Up @@ -18,27 +18,27 @@
"main": "lib/index.js",
"scripts": {
"build": "rimraf lib && babel src --out-dir lib --copy-files",
"coveralls": "cat ./reports/lcov.info | coveralls",
"create": "node ./scripts/create-rule",
"flow": "if [ ! -e ./.flowconfig ]; then echo \"Could not find .flowconfig\"; else flow; test $? -eq 0 -o $? -eq 2; fi",
"lint:fix": "npm run lint -- --fix",
"lint": "eslint --config .eslintrc src __tests__ __mocks__ scripts",
"prepublish": "safe-publish-latest && not-in-publish || (npm run lint && npm run flow && npm run jest && npm run build)",
"pretest": "npm run lint:fix && npm run flow",
"test": "npm run jest",
"posttest": "aud --production",
"test:ci": "npm run jest -- --ci --runInBand",
"jest": "jest --coverage __tests__/**/*"
},
"devDependencies": {
"@babel/cli": "^7.11.6",
"@babel/core": "^7.11.6",
"@babel/plugin-transform-flow-strip-types": "^7.10.4",
"@babel/cli": "^7.12.10",
"@babel/core": "^7.12.10",
"@babel/plugin-transform-flow-strip-types": "^7.12.10",
"aud": "^1.1.3",
"babel-eslint": "^10.1.0",
"babel-jest": "^24.9.0",
"babel-preset-airbnb": "^5.0.0",
"coveralls": "^3.1.0",
"eslint": "^3 || ^4 || ^5 || ^6 || ^7",
"eslint-config-airbnb-base": "^14.2.0",
"eslint-config-airbnb-base": "^14.2.1",
"eslint-plugin-flowtype": "^5.2.0",
"eslint-plugin-import": "^2.22.1",
"estraverse": "^5.2.0",
Expand All @@ -48,7 +48,7 @@
"jest": "^24.9.0",
"jscodeshift": "^0.7.0",
"minimist": "^1.2.5",
"object.assign": "^4.1.1",
"object.assign": "^4.1.2",
"rimraf": "^3.0.2",
"safe-publish-latest": "^1.1.4",
"to-ast": "^1.0.0"
Expand All @@ -58,27 +58,29 @@
},
"license": "MIT",
"dependencies": {
"@babel/runtime": "^7.11.2",
"@babel/runtime": "^7.12.5",
"aria-query": "^4.2.2",
"array-includes": "^3.1.1",
"array-includes": "^3.1.2",
"ast-types-flow": "^0.0.7",
"axe-core": "^4.0.2",
"axe-core": "^4.1.1",
"axobject-query": "^2.2.0",
"damerau-levenshtein": "^1.0.6",
"emoji-regex": "^9.0.0",
"emoji-regex": "^9.2.0",
"has": "^1.0.3",
"jsx-ast-utils": "^3.1.0",
"language-tags": "^1.0.5"
"jsx-ast-utils": "^3.2.0",
"language-tags": "^1.0.5",
"minimatch": "^3.0.4"
},
"peerDependencies": {
"eslint": "^3 || ^4 || ^5 || ^6 || ^7"
},
"jest": {
"coverageReporters": [
"lcov",
"json",
"html"
],
"coverageDirectory": "reports",
"coverageDirectory": "coverage",
"roots": [
"__tests__"
],
Expand Down
4 changes: 1 addition & 3 deletions src/index.js
Expand Up @@ -176,7 +176,6 @@ module.exports = {
allowExpressionValues: true,
},
],
'jsx-a11y/no-onchange': 'error',
'jsx-a11y/no-redundant-roles': 'error',
'jsx-a11y/no-static-element-interactions': [
'error',
Expand Down Expand Up @@ -266,7 +265,7 @@ module.exports = {
],
},
],
'jsx-a11y/label-has-for': 'error',
'jsx-a11y/label-has-for': 'off',
'jsx-a11y/label-has-associated-control': 'error',
'jsx-a11y/media-has-caption': 'error',
'jsx-a11y/mouse-events-have-key-events': 'error',
Expand All @@ -284,7 +283,6 @@ module.exports = {
],
'jsx-a11y/no-noninteractive-element-to-interactive-role': 'error',
'jsx-a11y/no-noninteractive-tabindex': 'error',
'jsx-a11y/no-onchange': 'error',
'jsx-a11y/no-redundant-roles': 'error',
'jsx-a11y/no-static-element-interactions': 'error',
'jsx-a11y/role-has-required-aria-props': 'error',
Expand Down
1 change: 1 addition & 0 deletions src/rules/no-onchange.js
Expand Up @@ -24,6 +24,7 @@ module.exports = {
docs: {
url: 'https://github.com/evcohen/eslint-plugin-jsx-a11y/tree/master/docs/rules/no-onchange.md',
},
deprecated: true,
schema: [schema],
},

Expand Down

0 comments on commit a18f6b0

Please sign in to comment.