Skip to content

Commit

Permalink
Adding jsx-a11y linter rules (#1952)
Browse files Browse the repository at this point in the history
* Adding jsx-a11y fixes

* address mouse-events-have-key-events errors

* eslintrc format fix

* docs examples updates

* EuiComboBox updates

* EuiTableHeaderCell update

* EuiImage update

* EuiSuperSelect updates

* more lint fixes

* #1952 CL entry
  • Loading branch information
bhavyarm authored and thompsongl committed Jun 4, 2019
1 parent 35a355b commit 85b8d85
Show file tree
Hide file tree
Showing 18 changed files with 158 additions and 49 deletions.
27 changes: 27 additions & 0 deletions .eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ module.exports = {
"plugin:prettier/recommended"
],
plugins: [
"jsx-a11y",
"prettier",
"local"
],
Expand All @@ -37,6 +38,32 @@ module.exports = {
"no-use-before-define": "off",
"quotes": ["warn", "single", "avoid-escape"],

"jsx-a11y/accessible-emoji": "error",
"jsx-a11y/alt-text": "error",
"jsx-a11y/anchor-has-content": "error",
"jsx-a11y/aria-activedescendant-has-tabindex": "error",
"jsx-a11y/aria-props": "error",
"jsx-a11y/aria-proptypes": "error",
"jsx-a11y/aria-role": "error",
"jsx-a11y/aria-unsupported-elements": "error",
"jsx-a11y/heading-has-content": "error",
"jsx-a11y/html-has-lang": "error",
"jsx-a11y/iframe-has-title": "error",
"jsx-a11y/interactive-supports-focus": "error",
"jsx-a11y/media-has-caption": "error",
"jsx-a11y/mouse-events-have-key-events": "error",
"jsx-a11y/no-access-key": "error",
"jsx-a11y/no-distracting-elements": "error",
"jsx-a11y/no-interactive-element-to-noninteractive-role": "error",
"jsx-a11y/no-noninteractive-element-interactions": "error",
"jsx-a11y/no-noninteractive-element-to-interactive-role": "error",
"jsx-a11y/no-redundant-roles": "error",
"jsx-a11y/role-has-required-aria-props": "error",
"jsx-a11y/role-supports-aria-props": "error",
"jsx-a11y/scope": "error",
"jsx-a11y/tabindex-no-positive": "error",
"jsx-a11y/label-has-associated-control": "error",

"@typescript-eslint/array-type": ["error", "array-simple"],
"@typescript-eslint/camelcase": "off",
"@typescript-eslint/class-name-casing": "off",
Expand Down
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@
- Removed TSlint and will perform all linting through ESLint ([#1950](https://github.com/elastic/eui/pull/1950))
- Added new component `EuiDelayRender` ([#1876](https://github.com/elastic/eui/pull/1876))
- Replaced `EuiColorPicker` with custom, customizable component ([#1914](https://github.com/elastic/eui/pull/1914))
- Added `jsx-a11y` `eslint` plugin and rules to match Kibana ([#1952](https://github.com/elastic/eui/pull/1952))
- Changed `EuiCopy` `beforeMessage` prop to accept `node` instead of just `string` ([#1952](https://github.com/elastic/eui/pull/1952))

**Bug fixes**

Expand Down
23 changes: 12 additions & 11 deletions src-docs/src/views/guidelines/colors.js
Original file line number Diff line number Diff line change
Expand Up @@ -283,17 +283,18 @@ color: $${color2};`;
beforeMessage={tooltipContent}
textToCopy={textToCopy}>
{copy => (
<p
onClick={copy}
style={{
backgroundColor: palette[color].rgba,
color: palette[color2].rgba,
padding: 6,
marginBottom: 2,
borderRadius: 4,
}}>
{contrastRating} &ensp; {color2}
</p>
<button type="button" onClick={copy}>
<p
style={{
backgroundColor: palette[color].rgba,
color: palette[color2].rgba,
padding: 6,
marginBottom: 2,
borderRadius: 4,
}}>
{contrastRating} &ensp; {color2}
</p>
</button>
)}
</EuiCopy>
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ exports[`EuiKeyboardAccessible adds accessibility attributes tabindex and role 1

exports[`EuiKeyboardAccessible doesn't override pre-existing accessibility attributes role 1`] = `
<div
role="submit"
role="button"
tabindex="0"
/>
`;
Expand Down
13 changes: 9 additions & 4 deletions src/components/accessibility/keyboard_accessible.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,9 @@ describe('EuiKeyboardAccessible', () => {
// @ts-ignore unused var
const component = ( // eslint-disable-line @typescript-eslint/no-unused-vars
<EuiKeyboardAccessible>
<a href="#" onClick={noop} />
<a href="#" onClick={noop}>
Click me
</a>
</EuiKeyboardAccessible>
);

Expand Down Expand Up @@ -119,7 +121,7 @@ describe('EuiKeyboardAccessible', () => {
// @ts-ignore unused var
const component = ( // eslint-disable-line @typescript-eslint/no-unused-vars
<EuiKeyboardAccessible>
<a onClick={noop} />
<a onClick={noop}>Click me</a>
</EuiKeyboardAccessible>
);

Expand All @@ -143,7 +145,10 @@ describe('EuiKeyboardAccessible', () => {
test('tabindex', () => {
const $button = render(
<EuiKeyboardAccessible>
<div onClick={noop} tabIndex={1} />
<div
onClick={noop}
tabIndex={1} // eslint-disable-line jsx-a11y/tabindex-no-positive
/>
</EuiKeyboardAccessible>
);

Expand All @@ -153,7 +158,7 @@ describe('EuiKeyboardAccessible', () => {
test('role', () => {
const $button = render(
<EuiKeyboardAccessible>
<div onClick={noop} role="submit" />
<div onClick={noop} role="button" tabIndex={0} />
</EuiKeyboardAccessible>
);

Expand Down
2 changes: 2 additions & 0 deletions src/components/color_picker/saturation.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,8 @@ export const EuiSaturation: FunctionComponent<EuiSaturationProps> = ({
token="euiSaturation.roleDescription"
default="HSV color mode saturation and value selection">
{(roleDescription: string) => (
// Unsure why this element causes errors as `tabIndex` and focus/interactivity (by extension) are accounted for.
// eslint-disable-next-line jsx-a11y/aria-activedescendant-has-tabindex, jsx-a11y/no-noninteractive-element-interactions
<div
role="application"
aria-roledescription={roleDescription}
Expand Down
13 changes: 12 additions & 1 deletion src/components/combo_box/combo_box.js
Original file line number Diff line number Diff line change
Expand Up @@ -727,13 +727,24 @@ export class EuiComboBox extends Component {
}

return (
/**
* Re: jsx-a11y/interactive-supports-focus
* Focus is managed and is placed on the textbox element (`EuiComboBoxInput`)
*
* Re: jsx-a11y/role-has-required-aria-props
* Expansion is managed and required `aria-controls` prop is placed on the textbox element (`EuiComboBoxInput`)
*
* Reference for both: https://www.w3.org/TR/2017/REC-wai-aria-1.1-20171214/#combobox,
* which verifies that this implementation follows the spec.
*/
// eslint-disable-next-line jsx-a11y/interactive-supports-focus
<div
{...rest}
className={classes}
onKeyDown={this.onKeyDown}
ref={this.comboBoxRef}
data-test-subj={dataTestSubj}
role="combobox"
role="combobox" // eslint-disable-line jsx-a11y/role-has-required-aria-props
aria-haspopup="listbox"
aria-expanded={isListOpen}>
<EuiComboBoxInput
Expand Down
4 changes: 3 additions & 1 deletion src/components/copy/copy.js
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@ export class EuiCopy extends React.Component {
} = this.props;

return (
// See `src/components/tool_tip/tool_tip.js` for explaination of below eslint-disable
// eslint-disable-next-line jsx-a11y/mouse-events-have-key-events
<EuiToolTip
content={this.state.tooltipText}
onMouseOut={this.resetTooltipText}
Expand All @@ -56,7 +58,7 @@ EuiCopy.propTypes = {
/**
* Tooltip message displayed before copy function is called.
*/
beforeMessage: PropTypes.string,
beforeMessage: PropTypes.node,

/**
* Tooltip message displayed after copy function is called that lets the user know that
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ exports[`EuiSuperSelect is rendered 1`] = `
aria-haspopup="true"
aria-label="aria-label"
aria-labelledby="undefined generated-id"
aria-selected="true"
class="euiSuperSelectControl testClass1 testClass2"
data-test-subj="test subject string"
role="option"
Expand Down Expand Up @@ -81,6 +82,7 @@ exports[`EuiSuperSelect props custom display is propagated to dropdown 1`] = `
<button
aria-haspopup="true"
aria-labelledby="undefined generated-id"
aria-selected="true"
class="euiSuperSelectControl euiSuperSelect--isOpen__button"
data-test-subj="superSelect"
role="option"
Expand Down Expand Up @@ -137,8 +139,10 @@ exports[`EuiSuperSelect props custom display is propagated to dropdown 1`] = `
</p>
<div
role="listbox"
tabindex="0"
>
<button
aria-selected="false"
class="euiContextMenuItem euiSuperSelect__item"
id="1"
role="option"
Expand All @@ -163,6 +167,7 @@ exports[`EuiSuperSelect props custom display is propagated to dropdown 1`] = `
</span>
</button>
<button
aria-selected="false"
class="euiContextMenuItem euiSuperSelect__item"
id="2"
role="option"
Expand Down Expand Up @@ -226,6 +231,7 @@ exports[`EuiSuperSelect props fullWidth is rendered 1`] = `
aria-haspopup="true"
aria-label="aria-label"
aria-labelledby="undefined generated-id"
aria-selected="true"
class="euiSuperSelectControl euiSuperSelectControl--fullWidth testClass1 testClass2"
data-test-subj="test subject string"
role="option"
Expand Down Expand Up @@ -280,6 +286,7 @@ exports[`EuiSuperSelect props more props are propogated to each option 1`] = `
<button
aria-haspopup="true"
aria-labelledby="undefined generated-id"
aria-selected="true"
class="euiSuperSelectControl euiSuperSelect--isOpen__button"
data-test-subj="superSelect"
role="option"
Expand Down Expand Up @@ -339,8 +346,10 @@ exports[`EuiSuperSelect props more props are propogated to each option 1`] = `
<div
aria-activedescendant="1"
role="listbox"
tabindex="0"
>
<button
aria-selected="true"
class="euiContextMenuItem euiSuperSelect__item euiContextMenuItem-isDisabled"
disabled=""
id="1"
Expand All @@ -366,6 +375,7 @@ exports[`EuiSuperSelect props more props are propogated to each option 1`] = `
</span>
</button>
<button
aria-selected="false"
class="euiContextMenuItem euiSuperSelect__item"
data-test-subj="option two"
id="2"
Expand Down Expand Up @@ -550,6 +560,7 @@ exports[`EuiSuperSelect props more props are propogated to each option 2`] = `
<button
aria-haspopup="true"
aria-labelledby="undefined generated-id"
aria-selected={true}
className="euiSuperSelectControl euiSuperSelect--isOpen__button"
data-test-subj="superSelect"
onChange={[Function]}
Expand Down Expand Up @@ -704,8 +715,10 @@ exports[`EuiSuperSelect props more props are propogated to each option 2`] = `
<div
aria-activedescendant="1"
role="listbox"
tabindex="0"
>
<button
aria-selected="true"
class="euiContextMenuItem euiSuperSelect__item euiContextMenuItem-isDisabled"
disabled=""
id="1"
Expand All @@ -731,6 +744,7 @@ exports[`EuiSuperSelect props more props are propogated to each option 2`] = `
</span>
</button>
<button
aria-selected="false"
class="euiContextMenuItem euiSuperSelect__item"
data-test-subj="option two"
id="2"
Expand Down Expand Up @@ -789,8 +803,10 @@ exports[`EuiSuperSelect props more props are propogated to each option 2`] = `
<div
aria-activedescendant="1"
role="listbox"
tabindex="0"
>
<button
aria-selected="true"
class="euiContextMenuItem euiSuperSelect__item euiContextMenuItem-isDisabled"
disabled=""
id="1"
Expand All @@ -816,6 +832,7 @@ exports[`EuiSuperSelect props more props are propogated to each option 2`] = `
</span>
</button>
<button
aria-selected="false"
class="euiContextMenuItem euiSuperSelect__item"
data-test-subj="option two"
id="2"
Expand Down Expand Up @@ -913,8 +930,10 @@ exports[`EuiSuperSelect props more props are propogated to each option 2`] = `
<div
aria-activedescendant="1"
role="listbox"
tabIndex="0"
>
<EuiContextMenuItem
aria-selected={true}
buttonRef={[Function]}
className="euiSuperSelect__item"
disabled={true}
Expand All @@ -933,6 +952,7 @@ exports[`EuiSuperSelect props more props are propogated to each option 2`] = `
toolTipPosition="right"
>
<button
aria-selected={true}
className="euiContextMenuItem euiSuperSelect__item euiContextMenuItem-isDisabled"
disabled={true}
id="1"
Expand Down Expand Up @@ -979,6 +999,7 @@ exports[`EuiSuperSelect props more props are propogated to each option 2`] = `
</button>
</EuiContextMenuItem>
<EuiContextMenuItem
aria-selected={false}
buttonRef={[Function]}
className="euiSuperSelect__item"
data-test-subj="option two"
Expand All @@ -997,6 +1018,7 @@ exports[`EuiSuperSelect props more props are propogated to each option 2`] = `
toolTipPosition="right"
>
<button
aria-selected={false}
className="euiContextMenuItem euiSuperSelect__item"
data-test-subj="option two"
id="2"
Expand Down Expand Up @@ -1101,6 +1123,7 @@ exports[`EuiSuperSelect props options are rendered when select is open 1`] = `
<button
aria-haspopup="true"
aria-labelledby="undefined generated-id"
aria-selected="true"
class="euiSuperSelectControl euiSuperSelect--isOpen__button"
data-test-subj="superSelect"
role="option"
Expand Down Expand Up @@ -1157,8 +1180,10 @@ exports[`EuiSuperSelect props options are rendered when select is open 1`] = `
</p>
<div
role="listbox"
tabindex="0"
>
<button
aria-selected="false"
class="euiContextMenuItem euiSuperSelect__item"
id="1"
role="option"
Expand All @@ -1183,6 +1208,7 @@ exports[`EuiSuperSelect props options are rendered when select is open 1`] = `
</span>
</button>
<button
aria-selected="false"
class="euiContextMenuItem euiSuperSelect__item"
id="2"
role="option"
Expand Down Expand Up @@ -1245,6 +1271,7 @@ exports[`EuiSuperSelect props select component is rendered 1`] = `
<button
aria-haspopup="true"
aria-labelledby="undefined generated-id"
aria-selected="true"
class="euiSuperSelectControl"
role="option"
type="button"
Expand Down Expand Up @@ -1298,6 +1325,7 @@ exports[`EuiSuperSelect props valueSelected is rendered 1`] = `
<button
aria-haspopup="true"
aria-labelledby="undefined generated-id"
aria-selected="true"
class="euiSuperSelectControl"
role="option"
type="button"
Expand Down
Loading

0 comments on commit 85b8d85

Please sign in to comment.