diff --git a/frontend/.eslintrc b/frontend/.eslintrc
index 55e4244d..0f6b9fe1 100644
--- a/frontend/.eslintrc
+++ b/frontend/.eslintrc
@@ -10,19 +10,90 @@
},
"plugins": [
"babel",
- "react"
+ "react",
+ "jsx-a11y"
],
"rules": {
+ "react/jsx-no-undef": 2,
+ "react/jsx-uses-react": 2,
+ "react/jsx-uses-vars": 2,
+ "react/no-deprecated": 2,
+ "react/no-direct-mutation-state": 2,
+ "react/no-find-dom-node": 2,
+ "react/no-is-mounted": 2,
+ "react/no-unknown-property": 2,
+ "react/no-render-return-value": 2,
+ "react/prop-types": 2,
+ "react/react-in-jsx-scope": 2,
+ "react/require-render-return": 2,
+ "react/no-children-prop": 2,
+ "react/no-danger": 2,
+ "react/no-danger-with-children": 2,
+ "react/no-did-mount-set-state": 2,
+ "react/no-did-update-set-state": 2,
+ "react/no-multi-comp": 1,
+ "react/no-string-refs": 2,
+ "react/no-unescaped-entities": 2,
+ "react/no-unused-prop-types": 2,
+ "react/prefer-stateless-function": 2,
+ "react/self-closing-comp": 2,
+ "react/sort-comp": 2,
+ "react/sort-prop-types": 2,
+ "react/style-prop-object": 2,
+ "react/jsx-boolean-value": [2, "never"],
+ "react/jsx-closing-bracket-location": 2,
+ "react/jsx-curly-spacing": [2, "never"],
+ "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": 2,
+ "react/jsx-indent": [2, 2],
+ "react/jsx-indent-props": [2, 2],
+ "react/jsx-key": 2,
+ "react/jsx-max-props-per-line": [2, {
+ "maximum": 2
+ }],
+ "react/jsx-no-bind": 2,
+ "react/jsx-no-comment-textnodes": 2,
+ "react/jsx-no-duplicate-props": 2,
+ "react/jsx-no-target-blank": 2,
+ "react/jsx-pascal-case": 2,
+ "react/jsx-sort-props": 2,
+ "react/jsx-space-before-closing": 2,
+ "react/jsx-wrap-multilines": 2,
+ "jsx-a11y/anchor-has-content": 2,
+ "jsx-a11y/href-no-hash": 2,
+ "jsx-a11y/aria-props": 2,
+ "jsx-a11y/aria-proptypes": 2,
+ "jsx-a11y/aria-role": 2,
+ "jsx-a11y/aria-unsupported-elements": 2,
+ "jsx-a11y/click-events-have-key-events": 2,
+ "jsx-a11y/mouse-events-have-key-events": 2,
+ "jsx-a11y/heading-has-content": 2,
+ "jsx-a11y/html-has-lang": 2,
+ "jsx-a11y/img-has-alt": 2,
+ "jsx-a11y/img-redundant-alt": 2,
+ "jsx-a11y/label-has-for": 2,
+ "jsx-a11y/lang": 2,
+ "jsx-a11y/no-access-key": 2,
+ "jsx-a11y/no-marquee": 2,
+ "jsx-a11y/no-onchange": 2,
+ "jsx-a11y/no-static-element-interactions": 2,
+ "jsx-a11y/onclick-has-focus": 2,
+ "jsx-a11y/onclick-has-role": 2,
+ "jsx-a11y/role-has-required-aria-props": 2,
+ "jsx-a11y/role-supports-aria-props": 2,
+ "jsx-a11y/scope": 2,
+ "jsx-a11y/tabindex-no-positive": 2,
"generator-star-spacing": 0,
"babel/generator-star-spacing": 1,
"space-before-function-paren": [2, "never"],
- "react/jsx-uses-react": 2,
- "react/jsx-uses-vars": 2,
- "react/react-in-jsx-scope": 2,
- "object-curly-newline": ["error", {
+ "object-curly-newline": [2, {
"minProperties": 1
}],
- "sort-vars": ["error", {
+ "sort-vars": [2, {
"ignoreCase": true
}]
}
diff --git a/frontend/package.json b/frontend/package.json
index c7cae2ac..a23f964d 100644
--- a/frontend/package.json
+++ b/frontend/package.json
@@ -62,6 +62,7 @@
"eslint-config-semistandard": "^7.0.0",
"eslint-config-standard": "^6.2.0",
"eslint-plugin-babel": "^3.3.0",
+ "eslint-plugin-jsx-a11y": "^2.2.3",
"eslint-plugin-promise": "^3.3.0",
"eslint-plugin-react": "^6.4.1",
"eslint-plugin-standard": "^2.0.1",
diff --git a/frontend/src/containers/app.js b/frontend/src/containers/app.js
index b2145cce..1b317608 100644
--- a/frontend/src/containers/app.js
+++ b/frontend/src/containers/app.js
@@ -20,6 +20,11 @@ const {
} = ReactRouter;
const App = connect()(React.createClass({
+ propTypes: {
+ children: React.PropTypes.node,
+ dispatch: React.PropTypes.func,
+ router: React.PropTypes.object
+ },
componentWillMount: function() {
const {
router,
@@ -51,8 +56,14 @@ const App = connect()(React.createClass({
module.exports = (props) => {
return (
-
-
+
+
);
};
diff --git a/frontend/src/containers/home/index.js b/frontend/src/containers/home/index.js
index fedce866..5a51cb1d 100644
--- a/frontend/src/containers/home/index.js
+++ b/frontend/src/containers/home/index.js
@@ -6,7 +6,7 @@ const {
FormattedMessage
} = ReactIntl;
-module.exports = () => {
+const Home = () => {
return (
@@ -15,3 +15,5 @@ module.exports = () => {
);
};
+
+module.exports = Home;
diff --git a/frontend/src/containers/not-found/index.js b/frontend/src/containers/not-found/index.js
index b5ae7b4d..6e90fd6a 100644
--- a/frontend/src/containers/not-found/index.js
+++ b/frontend/src/containers/not-found/index.js
@@ -1,6 +1,6 @@
const React = require('react');
-module.exports = () => {
+const NotFound = () => {
return (
404
@@ -8,3 +8,5 @@ module.exports = () => {
);
};
+
+module.exports = NotFound;
diff --git a/frontend/yarn.lock b/frontend/yarn.lock
index 88e1a905..fd8da6be 100644
--- a/frontend/yarn.lock
+++ b/frontend/yarn.lock
@@ -1928,6 +1928,10 @@ d@^0.1.1, d@~0.1.1:
dependencies:
es5-ext "~0.10.2"
+damerau-levenshtein@^1.0.0:
+ version "1.0.3"
+ resolved "https://registry.yarnpkg.com/damerau-levenshtein/-/damerau-levenshtein-1.0.3.tgz#ae4f4ce0b62acae10ff63a01bb08f652f5213af2"
+
dashdash@^1.12.0:
version "1.14.0"
resolved "https://registry.yarnpkg.com/dashdash/-/dashdash-1.14.0.tgz#29e486c5418bf0f356034a993d51686a33e84141"
@@ -2279,6 +2283,14 @@ eslint-plugin-babel@^3.3.0:
version "3.3.0"
resolved "https://registry.yarnpkg.com/eslint-plugin-babel/-/eslint-plugin-babel-3.3.0.tgz#2f494aedcf6f4aa4e75b9155980837bc1fbde193"
+eslint-plugin-jsx-a11y:
+ version "2.2.3"
+ resolved "https://registry.yarnpkg.com/eslint-plugin-jsx-a11y/-/eslint-plugin-jsx-a11y-2.2.3.tgz#4e35cb71b8a7db702ac415c806eb8e8d9ea6c65d"
+ dependencies:
+ damerau-levenshtein "^1.0.0"
+ jsx-ast-utils "^1.0.0"
+ object-assign "^4.0.1"
+
eslint-plugin-promise@^3.3.0:
version "3.3.0"
resolved "https://registry.yarnpkg.com/eslint-plugin-promise/-/eslint-plugin-promise-3.3.0.tgz#20a1ef58b4243ffdaef82ee9360a02353a7cca89"
@@ -3443,7 +3455,7 @@ jsprim@^1.2.2:
json-schema "0.2.3"
verror "1.3.6"
-jsx-ast-utils@^1.3.1:
+jsx-ast-utils@^1.0.0, jsx-ast-utils@^1.3.1:
version "1.3.2"
resolved "https://registry.yarnpkg.com/jsx-ast-utils/-/jsx-ast-utils-1.3.2.tgz#dff658782705352111f9865d40471bc4a955961e"
dependencies:
diff --git a/ui/.eslintignore b/ui/.eslintignore
index a6f80ca9..c49b1f00 100644
--- a/ui/.eslintignore
+++ b/ui/.eslintignore
@@ -2,4 +2,5 @@
coverage
.nyc_output
docs/static
-static
\ No newline at end of file
+static
+webpack/embed-markdown-loader
\ No newline at end of file
diff --git a/ui/.eslintrc b/ui/.eslintrc
index 55e4244d..0f6b9fe1 100644
--- a/ui/.eslintrc
+++ b/ui/.eslintrc
@@ -10,19 +10,90 @@
},
"plugins": [
"babel",
- "react"
+ "react",
+ "jsx-a11y"
],
"rules": {
+ "react/jsx-no-undef": 2,
+ "react/jsx-uses-react": 2,
+ "react/jsx-uses-vars": 2,
+ "react/no-deprecated": 2,
+ "react/no-direct-mutation-state": 2,
+ "react/no-find-dom-node": 2,
+ "react/no-is-mounted": 2,
+ "react/no-unknown-property": 2,
+ "react/no-render-return-value": 2,
+ "react/prop-types": 2,
+ "react/react-in-jsx-scope": 2,
+ "react/require-render-return": 2,
+ "react/no-children-prop": 2,
+ "react/no-danger": 2,
+ "react/no-danger-with-children": 2,
+ "react/no-did-mount-set-state": 2,
+ "react/no-did-update-set-state": 2,
+ "react/no-multi-comp": 1,
+ "react/no-string-refs": 2,
+ "react/no-unescaped-entities": 2,
+ "react/no-unused-prop-types": 2,
+ "react/prefer-stateless-function": 2,
+ "react/self-closing-comp": 2,
+ "react/sort-comp": 2,
+ "react/sort-prop-types": 2,
+ "react/style-prop-object": 2,
+ "react/jsx-boolean-value": [2, "never"],
+ "react/jsx-closing-bracket-location": 2,
+ "react/jsx-curly-spacing": [2, "never"],
+ "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": 2,
+ "react/jsx-indent": [2, 2],
+ "react/jsx-indent-props": [2, 2],
+ "react/jsx-key": 2,
+ "react/jsx-max-props-per-line": [2, {
+ "maximum": 2
+ }],
+ "react/jsx-no-bind": 2,
+ "react/jsx-no-comment-textnodes": 2,
+ "react/jsx-no-duplicate-props": 2,
+ "react/jsx-no-target-blank": 2,
+ "react/jsx-pascal-case": 2,
+ "react/jsx-sort-props": 2,
+ "react/jsx-space-before-closing": 2,
+ "react/jsx-wrap-multilines": 2,
+ "jsx-a11y/anchor-has-content": 2,
+ "jsx-a11y/href-no-hash": 2,
+ "jsx-a11y/aria-props": 2,
+ "jsx-a11y/aria-proptypes": 2,
+ "jsx-a11y/aria-role": 2,
+ "jsx-a11y/aria-unsupported-elements": 2,
+ "jsx-a11y/click-events-have-key-events": 2,
+ "jsx-a11y/mouse-events-have-key-events": 2,
+ "jsx-a11y/heading-has-content": 2,
+ "jsx-a11y/html-has-lang": 2,
+ "jsx-a11y/img-has-alt": 2,
+ "jsx-a11y/img-redundant-alt": 2,
+ "jsx-a11y/label-has-for": 2,
+ "jsx-a11y/lang": 2,
+ "jsx-a11y/no-access-key": 2,
+ "jsx-a11y/no-marquee": 2,
+ "jsx-a11y/no-onchange": 2,
+ "jsx-a11y/no-static-element-interactions": 2,
+ "jsx-a11y/onclick-has-focus": 2,
+ "jsx-a11y/onclick-has-role": 2,
+ "jsx-a11y/role-has-required-aria-props": 2,
+ "jsx-a11y/role-supports-aria-props": 2,
+ "jsx-a11y/scope": 2,
+ "jsx-a11y/tabindex-no-positive": 2,
"generator-star-spacing": 0,
"babel/generator-star-spacing": 1,
"space-before-function-paren": [2, "never"],
- "react/jsx-uses-react": 2,
- "react/jsx-uses-vars": 2,
- "react/react-in-jsx-scope": 2,
- "object-curly-newline": ["error", {
+ "object-curly-newline": [2, {
"minProperties": 1
}],
- "sort-vars": ["error", {
+ "sort-vars": [2, {
"ignoreCase": true
}]
}
diff --git a/ui/docs/containers/app/index.js b/ui/docs/containers/app/index.js
index 52afa66f..3af5438e 100644
--- a/ui/docs/containers/app/index.js
+++ b/ui/docs/containers/app/index.js
@@ -7,7 +7,7 @@ const Item = require('../item/');
const {
Base
-} = require('../../../src');;
+} = require('../../../src');
const {
Match
@@ -17,8 +17,15 @@ module.exports = () => {
return (
-
-
+
+
);
};
diff --git a/ui/docs/containers/app/navigation.js b/ui/docs/containers/app/navigation.js
index c29070ba..1d701027 100644
--- a/ui/docs/containers/app/navigation.js
+++ b/ui/docs/containers/app/navigation.js
@@ -39,7 +39,7 @@ const getList = (items, parent) => {
);
};
-module.exports = () => {
+const Navigation = () => {
return (
@@ -50,3 +50,5 @@ module.exports = () => {
);
};
+
+module.exports = Navigation;
diff --git a/ui/docs/containers/home.js b/ui/docs/containers/home.js
index edc65ecf..fa61e1d2 100644
--- a/ui/docs/containers/home.js
+++ b/ui/docs/containers/home.js
@@ -1,5 +1,5 @@
const React = require('react');
module.exports = () => {
- return (
);
+ return (
);
};
diff --git a/ui/docs/containers/item/index.js b/ui/docs/containers/item/index.js
index ef59be97..3fe4ad2e 100644
--- a/ui/docs/containers/item/index.js
+++ b/ui/docs/containers/item/index.js
@@ -6,7 +6,7 @@ const titleCase = require('title-case');
const Docs = require('../../../src/docs');
-module.exports = ({
+const Item = ({
params
}) => {
const path = (params.parent !== 'undefined')
@@ -26,3 +26,9 @@ module.exports = ({
);
};
+
+Item.propTypes = {
+ params: React.PropTypes.object
+};
+
+module.exports = Item;
diff --git a/ui/package.json b/ui/package.json
index 5588634c..d619426b 100644
--- a/ui/package.json
+++ b/ui/package.json
@@ -35,6 +35,7 @@
"eslint-config-semistandard": "^7.0.0",
"eslint-config-standard": "^6.2.0",
"eslint-plugin-babel": "^3.3.0",
+ "eslint-plugin-jsx-a11y": "^2.2.3",
"eslint-plugin-promise": "^3.3.0",
"eslint-plugin-react": "^6.4.1",
"eslint-plugin-standard": "^2.0.1",
diff --git a/ui/src/components/base/index.js b/ui/src/components/base/index.js
index 9021ba18..547cb440 100644
--- a/ui/src/components/base/index.js
+++ b/ui/src/components/base/index.js
@@ -2,10 +2,10 @@ const React = require('react');
const classNames = require('classnames');
const styles = require('./style.css');
-const Base = module.exports = ({
+const Base = ({
+ children,
className,
- style,
- children
+ style
}) => {
const cn = classNames(
className,
@@ -13,14 +13,16 @@ const Base = module.exports = ({
);
return (
-
+
{children}
);
};
Base.propTypes = {
+ children: React.PropTypes.node,
className: React.PropTypes.string,
- style: React.PropTypes.object,
- children: React.PropTypes.node
+ style: React.PropTypes.object
};
+
+module.exports = Base;
diff --git a/ui/src/components/button/index.js b/ui/src/components/button/index.js
index d53e09a0..f00df8e0 100644
--- a/ui/src/components/button/index.js
+++ b/ui/src/components/button/index.js
@@ -1,16 +1,28 @@
const React = require('react');
const styles = require('./style.css');
-module.exports = ({
+const Button = ({
disabled = false,
+ className,
+ style,
children
}) => {
return (
);
};
+
+Button.propTypes = {
+ children: React.PropTypes.node,
+ className: React.PropTypes.string,
+ disabled: React.PropTypes.bool,
+ style: React.PropTypes.object
+};
+
+module.exports = Button;
diff --git a/ui/src/components/column/index.js b/ui/src/components/column/index.js
index d3bd8623..22985c24 100644
--- a/ui/src/components/column/index.js
+++ b/ui/src/components/column/index.js
@@ -27,11 +27,11 @@ const getClasses = (props) => {
})).filter(Boolean);
};
-const Column = module.exports = (props) => {
+const Column = (props) => {
const {
+ children,
className,
reverse,
- children,
style
} = props;
@@ -43,20 +43,22 @@ const Column = module.exports = (props) => {
);
return (
-
+
{children}
);
};
Column.propTypes = {
- reverse: React.PropTypes.bool,
- className: React.PropTypes.string,
- style: React.PropTypes.object,
children: React.PropTypes.node,
+ className: React.PropTypes.string,
+ reverse: React.PropTypes.bool,
+ style: React.PropTypes.object,
...breakpoints.reduce((all, bp) => ({
...all,
[`${bp}Offset`]: React.PropTypes.number,
[bp]: React.PropTypes.number
}), {})
};
+
+module.exports = Column;
diff --git a/ui/src/components/container/index.js b/ui/src/components/container/index.js
index 537fdd6d..53258846 100644
--- a/ui/src/components/container/index.js
+++ b/ui/src/components/container/index.js
@@ -7,7 +7,7 @@ const React = require('react');
const classNames = require('classnames');
const styles = require('./style.css');
-const Container = module.exports = ({
+const Container = ({
fluid = false,
className,
children,
@@ -19,15 +19,17 @@ const Container = module.exports = ({
);
return (
-
+
{children}
);
};
Container.propTypes = {
- fluid: React.PropTypes.bool,
+ children: React.PropTypes.node,
className: React.PropTypes.string,
- style: React.PropTypes.object,
- children: React.PropTypes.node
+ fluid: React.PropTypes.bool,
+ style: React.PropTypes.object
};
+
+module.exports = Container;
diff --git a/ui/src/components/row/index.js b/ui/src/components/row/index.js
index 6250eb74..52042aef 100644
--- a/ui/src/components/row/index.js
+++ b/ui/src/components/row/index.js
@@ -52,7 +52,7 @@ const getClasses = (props) => {
})).filter(Boolean);
};
-const Row = module.exports = (props) => {
+const Row = (props) => {
const {
className,
reverse,
@@ -68,7 +68,7 @@ const Row = module.exports = (props) => {
);
return (
-
+
{children}
);
@@ -81,12 +81,14 @@ const ModificatorType = React.PropTypes.oneOfType([
]);
Row.propTypes = {
- reverse: React.PropTypes.bool,
- className: React.PropTypes.string,
- style: React.PropTypes.object,
children: React.PropTypes.node,
+ className: React.PropTypes.string,
+ reverse: React.PropTypes.bool,
+ style: React.PropTypes.object,
...modifiers.reduce((all, m) => ({
...all,
[m]: ModificatorType
}), {})
};
+
+module.exports = Row;
diff --git a/ui/webpack/base.js b/ui/webpack/base.js
index c93d4c83..309f08d1 100644
--- a/ui/webpack/base.js
+++ b/ui/webpack/base.js
@@ -16,13 +16,10 @@ const plugins = {
require('postcss-modules-values'),
require('postcss-mixins')(),
require('postcss-for'),
- require('postcss-cssnext')(),
+ require('postcss-cssnext')()
]
},
- 'embed-markdown-loader': {
- // don't detach yet (has a bug in the production config)
- // webpackConfigFullpath: path.join(__dirname, 'index.js')
- }
+ 'embed-markdown-loader': {}
}
})
};
diff --git a/ui/webpack/production.js b/ui/webpack/production.js
index 4b3d924a..02c90d18 100644
--- a/ui/webpack/production.js
+++ b/ui/webpack/production.js
@@ -2,7 +2,6 @@ const WebpackShellPlugin = require('webpack-shell-plugin');
const base = require('./base.js');
const webpack = require('webpack');
const entries = require('./entrypoints');
-const path = require('path');
module.exports = Object.assign(base.config, {
entry: entries.reduce((all, entry) => {
diff --git a/ui/webpack/test.js b/ui/webpack/test.js
index 3de7c020..af6bef85 100644
--- a/ui/webpack/test.js
+++ b/ui/webpack/test.js
@@ -1,6 +1,4 @@
const base = require('./base');
-const webpack = require('webpack');
-const path = require('path');
module.exports = {
output: {
@@ -16,4 +14,4 @@ module.exports = {
loader: 'css-loader?modules&importLoaders=1&localIdentName=[name]__[local]___[hash:base64:5]!postcss-loader'
}]
}
-};
\ No newline at end of file
+};
diff --git a/ui/yarn.lock b/ui/yarn.lock
index 9934b15b..f6b29439 100644
--- a/ui/yarn.lock
+++ b/ui/yarn.lock
@@ -1856,6 +1856,10 @@ d@^0.1.1, d@~0.1.1:
dependencies:
es5-ext "~0.10.2"
+damerau-levenshtein@^1.0.0:
+ version "1.0.3"
+ resolved "https://registry.yarnpkg.com/damerau-levenshtein/-/damerau-levenshtein-1.0.3.tgz#ae4f4ce0b62acae10ff63a01bb08f652f5213af2"
+
dangerously-set-inner-html@2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/dangerously-set-inner-html/-/dangerously-set-inner-html-2.0.0.tgz#da73f26330c9ef0b6b12ca443091904406ddb73a"
@@ -2249,6 +2253,14 @@ eslint-plugin-babel@^3.3.0:
version "3.3.0"
resolved "https://registry.yarnpkg.com/eslint-plugin-babel/-/eslint-plugin-babel-3.3.0.tgz#2f494aedcf6f4aa4e75b9155980837bc1fbde193"
+eslint-plugin-jsx-a11y:
+ version "2.2.3"
+ resolved "https://registry.yarnpkg.com/eslint-plugin-jsx-a11y/-/eslint-plugin-jsx-a11y-2.2.3.tgz#4e35cb71b8a7db702ac415c806eb8e8d9ea6c65d"
+ dependencies:
+ damerau-levenshtein "^1.0.0"
+ jsx-ast-utils "^1.0.0"
+ object-assign "^4.0.1"
+
eslint-plugin-promise@^3.3.0:
version "3.3.0"
resolved "https://registry.yarnpkg.com/eslint-plugin-promise/-/eslint-plugin-promise-3.3.0.tgz#20a1ef58b4243ffdaef82ee9360a02353a7cca89"
@@ -3328,7 +3340,7 @@ jsprim@^1.2.2:
json-schema "0.2.3"
verror "1.3.6"
-jsx-ast-utils@^1.3.1:
+jsx-ast-utils@^1.0.0, jsx-ast-utils@^1.3.1:
version "1.3.2"
resolved "https://registry.yarnpkg.com/jsx-ast-utils/-/jsx-ast-utils-1.3.2.tgz#dff658782705352111f9865d40471bc4a955961e"
dependencies: