forked from jsx-eslint/eslint-plugin-jsx-a11y
-
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[Fix]
no-redundant-roles
: Refine implicit role of select
to inclu…
…de `combobox` scenarios Encode implicit roles for `select` elements based on roles defined in https://www.w3.org/TR/html-aria/#el-select - `select` (with a multiple attribute or a size attribute having value greater than 1) will have the implicit role 'listbox' - `select` (with NO multiple attribute and NO size attribute having value greater than 1) will have the implicit role 'combobox' Fixes jsx-eslint#949
- Loading branch information
Showing
3 changed files
with
193 additions
and
4 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,158 @@ | ||
import test from 'tape'; | ||
|
||
import JSXAttributeMock from '../../../../__mocks__/JSXAttributeMock'; | ||
import getImplicitRoleForSelect from '../../../../src/util/implicitRoles/select'; | ||
|
||
test('isAbstractRole', (t) => { | ||
t.test('works for combobox', (st) => { | ||
st.equal( | ||
getImplicitRoleForSelect([]), | ||
'combobox', | ||
'defaults to combobox', | ||
); | ||
|
||
st.equal( | ||
getImplicitRoleForSelect([JSXAttributeMock('multiple', null)]), | ||
'combobox', | ||
'is combobox when multiple attribute is set to not be present', | ||
); | ||
|
||
st.equal( | ||
getImplicitRoleForSelect([JSXAttributeMock('multiple', undefined)]), | ||
'combobox', | ||
'is combobox when multiple attribute is set to not be present', | ||
); | ||
|
||
st.equal( | ||
getImplicitRoleForSelect([JSXAttributeMock('multiple', false)]), | ||
'combobox', | ||
'is combobox when multiple attribute is set to boolean false', | ||
); | ||
|
||
st.equal( | ||
getImplicitRoleForSelect([JSXAttributeMock('multiple', '')]), | ||
'combobox', | ||
'is listbox when multiple attribute is falsey (empty string)', | ||
); | ||
|
||
st.equal( | ||
getImplicitRoleForSelect([JSXAttributeMock('size', '1')]), | ||
'combobox', | ||
'is combobox when size is not greater than 1', | ||
); | ||
|
||
st.equal( | ||
getImplicitRoleForSelect([JSXAttributeMock('size', 1)]), | ||
'combobox', | ||
'is combobox when size is not greater than 1', | ||
); | ||
|
||
st.equal( | ||
getImplicitRoleForSelect([JSXAttributeMock('size', 0)]), | ||
'combobox', | ||
'is combobox when size is not greater than 1', | ||
); | ||
|
||
st.equal( | ||
getImplicitRoleForSelect([JSXAttributeMock('size', '0')]), | ||
'combobox', | ||
'is combobox when size is not greater than 1', | ||
); | ||
|
||
st.equal( | ||
getImplicitRoleForSelect([JSXAttributeMock('size', '-1')]), | ||
'combobox', | ||
'is combobox when size is not greater than 1', | ||
); | ||
|
||
st.equal( | ||
getImplicitRoleForSelect([JSXAttributeMock('size', '')]), | ||
'combobox', | ||
'is combobox when size is a valid number', | ||
); | ||
|
||
st.equal( | ||
getImplicitRoleForSelect([JSXAttributeMock('size', 'true')]), | ||
'combobox', | ||
'is combobox when size is a valid number', | ||
); | ||
|
||
st.equal( | ||
getImplicitRoleForSelect([JSXAttributeMock('size', true)]), | ||
'combobox', | ||
'is combobox when size is a valid number', | ||
); | ||
|
||
st.equal( | ||
getImplicitRoleForSelect([JSXAttributeMock('size', NaN)]), | ||
'combobox', | ||
'is combobox when size is a valid number', | ||
); | ||
|
||
st.equal( | ||
getImplicitRoleForSelect([JSXAttributeMock('size', '')]), | ||
'combobox', | ||
'is combobox when size is a valid number', | ||
); | ||
|
||
st.equal( | ||
getImplicitRoleForSelect([JSXAttributeMock('size', undefined)]), | ||
'combobox', | ||
'is combobox when size is a valid number', | ||
); | ||
|
||
st.equal( | ||
getImplicitRoleForSelect([JSXAttributeMock('size', false)]), | ||
'combobox', | ||
'is combobox when size is a valid number', | ||
); | ||
|
||
st.end(); | ||
}); | ||
|
||
t.test('works for listbox based on multiple attribute', (st) => { | ||
st.equal( | ||
getImplicitRoleForSelect([JSXAttributeMock('multiple', true)]), | ||
'listbox', | ||
'is listbox when multiple is boolean true', | ||
); | ||
|
||
st.equal( | ||
getImplicitRoleForSelect([JSXAttributeMock('multiple', 'multiple')]), | ||
'listbox', | ||
'is listbox when multiple is truthy (string)', | ||
); | ||
|
||
st.equal( | ||
getImplicitRoleForSelect([JSXAttributeMock('multiple', 'true')]), | ||
'listbox', | ||
'is listbox when multiple is truthy (string) - React will warn about this', | ||
); | ||
|
||
st.end(); | ||
}); | ||
|
||
t.test('works for listbox based on size attribute', (st) => { | ||
st.equal( | ||
getImplicitRoleForSelect([JSXAttributeMock('size', 2)]), | ||
'listbox', | ||
'is listbox when size is greater than 1', | ||
); | ||
|
||
st.equal( | ||
getImplicitRoleForSelect([JSXAttributeMock('size', '3')]), | ||
'listbox', | ||
'is listbox when size is greater than 1', | ||
); | ||
|
||
st.equal( | ||
getImplicitRoleForSelect([JSXAttributeMock('size', 40)]), | ||
'listbox', | ||
'is listbox when size is greater than 1', | ||
); | ||
|
||
st.end(); | ||
}); | ||
|
||
t.end(); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,18 @@ | ||
import { getProp, getLiteralPropValue } from 'jsx-ast-utils'; | ||
|
||
/** | ||
* Returns the implicit role for a select tag. | ||
* Returns the implicit role for a select tag depending on attributes. | ||
* | ||
* @see https://www.w3.org/TR/html-aria/#el-select | ||
*/ | ||
export default function getImplicitRoleForSelect() { | ||
return 'listbox'; | ||
export default function getImplicitRoleForSelect(attributes) { | ||
const multiple = getProp(attributes, 'multiple'); | ||
if (multiple && getLiteralPropValue(multiple)) { | ||
return 'listbox'; | ||
} | ||
|
||
const size = getProp(attributes, 'size'); | ||
const sizeValue = size && getLiteralPropValue(size); | ||
|
||
return sizeValue > 1 ? 'listbox' : 'combobox'; | ||
} |