Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adding jsx-a11y linter rules #1952

Merged
merged 13 commits into from
Jun 4, 2019
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
5 changes: 4 additions & 1 deletion src-docs/src/views/color_picker/color_picker_clear.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,11 +27,14 @@ export class ColorPickerLabelAndClear extends Component {
return (
<EuiFlexGroup alignItems="center">
<EuiFlexItem grow={false}>
<label className="kuiLabel">Background color</label>
<label htmlFor="colorPicker" className="kuiLabel">
Background color
</label>
</EuiFlexItem>

<EuiFlexItem grow={false}>
<EuiColorPicker
id="colorPicker"
onChange={this.handleChange}
color={this.state.color}
/>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,14 @@ export class ColorPickerNoColorLabel extends Component {
return (
<EuiFlexGroup alignItems="center">
<EuiFlexItem grow={false}>
<label className="kuiLabel">Foreground color</label>
thompsongl marked this conversation as resolved.
Show resolved Hide resolved
<label htmlFor="colorPicker" className="kuiLabel">
Foreground color
</label>
</EuiFlexItem>

<EuiFlexItem grow={false}>
<EuiColorPicker
id="colorPicker"
onChange={this.handleChange}
color={this.state.color}
showColorLabel={false}
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
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,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Make sure to list this in the CL I guess.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah yeah I meant to comment here. Reason for this is that we put WCAG level badges inside the tooltip for color copying, which is absolutely reasonable but results in prop type warnings.


/**
* 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