]> source.dussan.org Git - sonarqube.git/commitdiff
Make Checkbox component accessible
authorWouter Admiraal <wouter.admiraal@sonarsource.com>
Thu, 6 Jun 2019 09:30:56 +0000 (11:30 +0200)
committersonartech <sonartech@sonarsource.com>
Fri, 28 Jun 2019 06:45:39 +0000 (08:45 +0200)
server/sonar-web/src/main/js/components/controls/Checkbox.tsx
server/sonar-web/src/main/js/components/controls/__tests__/Checkbox-test.tsx
server/sonar-web/src/main/js/components/controls/__tests__/__snapshots__/Checkbox-test.tsx.snap

index a1df816ed01508168f3266c0188cb5dd1a3cb646..b73e3003d3b37678a3574ae8eef965ca6516f815 100644 (file)
@@ -31,6 +31,7 @@ interface Props {
   onCheck: (checked: boolean, id?: string) => void;
   right?: boolean;
   thirdState?: boolean;
+  title?: string;
 }
 
 export default class Checkbox extends React.PureComponent<Props> {
@@ -47,23 +48,26 @@ export default class Checkbox extends React.PureComponent<Props> {
   };
 
   render() {
-    const { children, disabled, loading, right } = this.props;
+    const { checked, children, disabled, id, loading, right, thirdState, title } = this.props;
     const className = classNames('icon-checkbox', {
-      'icon-checkbox-checked': this.props.checked,
-      'icon-checkbox-single': this.props.thirdState,
+      'icon-checkbox-checked': checked,
+      'icon-checkbox-single': thirdState,
       'icon-checkbox-disabled': disabled
     });
 
     if (children) {
       return (
         <a
+          aria-checked={checked}
           className={classNames('link-checkbox', this.props.className, {
             note: disabled,
             disabled
           })}
           href="#"
-          id={this.props.id}
-          onClick={this.handleClick}>
+          id={id}
+          onClick={this.handleClick}
+          role="checkbox"
+          title={title}>
           {right && children}
           <DeferredSpinner loading={Boolean(loading)}>
             <i className={className} />
@@ -79,10 +83,13 @@ export default class Checkbox extends React.PureComponent<Props> {
 
     return (
       <a
+        aria-checked={checked}
         className={classNames(className, this.props.className)}
         href="#"
-        id={this.props.id}
+        id={id}
         onClick={this.handleClick}
+        role="checkbox"
+        title={title}
       />
     );
   }
index f089b43dfa585cf762bee9a7983f80108b85dd09..8353052c830300ff15320d27fdb568c6294ed839 100644 (file)
@@ -22,14 +22,21 @@ import * as React from 'react';
 import Checkbox from '../Checkbox';
 import { click } from '../../../helpers/testUtils';
 
+it('should render', () => {
+  const checkbox = shallow(<Checkbox checked={true} onCheck={() => {}} title="Title value" />);
+  expect(checkbox).toMatchSnapshot();
+});
+
 it('should render unchecked', () => {
   const checkbox = shallow(<Checkbox checked={false} onCheck={() => true} />);
   expect(checkbox.is('.icon-checkbox-checked')).toBeFalsy();
+  expect(checkbox.prop('aria-checked')).toBe(false);
 });
 
 it('should render checked', () => {
   const checkbox = shallow(<Checkbox checked={true} onCheck={() => true} />);
   expect(checkbox.is('.icon-checkbox-checked')).toBeTruthy();
+  expect(checkbox.prop('aria-checked')).toBe(true);
 });
 
 it('should render disabled', () => {
index f733f88a91618b6b47675fd6935c9fbf88371512..69c0c60af8c557f6957628b344c817781f61ae4d 100644 (file)
@@ -1,9 +1,22 @@
 // Jest Snapshot v1, https://goo.gl/fbAQLP
 
+exports[`should render 1`] = `
+<a
+  aria-checked={true}
+  className="icon-checkbox icon-checkbox-checked"
+  href="#"
+  onClick={[Function]}
+  role="checkbox"
+  title="Title value"
+/>
+`;
+
 exports[`should render the checkbox on the right 1`] = `
 <a
+  aria-checked={true}
   className="icon-checkbox icon-checkbox-checked"
   href="#"
   onClick={[Function]}
+  role="checkbox"
 />
 `;