Skip to content

Commit c1e47c1

Browse files
committed
[fix] Refine implicit role of select to include 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
1 parent e5dda96 commit c1e47c1

File tree

2 files changed

+21
-3
lines changed

2 files changed

+21
-3
lines changed

__tests__/src/rules/no-redundant-roles-test.js

+7
Original file line numberDiff line numberDiff line change
@@ -41,12 +41,19 @@ const alwaysValid = [
4141
{ code: '<MyComponent role="button" />' },
4242
{ code: '<button role={`${foo}button`} />' },
4343
{ code: '<Button role={`${foo}button`} />', settings: componentsSettings },
44+
{ code: '<select role="menu"><option>1</option><option>2</option></select>' },
4445
];
4546

4647
const neverValid = [
4748
{ code: '<button role="button" />', errors: [expectedError('button', 'button')] },
4849
{ code: '<body role="DOCUMENT" />', errors: [expectedError('body', 'document')] },
4950
{ code: '<Button role="button" />', settings: componentsSettings, errors: [expectedError('button', 'button')] },
51+
{ code: '<select role="combobox" size />', errors: [expectedError('select', 'combobox')] },
52+
{ code: '<select role="combobox" size={1} />', errors: [expectedError('select', 'combobox')] },
53+
{ code: '<select role="combobox"><option>1</option><option>2</option></select>', errors: [expectedError('select', 'combobox')] },
54+
{ code: '<select role="listbox" size="3" />', errors: [expectedError('select', 'listbox')] },
55+
{ code: '<select role="listbox" size={2} />', errors: [expectedError('select', 'listbox')] },
56+
{ code: '<select role="listbox" multiple><option>1</option><option>2</option></select>', errors: [expectedError('select', 'listbox')] },
5057
];
5158

5259
ruleTester.run(`${ruleName}:recommended`, rule, {

src/util/implicitRoles/select.js

+14-3
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,17 @@
1+
import { getProp, getLiteralPropValue } from 'jsx-ast-utils';
2+
13
/**
2-
* Returns the implicit role for a select tag.
4+
* Returns the implicit role for a select tag depending on attributes.
5+
*
6+
* @see https://www.w3.org/TR/html-aria/#el-select
37
*/
4-
export default function getImplicitRoleForSelect() {
5-
return 'listbox';
8+
export default function getImplicitRoleForSelect(attributes) {
9+
const multiple = getProp(attributes, 'multiple');
10+
if (multiple) return 'listbox';
11+
12+
const size = getProp(attributes, 'size');
13+
const sizeValue = size && getLiteralPropValue(size);
14+
if (sizeValue && (Number(sizeValue) > 1)) return 'listbox';
15+
16+
return 'combobox';
617
}

0 commit comments

Comments
 (0)