Upgrade eslint and react
diff --git a/.eslintrc b/.eslintrc
deleted file mode 100644
index e6ac5a8..0000000
--- a/.eslintrc
+++ /dev/null
@@ -1,50 +0,0 @@
-{
-  "env": {
-    "es6": true,
-    "node": true,
-    "browser": true
-  },
-  "parser": "babel-eslint",
-  "parserOptions": {
-    "ecmaFeatures": {
-      "jsx": true
-    }
-  },
-  "plugins": [
-    "react"
-  ],
-  "rules": {
-    "array-callback-return": 2,
-    "brace-style": [2, "1tbs"],
-    "camelcase": [2, { "properties": "always" }],
-    "comma-dangle": [2, "never"],
-    "comma-style": [2, "last"],
-    "eol-last": 2,
-    "indent": [2, 2, { "SwitchCase": 1 }],
-    "jsx-quotes": [2, "prefer-double"],
-    "key-spacing": [2, { "beforeColon": false, "afterColon": true }],
-    "keyword-spacing": 2,
-    "linebreak-style": [2, "unix"],
-    "no-cond-assign": [2, "always"],
-    "no-console": 2,
-    "no-multiple-empty-lines": [2, { "max": 1 }],
-    "no-spaced-func": 2,
-    "no-trailing-spaces": 2,
-    "no-unused-vars": [2, {"vars": "all", "args": "after-used"}],
-    "no-whitespace-before-property": 2,
-    "newline-after-var": [2, "always"],
-    "object-curly-spacing": [2, "always"],
-    "prefer-rest-params": 2,
-    "quote-props": [2, "as-needed"],
-    "quotes": [2, "single"],
-    "semi": [2, "always"],
-    "space-before-blocks": [2, "always"],
-    "space-before-function-paren": [2, "never"],
-    "space-in-parens": [2, "never"],
-    "template-curly-spacing": [2, "never"],
-
-    "react/jsx-boolean-value": [2, "always"],
-    "react/jsx-uses-react": 2,
-    "react/jsx-uses-vars": 2
-  }
-}
diff --git a/.eslintrc.js b/.eslintrc.js
new file mode 100644
index 0000000..d0b2318
--- /dev/null
+++ b/.eslintrc.js
@@ -0,0 +1,119 @@
+module.exports = {
+  env: {
+    es6: true,
+    node: true,
+    browser: true,
+    mocha: true
+  },
+  parser: 'babel-eslint',
+  plugins: [
+    'react'
+  ],
+  extends: [
+    'eslint:recommended'
+  ],
+  rules: {
+    'array-callback-return': 2,
+    'brace-style': [2, '1tbs'],
+    'camelcase': [2, { 'properties': 'always' }],
+    'comma-dangle': [2, 'never'],
+    'comma-style': [2, 'last'],
+    'eol-last': 2,
+    'func-call-spacing': 2,
+    'indent': [2, 2, { 'SwitchCase': 1 }],
+    'key-spacing': [2, { 'beforeColon': false, 'afterColon': true }],
+    'keyword-spacing': 2,
+    'linebreak-style': [2, 'unix'],
+    'no-cond-assign': [2, 'always'],
+    'no-console': 2,
+    'no-global-assign': 2,
+    'no-multiple-empty-lines': [2, { 'max': 1 }],
+    'no-restricted-properties': [2,
+      {
+        object: 'describe',
+        property: 'only',
+        message: 'Please run all tests!'
+      },
+      {
+        object: 'describe',
+        property: 'skip',
+        message: 'Please run all tests!'
+      },
+      {
+        object: 'it',
+        property: 'only',
+        message: 'Please run all tests!'
+      },
+      {
+        object: 'it',
+        property: 'skip',
+        message: 'Please run all tests!'
+      }
+    ],
+    'no-template-curly-in-string': 2,
+    'no-trailing-spaces': 2,
+    'no-unused-vars': 2,
+    'no-whitespace-before-property': 2,
+    'newline-after-var': [2, 'always'],
+    'object-curly-spacing': [2, 'always'],
+    'prefer-rest-params': 2,
+    'quote-props': [2, 'as-needed'],
+    'quotes': [2, 'single'],
+    'semi': [2, 'always'],
+    'space-before-blocks': [2, 'always'],
+    'space-before-function-paren': [2, 'never'],
+    'space-in-parens': [2, 'never'],
+    'template-curly-spacing': [2, 'never'],
+
+    'react/display-name': 0,
+    'react/forbid-prop-types': 0,
+    'react/no-comment-textnodes': 0,
+    'react/no-danger': 2,
+    'react/no-danger-with-children': 2,
+    'react/no-deprecated': 2,
+    'react/no-did-mount-set-state': 2,
+    'react/no-did-update-set-state': 2,
+    'react/no-direct-mutation-state': 2,
+    'react/no-find-dom-node': 2,
+    'react/no-is-mounted': 2,
+    'react/no-multi-comp': [2, { 'ignoreStateless': true }],
+    'react/no-render-return-value': 2,
+    'react/no-set-state': 0,
+    'react/no-string-refs': 2,
+    'react/no-unknown-property': 2,
+    'react/no-unused-prop-types': 0, // https://github.com/yannickcr/eslint-plugin-react/pull/835
+    'react/prefer-es6-class': [2, 'always'],
+    'react/prefer-stateless-function': 2,
+    'react/prop-types': 2,
+    'react/react-in-jsx-scope': 2,
+    'react/require-optimization': 0,
+    'react/require-render-return': 2,
+    'react/self-closing-comp': 2,
+    'react/sort-comp': 2,
+    'react/sort-prop-types': 0,
+    'react/style-prop-object': 2,
+
+    'react/jsx-boolean-value': [2, 'always'],
+    'react/jsx-closing-bracket-location': [2, 'tag-aligned'],
+    'react/jsx-curly-spacing': [2, 'never', { 'allowMultiline': true }],
+    'react/jsx-equals-spacing': [2, 'never'],
+    'react/jsx-filename-extension': [2, { 'extensions': ['.js'] }],
+    'react/jsx-first-prop-new-line': [2, 'multiline'],
+    'react/jsx-handler-names': 0,
+    'react/jsx-indent': [2, 2],
+    'react/jsx-indent-props': [2, 2],
+    'react/jsx-key': 2,
+    'react/jsx-max-props-per-line': 0,
+    'react/jsx-no-bind': 2,
+    'react/jsx-no-duplicate-props': 2,
+    'react/jsx-no-literals': 0,
+    'react/jsx-no-target-blank': 2,
+    'react/jsx-no-undef': 2,
+    'react/jsx-pascal-case': 2,
+    'react/jsx-sort-props': 0,
+    'react/jsx-space-before-closing': [2, 'always'],
+    'react/jsx-uses-react': 2,
+    'react/jsx-uses-vars': 2,
+    'react/jsx-wrap-multilines': 2
+  }
+};
diff --git a/.gitignore b/.gitignore
index 802ddd2..ed4203d 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,3 +1,4 @@
 node_modules
 npm-debug.log
 dist
+yarn.lock
diff --git a/package.json b/package.json
index 7847e28..785645c 100644
--- a/package.json
+++ b/package.json
@@ -22,8 +22,8 @@
     "es6-promise": "^3.1.2",
     "isomorphic-fetch": "^2.2.1",
     "jsonp": "^0.2.0",
-    "react": "^0.14.7",
-    "react-dom": "^0.14.7",
+    "react": "^15.4.1",
+    "react-dom": "^15.4.1",
     "react-redux": "^4.4.0",
     "redux": "^3.3.1",
     "redux-thunk": "^1.0.3"
@@ -31,7 +31,7 @@
   "devDependencies": {
     "autoprefixer-loader": "^3.1.0",
     "babel-core": "^6.5.2",
-    "babel-eslint": "^5.0.0-beta9",
+    "babel-eslint": "^7.1.1",
     "babel-loader": "^6.2.2",
     "babel-plugin-react-transform": "^2.0.0",
     "babel-preset-es2015": "^6.5.0",
@@ -39,8 +39,8 @@
     "babel-preset-stage-0": "^6.5.0",
     "chai": "^3.5.0",
     "css-loader": "^0.23.1",
-    "eslint": "^2.0.0",
-    "eslint-plugin-react": "^3.16.1",
+    "eslint": "^3.12.2",
+    "eslint-plugin-react": "^6.8.0",
     "express": "^4.13.4",
     "extract-text-webpack-plugin": "^1.0.1",
     "less": "^2.6.0",
diff --git a/src/components/App/App.js b/src/components/App/App.js
index a178047..58f2b6c 100644
--- a/src/components/App/App.js
+++ b/src/components/App/App.js
@@ -40,9 +40,11 @@
       <div className={styles.previewContainer}>
         {
           isUserInputValid &&
-            <Preview accessibilityLevel={accessibilityLevel}
-                     accessibleContrast={accessibleContrastRatio}
-                     isAccessible={isAccessible} />
+            <Preview
+              accessibilityLevel={accessibilityLevel}
+              accessibleContrast={accessibleContrastRatio}
+              isAccessible={isAccessible}
+            />
         }
       </div>
       <HowItWorks />
diff --git a/src/components/App/components/ComingSoon/ComingSoon.js b/src/components/App/components/ComingSoon/ComingSoon.js
index 6f3a75a..3662441 100644
--- a/src/components/App/components/ComingSoon/ComingSoon.js
+++ b/src/components/App/components/ComingSoon/ComingSoon.js
@@ -18,9 +18,13 @@
           <p>
             To find out more, or if you have any feedback, get in touch with
             us on&nbsp;
-            <a className={styles.link} target="_blank"
-               href="https://accessible-colors.herokuapp.com"
-               data-link-name="Coming soon - Slack">
+            <a
+              className={styles.link}
+              target="_blank"
+              rel="noopener noreferrer"
+              href="https://accessible-colors.herokuapp.com"
+              data-link-name="Coming soon - Slack"
+            >
               Slack
             </a>.
           </p>
diff --git a/src/components/App/components/Footer/Footer.js b/src/components/App/components/Footer/Footer.js
index 9f1fba9..9f0c7dc 100644
--- a/src/components/App/components/Footer/Footer.js
+++ b/src/components/App/components/Footer/Footer.js
@@ -11,22 +11,36 @@
             Brought to you by
           </h3>
           <p className={styles.content}>
-            <a className={styles.link} target="_blank"
-               href="https://twitter.com/moroshko"
-               data-link-name="Footer - Misha Moroshko">
-              <img className={styles.image}
-                   src="https://www.gravatar.com/avatar/7ee5d55919c272eddef98dbe16f5cb09?s=54"
-                   alt="" role="presentation" />
+            <a
+              className={styles.link}
+              target="_blank"
+              rel="noopener noreferrer"
+              href="https://twitter.com/moroshko"
+              data-link-name="Footer - Misha Moroshko"
+            >
+              <img
+                className={styles.image}
+                src="https://www.gravatar.com/avatar/7ee5d55919c272eddef98dbe16f5cb09?s=54"
+                alt=""
+                role="presentation"
+              />
               <span className={styles.linkText}>Misha Moroshko</span>
             </a>
           </p>
           <p className={styles.content}>
-            <a className={styles.link} target="_blank"
-               href="https://twitter.com/vedranio"
-               data-link-name="Footer - Vedran Arnautovic">
-              <img className={styles.image}
-                   src="https://www.gravatar.com/avatar/6fa8f8433861ca68ed44cc79001554d6?s=54"
-                   alt="" role="presentation" />
+            <a
+              className={styles.link}
+              target="_blank"
+              rel="noopener noreferrer"
+              href="https://twitter.com/vedranio"
+              data-link-name="Footer - Vedran Arnautovic"
+            >
+              <img
+                className={styles.image}
+                src="https://www.gravatar.com/avatar/6fa8f8433861ca68ed44cc79001554d6?s=54"
+                alt=""
+                role="presentation"
+              />
               <span className={styles.linkText}>Vedran Arnautovic</span>
             </a>
           </p>
@@ -36,9 +50,13 @@
             Have feature ideas?
           </h3>
           <p className={styles.content}>
-            <a className={styles.link} target="_blank"
-               href="https://accessible-colors.herokuapp.com"
-               data-link-name="Footer - Chat to us on Slack">
+            <a
+              className={styles.link}
+              target="_blank"
+              rel="noopener noreferrer"
+              href="https://accessible-colors.herokuapp.com"
+              data-link-name="Footer - Chat to us on Slack"
+            >
               <span className={styles.icon + ' icon-circle-slack'} />
               <span className={styles.linkText}>Chat to us on Slack</span>
             </a>
diff --git a/src/components/App/components/Graph/Graph.js b/src/components/App/components/Graph/Graph.js
index 11a0d29..e56d58e 100644
--- a/src/components/App/components/Graph/Graph.js
+++ b/src/components/App/components/Graph/Graph.js
@@ -27,12 +27,20 @@
   render() {
     const { isBackgroundColor, colorChannel, backgroundColor, textColor,
             accessibleContrast } = this.props;
+    const accessibleAreaStyle = {
+      left: 5 * (accessibleContrast - 1) + '%',
+      width: (100 - 5 * (accessibleContrast - 1)) + '%'
+    };
     const yAxisName = (isBackgroundColor ? 'Background' : 'Text') +
                       ' color ' + colorChannel;
     const yMaxValue = (colorChannel === 'hue' ? 360 : 100);
     const color = (isBackgroundColor ? backgroundColor: textColor);
     const otherColor = (isBackgroundColor ? textColor: backgroundColor);
     const yValue = parseFloat(color[colorChannel]);
+    const currentValueStyle = {
+      top: 100 * (1 - yValue / yMaxValue) + '%',
+      backgroundColor: str2sixDigitHex(color.value)
+    };
 
     let data = [];
 
@@ -46,32 +54,41 @@
     return (
       <div className={styles.container}>
         <div className={styles.coordinates}>
-          <div className={styles.notAccessibleArea}
-               style={{ width: 5 * (accessibleContrast - 1) + '%' }} />
-          <div className={styles.accessibleArea}
-               style={{ left: 5 * (accessibleContrast - 1) + '%',
-                        width: (100 - 5 * (accessibleContrast - 1)) + '%' }} />
+          <div
+            className={styles.notAccessibleArea}
+            style={{ width: 5 * (accessibleContrast - 1) + '%' }}
+          />
+          <div
+            className={styles.accessibleArea}
+            style={accessibleAreaStyle}
+          />
           <div className={styles.xAxis} />
           <div className={styles.xAxisArrow} />
           <div className={styles.xAxisName}>Contrast</div>
           <div className={styles.xAxisMinValue}>1</div>
-          <div className={styles.xAxisAccessibleContrast}
-               style={{ left: 5 * (accessibleContrast - 1) - 1 + '%' }}>{accessibleContrast}</div>
+          <div
+            className={styles.xAxisAccessibleContrast}
+            style={{ left: 5 * (accessibleContrast - 1) - 1 + '%' }}
+          >
+            {accessibleContrast}
+          </div>
           <div className={styles.xAxisMaxValue}>21</div>
           <div className={styles.yAxis} />
           <div className={styles.yAxisArrow} />
           <div className={styles.yAxisName}>{yAxisName}</div>
           <div className={styles.yAxisMinValue}>0</div>
           <div className={styles.yAxisMaxValue}>{yMaxValue}</div>
-          <div className={styles.currentValue}
-               style={{ top: 100 * (1 - yValue / yMaxValue) + '%',
-                        backgroundColor: str2sixDigitHex(color.value) }} />
+          <div
+            className={styles.currentValue}
+            style={currentValueStyle}
+          />
           {
             data.map(({ x, y }) =>
-              <div className={styles.dataPoint}
-                   style={{ left: 5 * (x - 1) + '%',
-                            top: 100 * (1 - y / yMaxValue) + '%' }}
-                   key={x + ' ' + y} />
+              <div
+                className={styles.dataPoint}
+                style={{ left: 5 * (x - 1) + '%', top: 100 * (1 - y / yMaxValue) + '%' }}
+                key={x + ' ' + y}
+              />
             )
           }
         </div>
diff --git a/src/components/App/components/Header/Header.js b/src/components/App/components/Header/Header.js
index 39fe82f..be16e81 100644
--- a/src/components/App/components/Header/Header.js
+++ b/src/components/App/components/Header/Header.js
@@ -50,22 +50,30 @@
             Accessible colors
           </h1>
           <div className={styles.socialButtons}>
-            <SocialButton icon="icon-circle-github" count={githubStars}
-                          color="#212121" hoverColor="#4078c0"
-                          linkProps={{
-                            href: GITHUB_HREF,
-                            target: '_blank',
-                            ariaLabel: `Star ${REPO} on GitHub`,
-                            'data-link-name': 'Header - GitHub'
-                          }} />
-            <SocialButton icon="icon-circle-twitter" count={twitterCount}
-                          color="#212121" hoverColor="#55acee"
-                          linkProps={{
-                            className: styles.twitterButton,
-                            href: TWITTER_HREF,
-                            ariaLabel: `Share ${DOMAIN} on Twitter`,
-                            'data-link-name': 'Header - Twitter'
-                          }} />
+            <SocialButton
+              icon="icon-circle-github"
+              count={githubStars}
+              color="#212121"
+              hoverColor="#4078c0"
+              linkProps={{
+                href: GITHUB_HREF,
+                target: '_blank',
+                'aria-label': `Star ${REPO} on GitHub`,
+                'data-link-name': 'Header - GitHub'
+              }}
+            />
+            <SocialButton
+              icon="icon-circle-twitter"
+              count={twitterCount}
+              color="#212121"
+              hoverColor="#55acee"
+              linkProps={{
+                className: styles.twitterButton,
+                href: TWITTER_HREF,
+                'aria-label': `Share ${DOMAIN} on Twitter`,
+                'data-link-name': 'Header - Twitter'
+              }}
+            />
           </div>
         </div>
       </header>
diff --git a/src/components/App/components/Header/components/SocialButton/SocialButton.js b/src/components/App/components/Header/components/SocialButton/SocialButton.js
index 4e770ef..dc19ba3 100644
--- a/src/components/App/components/Header/components/SocialButton/SocialButton.js
+++ b/src/components/App/components/Header/components/SocialButton/SocialButton.js
@@ -11,21 +11,33 @@
     hoverColor: PropTypes.string.isRequired
   };
 
-  setColor(color) {
-    this.refs.link.style.color = color;
-  }
+  storeLinkElement = element => {
+    if (element !== null) {
+      this.link = element;
+    }
+  };
+
+  onMouseEnter = () => {
+    this.link.style.color = this.props.hoverColor;
+  };
+
+  onMouseLeave = () => {
+    this.link.style.color = this.props.color;
+  };
 
   render() {
-    const { linkProps, icon, count, color, hoverColor } = this.props;
+    const { linkProps, icon, count, color } = this.props;
     const className = (linkProps.className || '') + ' ' + styles.container;
 
     return (
-      <a {...linkProps}
-         className={className}
-         style={{ color }}
-         onMouseEnter={() => this.setColor(hoverColor)}
-         onMouseLeave={() => this.setColor(color)}
-         ref="link">
+      <a
+        {...linkProps}
+        className={className}
+        style={{ color }}
+        onMouseEnter={this.onMouseEnter}
+        onMouseLeave={this.onMouseLeave}
+        ref={this.storeLinkElement}
+      >
         <span className={styles.icon + ' ' + icon} />
         <span className={styles.count}>{count}</span>
       </a>
diff --git a/src/components/App/components/HowItWorks/HowItWorks.js b/src/components/App/components/HowItWorks/HowItWorks.js
index ac59c89..b53097c 100644
--- a/src/components/App/components/HowItWorks/HowItWorks.js
+++ b/src/components/App/components/HowItWorks/HowItWorks.js
@@ -12,20 +12,26 @@
         <div className={styles.content}>
           <p>
             We evaluate your color combination using the&nbsp;
-            <a className={styles.link}
-               href="https://www.w3.org/TR/UNDERSTANDING-WCAG20/visual-audio-contrast-contrast.html"
-               target="_blank"
-               data-link-name="How it works - WCAG 2.0 guidelines for contrast accessibility">
+            <a
+              className={styles.link}
+              href="https://www.w3.org/TR/UNDERSTANDING-WCAG20/visual-audio-contrast-contrast.html"
+              target="_blank"
+              rel="noopener noreferrer"
+              data-link-name="How it works - WCAG 2.0 guidelines for contrast accessibility"
+            >
               WCAG 2.0 guidelines for contrast accessibility
             </a>.
           </p>
           <p>
             If your combination does not meet the guidelines, we find the
             closest accessible combination by modifying the color&nbsp;
-            <a className={styles.link}
-               href="https://en.wikipedia.org/wiki/HSL_and_HSV"
-               target="_blank"
-               data-link-name="How it works - lightness">
+            <a
+              className={styles.link}
+              href="https://en.wikipedia.org/wiki/HSL_and_HSV"
+              target="_blank"
+              rel="noopener noreferrer"
+              data-link-name="How it works - lightness"
+            >
               lightness
             </a>.
           </p>
diff --git a/src/components/App/components/Preview/Preview.js b/src/components/App/components/Preview/Preview.js
index f906d61..a63e8ec 100644
--- a/src/components/App/components/Preview/Preview.js
+++ b/src/components/App/components/Preview/Preview.js
@@ -68,9 +68,11 @@
   };
   const linesToShow = calcLinesToShow(previewContentStyle.fontSize);
   const multilineEllipsis = (
-    <MultilineEllipsis text={loremIpsum}
-                       fontSize={previewContentStyle.fontSize}
-                       linesToShow={linesToShow} />
+    <MultilineEllipsis
+      text={loremIpsum}
+      fontSize={previewContentStyle.fontSize}
+      linesToShow={linesToShow}
+    />
   );
 
   return (
diff --git a/src/components/App/components/UserInput/UserInput.js b/src/components/App/components/UserInput/UserInput.js
index e2d0a4c..bafc65a 100644
--- a/src/components/App/components/UserInput/UserInput.js
+++ b/src/components/App/components/UserInput/UserInput.js
@@ -46,37 +46,43 @@
           <span className={styles.textColorContainer}>
             <label htmlFor="text-color">My text color is </label>
             <span className={styles.colorContainer}>
-              <Editable isValid={textColor.isValueValid}
-                        onChange={updateTextColor}
-                        inputProps={{
-                          id: 'text-color',
-                          type: 'text',
-                          value: textColor.value,
-                          onBlur: blurTextColor
-                        }} />
+              <Editable
+                isValid={textColor.isValueValid}
+                onChange={updateTextColor}
+                inputProps={{
+                  id: 'text-color',
+                  type: 'text',
+                  value: textColor.value,
+                  onBlur: blurTextColor
+                }}
+              />
             </span>
           </span>
           {' '}
           <span className={styles.fontSizeAndWeightContainer}>
             <label htmlFor="font-size">at </label>
             <span className={styles.fontSizeContainer}>
-              <Editable isValid={fontSize.isValid}
-                        onChange={updateFontSize}
-                        inputProps={{
-                          id: 'font-size',
-                          type: 'number',
-                          min: MIN_FONT_SIZE,
-                          max: MAX_FONT_SIZE,
-                          step: '1',
-                          value: fontSize.value,
-                          onBlur: blurFontSize
-                        }} />
+              <Editable
+                isValid={fontSize.isValid}
+                onChange={updateFontSize}
+                inputProps={{
+                  id: 'font-size',
+                  type: 'number',
+                  min: MIN_FONT_SIZE,
+                  max: MAX_FONT_SIZE,
+                  step: '1',
+                  value: fontSize.value,
+                  onBlur: blurFontSize
+                }}
+              />
             </span>
             pt and
             <span className={styles.fontWeightContainer}>
-              <Toggle values={['regular', 'bold']}
-                      currentValue={isFontBold ? 'bold' : 'regular'}
-                      onChange={toggleFontWeight} />
+              <Toggle
+                values={['regular', 'bold']}
+                currentValue={isFontBold ? 'bold' : 'regular'}
+                onChange={toggleFontWeight}
+              />
             </span>
             weight
           </span>
@@ -84,21 +90,25 @@
         <p className={styles.backgroundColorContainer}>
           <label htmlFor="background-color">My background color is </label>
           <span className={styles.colorContainer}>
-            <Editable isValid={backgroundColor.isValueValid}
-                      onChange={updateBackgroundColor}
-                      inputProps={{
-                        id: 'background-color',
-                        type: 'text',
-                        value: backgroundColor.value,
-                        onBlur: blurBackgroundColor
-                      }} />
+            <Editable
+              isValid={backgroundColor.isValueValid}
+              onChange={updateBackgroundColor}
+              inputProps={{
+                id: 'background-color',
+                type: 'text',
+                value: backgroundColor.value,
+                onBlur: blurBackgroundColor
+              }}
+            />
           </span>
         </p>
         <p className={styles.accessibilityLevelContainer}>
           My design must be
-          <Toggle values={['AA', 'AAA']}
-                  currentValue={accessibilityLevel}
-                  onChange={updateAccessibilityLevel} />
+          <Toggle
+            values={['AA', 'AAA']}
+            currentValue={accessibilityLevel}
+            onChange={updateAccessibilityLevel}
+          />
           compliant
         </p>
         {
diff --git a/src/components/App/components/UserInput/components/Editable/Editable.js b/src/components/App/components/UserInput/components/Editable/Editable.js
index b431ca2..c546fcc 100644
--- a/src/components/App/components/UserInput/components/Editable/Editable.js
+++ b/src/components/App/components/UserInput/components/Editable/Editable.js
@@ -22,9 +22,15 @@
     this.onKeyUp = ::this.onKeyUp;
   }
 
+  storeInputElement = element => {
+    if (element !== null) {
+      this.input = element;
+    }
+  };
+
   onFocus(event) {
     this.valueBeforeEdit = event.target.value;
-    setTimeout(() => this.refs.input.select());
+    setTimeout(() => this.input.select());
   }
 
   onKeyUp(event) {
@@ -43,16 +49,23 @@
     }
   }
 
+  onChange = event => {
+    this.props.onChange(event.target.value);
+  };
+
   render() {
-    const { isValid, onChange, inputProps } = this.props;
+    const { isValid, inputProps } = this.props;
 
     return (
-      <input {...inputProps}
-             className={isValid ? styles.validInput : styles.invalidInput}
-             aria-invalid={!isValid}
-             onFocus={this.onFocus} onKeyUp={this.onKeyUp}
-             onChange={event => onChange(event.target.value)}
-             ref="input" />
+      <input
+        {...inputProps}
+        className={isValid ? styles.validInput : styles.invalidInput}
+        aria-invalid={!isValid}
+        onFocus={this.onFocus}
+        onKeyUp={this.onKeyUp}
+        onChange={this.onChange}
+        ref={this.storeInputElement}
+      />
     );
   }
 }
diff --git a/src/components/App/components/UserInput/components/Toggle/Toggle.js b/src/components/App/components/UserInput/components/Toggle/Toggle.js
index 83107bf..2619722 100644
--- a/src/components/App/components/UserInput/components/Toggle/Toggle.js
+++ b/src/components/App/components/UserInput/components/Toggle/Toggle.js
@@ -1,23 +1,32 @@
 import styles from './Toggle.less';
 
-import React, { PropTypes } from 'react';
+import React, { PropTypes, Component } from 'react';
 
-function Toggle(props) {
-  const { values, currentValue, onChange } = props;
-  const otherValue = (currentValue === values[0] ? values[1] : values[0]);
+export default class Toggle extends Component {
+  static propTypes = {
+    values: PropTypes.arrayOf(PropTypes.string).isRequired,
+    currentValue: PropTypes.string.isRequired,
+    onChange: PropTypes.func.isRequired
+  };
 
-  return (
-    <button className={styles.button} type="button"
-            onClick={() => onChange(otherValue)}>
-      {currentValue}
-    </button>
-  );
+  onClick = () => {
+    const { values, currentValue, onChange } = this.props;
+    const otherValue = (currentValue === values[0] ? values[1] : values[0]);
+
+    onChange(otherValue);
+  };
+
+  render() {
+    const { currentValue } = this.props;
+
+    return (
+      <button
+        className={styles.button}
+        type="button"
+        onClick={this.onClick}
+      >
+        {currentValue}
+      </button>
+    );
+  }
 }
-
-Toggle.propTypes = {
-  values: PropTypes.arrayOf(PropTypes.string).isRequired,
-  currentValue: PropTypes.string.isRequired,
-  onChange: PropTypes.func.isRequired
-};
-
-export default Toggle;
diff --git a/src/components/TrackLinks/TrackLinks.js b/src/components/TrackLinks/TrackLinks.js
index 12c0225..615edad 100644
--- a/src/components/TrackLinks/TrackLinks.js
+++ b/src/components/TrackLinks/TrackLinks.js
@@ -1,12 +1,16 @@
-import React, { Component } from 'react';
+import React, { PropTypes, Component } from 'react';
 
 export default class TrackLinks extends Component {
+  static propTypes = {
+    children: PropTypes.node
+  };
+
   componentDidMount() {
-    if (typeof analytics !== 'object') {
+    if (typeof window.analytics !== 'object') {
       return;
     }
 
-    const links = this.refs.children.querySelectorAll('a');
+    const links = this.container.querySelectorAll('a');
     const linksCount = links.length;
 
     for (let i = 0; i < linksCount; i++) {
@@ -14,15 +18,21 @@
       const linkName = link.dataset.linkName;
       const event = `Clicked [${linkName}] link`;
 
-      analytics.trackLink(link, event);
+      window.analytics.trackLink(link, event);
     }
   }
 
+  storeContainerElement = element => {
+    if (element !== null) {
+      this.container = element;
+    }
+  };
+
   render() {
     const { children } = this.props;
 
     return (
-      <div ref="children">
+      <div ref={this.storeContainerElement}>
         {children}
       </div>
     );
diff --git a/src/store.js b/src/store.js
index 011aae5..26f7806 100644
--- a/src/store.js
+++ b/src/store.js
@@ -4,4 +4,4 @@
 
 export default function configureStore() {
   return createStore(appReducer, applyMiddleware(thunk));
-};
+}