Compare commits

...

14 Commits

Author SHA1 Message Date
Jordan Harband
b4d8543f12 [eslint config] [react] [breaking] enable jsx-a11y rules:
- `jsx-a11y/heading-has-content`
 - `jsx-a11y/html-has-lang`
 - `jsx-a11y/lang`
 - `jsx-a11y/no-marquee`
 - `jsx-a11y/scope`
 - `jsx-a11y/href-no-hash`
 - `jsx-a11y/label-has-for`
2016-07-05 13:38:57 -07:00
Jordan Harband
a6da4bb5b2 [eslint config] [react] [breaking] enable aria rules:
- `jsx-a11y/aria-props`
 - `jsx-a11y/aria-proptypes`
 - `jsx-a11y/aria-unsupported-elements`
 - `jsx-a11y/role-has-required-aria-props`
 - `jsx-a11y/role-supports-aria-props`
2016-07-05 13:36:21 -07:00
Jordan Harband
6857f7af97 [eslint config] [react] [breaking] enable react rules:
- `react/jsx-filename-extension`
 - `react/jsx-no-comment-textnodes`
 - `react/jsx-no-target-blank`
 - `react/require-extension`
 - `react/no-render-return-value`
 - `react/no-find-dom-node`
 - `react/no-deprecated`
2016-07-05 13:20:39 -07:00
Jordan Harband
cb36ed90c3 [eslint config] [deps] [breaking] update eslint to v3, eslint-config-airbnb-base to v5, eslint-find-rules, eslint-plugin-import, eslint-plugin-jsx-a11y to v2, eslint-plugin-react to v6, tape.
- drop node < 4 support
2016-07-05 13:15:51 -07:00
Zane Mountcastle
75c961a43f Change 'Brazilian' to 'Portuguese' 2016-08-01 10:41:15 +08:00
Jordan Harband
a533e2dd35 [eslint config] [base] v5.0.1 2016-07-29 17:32:24 -07:00
Jordan Harband
4425d3c76b [eslint config] [base] [deps] update eslint to v3.2 2016-07-29 16:29:00 -07:00
Jordan Harband
49dfcc42de [eslint config] [*] improve prepublish script 2016-07-29 16:29:50 -07:00
Jordan Harband
b2ea03ef2c [eslint config] [base] [deps] update eslint-plugin-import 2016-07-29 08:14:10 -07:00
Joe Lencioni
4dbb2af7da Improve React HOC example
I decided that `WrappedComponent` is clearer than `Component` here, so I
made the switch. I also realized that `WrappedComponent.name` might
still be undefined, so I added a fallback value of "Component".
2016-07-27 09:54:00 -07:00
Joe Lencioni
1917968acb Add missing closing paren in HOC guideline
As pointed out by eagle-eyed @pepakriz.
2016-07-27 09:53:42 -07:00
James Glover
0165c13845 [eslint config] [*] [docs] Added subshell to usage commands and converted samples to the three backtick markdown syntax with language specifier for highlighting. 2016-07-27 20:18:11 +10:00
Joe Lencioni
4c8f78921f Add guideline for displayName in higher-order components
This guideline will help us keep our higher-order components consistent
and easy to understand.

Fixes #968.
2016-07-26 16:51:08 -07:00
Jordan Harband
eea5f0f5f5 [eslint config] [base] no-unused-expressions: flesh out options
Fixes #963.
2016-07-25 12:39:31 -07:00
11 changed files with 167 additions and 53 deletions

View File

@@ -1,3 +1,9 @@
5.0.1 / 2016-07-29
==================
- [patch] `no-unused-expressions`: flesh out options
- [deps] update `eslint` to `v3.2`, `eslint-plugin-import` to `v1.12`
- [tests] improve prepublish script
5.0.0 / 2016-07-24
==================
- [breaking] enable `import/newline-after-import`

View File

@@ -12,15 +12,41 @@ We export two ESLint configurations for your usage.
Our default export contains all of our ESLint rules, including ECMAScript 6+. It requires `eslint` and `eslint-plugin-import`.
1. `PKG=eslint-config-airbnb-base npm info "$PKG" peerDependencies --json | command sed 's/[\{\},]//g ; s/: /@/g' | xargs npm install --save-dev "$PKG"` (which produces and runs a command like `npm install --save-dev eslint-config-airbnb-base eslint@^3.0.1 eslint-plugin-import@^1.10.3` but with whatever the proper version numbers are)
2. add `"extends": "airbnb-base"` to your .eslintrc
1. Ensure packages are installed with correct version numbers by running:
```sh
(
export PKG=eslint-config-airbnb-base;
npm info "$PKG" peerDependencies --json | command sed 's/[\{\},]//g ; s/: /@/g' | xargs npm install --save-dev "$PKG"
)
```
Which produces and runs a command like:
```sh
npm install --save-dev eslint-config-airbnb-base eslint@^3.0.1 eslint-plugin-import@^1.10.3
```
2. Add `"extends": "airbnb-base"` to your .eslintrc
### eslint-config-airbnb-base/legacy
Lints ES5 and below. Requires `eslint` and `eslint-plugin-import`.
1. `PKG=eslint-config-airbnb-base npm info "$PKG" peerDependencies --json | command sed 's/[\{\},]//g ; s/: /@/g' | xargs npm install --save-dev "$PKG"` (which produces and runs a command like `npm install --save-dev eslint-config-airbnb-base eslint@^3.0.1 eslint-plugin-import@^1.10.3` but with whatever the proper version numbers are)
2. add `"extends": "airbnb-base/legacy"` to your .eslintrc
1. Ensure packages are installed with correct version numbers by running:
```sh
(
export PKG=eslint-config-airbnb-base;
npm info "$PKG" peerDependencies --json | command sed 's/[\{\},]//g ; s/: /@/g' | xargs npm install --save-dev "$PKG"
)
```
Which produces and runs a command like:
```sh
npm install --save-dev eslint-config-airbnb-base eslint@^3.0.1 eslint-plugin-import@^1.10.3
```
2. Add `"extends": "airbnb-base/legacy"` to your .eslintrc
See [Airbnb's overarching ESLint config](https://npmjs.com/eslint-config-airbnb), [Airbnb's Javascript styleguide](https://github.com/airbnb/javascript), and the [ESlint config docs](http://eslint.org/docs/user-guide/configuring#extending-configuration-files) for more information.

View File

@@ -1,12 +1,12 @@
{
"name": "eslint-config-airbnb-base",
"version": "5.0.0",
"version": "5.0.1",
"description": "Airbnb's base JS ESLint config, following our styleguide",
"main": "index.js",
"scripts": {
"lint": "eslint .",
"tests-only": "babel-tape-runner ./test/test-*.js",
"prepublish": "not-in-publish || (eslint-find-rules --unused && npm test)",
"prepublish": "(in-install || eslint-find-rules --unused) && (not-in-publish || npm test)",
"pretest": "npm run --silent lint",
"test": "npm run --silent tests-only",
"travis": "npm run --silent test"
@@ -47,15 +47,15 @@
"devDependencies": {
"babel-preset-airbnb": "^2.0.0",
"babel-tape-runner": "^2.0.1",
"eslint": "^3.1.1",
"eslint": "^3.2.0",
"eslint-find-rules": "^1.11.1",
"eslint-plugin-import": "^1.11.1",
"eslint-plugin-import": "^1.12.0",
"in-publish": "^2.0.0",
"tape": "^4.6.0"
},
"peerDependencies": {
"eslint": "^3.1.1",
"eslint-plugin-import": "^1.11.1"
"eslint": "^3.2.0",
"eslint-plugin-import": "^1.12.0"
},
"engines": {
"node": ">= 4"

View File

@@ -189,7 +189,10 @@ module.exports = {
'no-unmodified-loop-condition': 0,
// disallow usage of expressions in statement position
'no-unused-expressions': 2,
'no-unused-expressions': [2, {
allowShortCircuit: false,
allowTernary: false,
}],
// disallow unused labels
// http://eslint.org/docs/rules/no-unused-labels

View File

@@ -191,6 +191,10 @@ module.exports = {
// disallow space between function identifier and application
'no-spaced-func': 2,
// disallow tab characters entirely
// TODO: enable
'no-tabs': 0,
// disallow the use of ternary operators
'no-ternary': 0,

View File

@@ -12,9 +12,21 @@ We export three ESLint configurations for your usage.
Our default export contains all of our ESLint rules, including ECMAScript 6+ and React. It requires `eslint`, `eslint-plugin-import`, `eslint-plugin-react`, and `eslint-plugin-jsx-a11y`.
1. `PKG=eslint-config-airbnb npm info "$PKG" peerDependencies --json | command sed 's/[\{\},]//g ; s/: /@/g' | xargs npm install --save-dev "$PKG"` (which produces and runs a command like `npm install --save-dev eslint-config-airbnb eslint@^2.9.0 eslint-plugin-jsx-a11y@^1.2.0 eslint-plugin-import@^1.7.0 eslint-plugin-react@^5.0.1` but with whatever the proper version numbers are)
2. add `"extends": "airbnb"` to your .eslintrc
1. Ensure packages are installed with correct version numbers by running:
```sh
(
export PKG=eslint-config-airbnb;
npm info "$PKG" peerDependencies --json | command sed 's/[\{\},]//g ; s/: /@/g' | xargs npm install --save-dev "$PKG"
)
```
Which produces and runs a command like:
```sh
npm install --save-dev eslint-config-airbnb eslint@^2.9.0 eslint-plugin-jsx-a11y@^1.2.0 eslint-plugin-import@^1.7.0 eslint-plugin-react@^5.0.1
```
2. Add `"extends": "airbnb"` to your .eslintrc
### eslint-config-airbnb/base
This entry point is deprecated. See [eslint-config-airbnb-base](https://npmjs.com/eslint-config-airbnb-base).

View File

@@ -6,7 +6,7 @@
"scripts": {
"lint": "eslint .",
"tests-only": "babel-tape-runner ./test/test-*.js",
"prepublish": "not-in-publish || (eslint-find-rules --unused && npm test)",
"prepublish": "(in-install || eslint-find-rules --unused) && (not-in-publish || npm test)",
"pretest": "npm run --silent lint",
"test": "npm run --silent tests-only",
"travis": "cd ../eslint-config-airbnb-base && npm install && npm link && cd - && npm link eslint-config-airbnb-base && npm run --silent test ; npm unlink eslint-config-airbnb-base >/dev/null &"
@@ -45,24 +45,27 @@
},
"homepage": "https://github.com/airbnb/javascript",
"dependencies": {
"eslint-config-airbnb-base": "^3.0.1"
"eslint-config-airbnb-base": "^5.0.1"
},
"devDependencies": {
"babel-preset-airbnb": "^2.0.0",
"babel-tape-runner": "^2.0.1",
"eslint": "^2.10.2",
"eslint-find-rules": "^1.9.2",
"eslint-plugin-import": "^1.8.0",
"eslint-plugin-jsx-a11y": "^1.2.2",
"eslint-plugin-react": "^5.1.1",
"eslint": "^3.2.2",
"eslint-find-rules": "^1.11.1",
"eslint-plugin-import": "^1.12.0",
"eslint-plugin-jsx-a11y": "^2.0.1",
"eslint-plugin-react": "^6.0.0",
"in-publish": "^2.0.0",
"react": ">= 0.13.0",
"tape": "^4.5.1"
"tape": "^4.6.0"
},
"peerDependencies": {
"eslint": "^2.10.2",
"eslint-plugin-jsx-a11y": "^1.2.2",
"eslint-plugin-import": "^1.8.0",
"eslint-plugin-react": "^5.1.1"
"eslint": "^3.2.2",
"eslint-plugin-jsx-a11y": "^2.0.1",
"eslint-plugin-import": "^1.12.0",
"eslint-plugin-react": "^6.0.0"
},
"engines": {
"node": ">= 4"
}
}

View File

@@ -12,25 +12,21 @@ module.exports = {
'jsx-a11y/aria-role': 2,
// Enforce all aria-* props are valid.
// TODO: enable
// https://github.com/evcohen/eslint-plugin-jsx-a11y/blob/master/docs/rules/aria-props.md
'jsx-a11y/aria-props': 0,
'jsx-a11y/aria-props': 2,
// Enforce ARIA state and property values are valid.
// TODO: enable
// https://github.com/evcohen/eslint-plugin-jsx-a11y/blob/master/docs/rules/aria-proptypes.md
'jsx-a11y/aria-proptypes': 0,
'jsx-a11y/aria-proptypes': 2,
// Enforce that elements that do not support ARIA roles, states, and
// properties do not have those attributes.
// TODO: enable
// https://github.com/evcohen/eslint-plugin-jsx-a11y/blob/master/docs/rules/aria-unsupported-elements.md
'jsx-a11y/aria-unsupported-elements': 0,
'jsx-a11y/aria-unsupported-elements': 2,
// disallow href "#"
// TODO: enable
// https://github.com/evcohen/eslint-plugin-jsx-a11y/blob/master/docs/rules/href-no-hash.md
'jsx-a11y/href-no-hash': 0,
'jsx-a11y/href-no-hash': [2, ['a']],
// Require <img> to have a non-empty `alt` prop, or role="presentation"
// https://github.com/evcohen/eslint-plugin-jsx-a11y/blob/master/docs/rules/img-has-alt.md
@@ -41,12 +37,11 @@ module.exports = {
'jsx-a11y/img-redundant-alt': 2,
// require that JSX labels use "htmlFor"
// TODO: enable
// https://github.com/evcohen/eslint-plugin-jsx-a11y/blob/master/docs/rules/label-has-for.md
'jsx-a11y/label-has-for': 0,
'jsx-a11y/label-has-for': [2, ['label']],
// require that mouseover/out come with focus/blur, for keyboard-only users
// TODO: enable?
// TODO: evaluate
// https://github.com/evcohen/eslint-plugin-jsx-a11y/blob/master/docs/rules/mouse-events-have-key-events.md
'jsx-a11y/mouse-events-have-key-events': 0,
@@ -69,19 +64,37 @@ module.exports = {
// Enforce that elements with ARIA roles must have all required attributes
// for that role.
// TODO: enable
// https://github.com/evcohen/eslint-plugin-jsx-a11y/blob/master/docs/rules/role-has-required-aria-props.md
'jsx-a11y/role-has-required-aria-props': 0,
'jsx-a11y/role-has-required-aria-props': 2,
// Enforce that elements with explicit or implicit roles defined contain
// only aria-* properties supported by that role.
// TODO: enable
// https://github.com/evcohen/eslint-plugin-jsx-a11y/blob/master/docs/rules/role-supports-aria-props.md
'jsx-a11y/role-supports-aria-props': 0,
'jsx-a11y/role-supports-aria-props': 2,
// Enforce tabIndex value is not greater than zero.
// TODO: evaluate
// https://github.com/evcohen/eslint-plugin-jsx-a11y/blob/master/docs/rules/tabindex-no-positive.md
'jsx-a11y/tabindex-no-positive': 0,
// ensure <hX> tags have content and are not aria-hidden
// https://github.com/evcohen/eslint-plugin-jsx-a11y/blob/master/docs/rules/heading-has-content.md
'jsx-a11y/heading-has-content': [2, ['']],
// require HTML elements to have a "lang" prop
// https://github.com/evcohen/eslint-plugin-jsx-a11y/blob/master/docs/rules/html-has-lang.md
'jsx-a11y/html-has-lang': 2,
// require HTML element's lang prop to be valid
// https://github.com/evcohen/eslint-plugin-jsx-a11y/blob/master/docs/rules/lang.md
'jsx-a11y/lang': 2,
// prevent marquee elements
// https://github.com/evcohen/eslint-plugin-jsx-a11y/blob/master/docs/rules/no-marquee.md
'jsx-a11y/no-marquee': 2,
// only allow <th> to have the "scope" attr
// https://github.com/evcohen/eslint-plugin-jsx-a11y/blob/master/docs/rules/scope.md
'jsx-a11y/scope': 2,
},
};

View File

@@ -89,6 +89,7 @@ module.exports = {
'react/sort-prop-types': [0, {
ignoreCase: false,
callbacksLast: false,
requiredFirst: false,
}],
// Deprecated in favor of react/jsx-sort-props
@@ -99,11 +100,13 @@ module.exports = {
'react/jsx-sort-props': [0, {
ignoreCase: false,
callbacksLast: false,
shorthandFirst: false,
shorthandLast: false,
}],
// Prevent React to be incorrectly marked as unused
// https://github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/jsx-uses-react.md
'react/jsx-uses-react': [2, { pragma: 'React' }],
'react/jsx-uses-react': [2],
// Prevent variables used in JSX to be incorrectly marked as unused
// https://github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/jsx-uses-vars.md
@@ -115,15 +118,15 @@ module.exports = {
// Prevent usage of deprecated methods
// https://github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/no-deprecated.md
'react/no-deprecated': [1, { react: '0.14.0' }],
'react/no-deprecated': [2],
// Prevent usage of setState in componentDidMount
// https://github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/no-did-mount-set-state.md
'react/no-did-mount-set-state': [2, 'allow-in-func'],
'react/no-did-mount-set-state': [2],
// Prevent usage of setState in componentDidUpdate
// https://github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/no-did-update-set-state.md
'react/no-did-update-set-state': [2, 'allow-in-func'],
'react/no-did-update-set-state': [2],
// Prevent direct mutation of this.state
// https://github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/no-direct-mutation-state.md
@@ -167,7 +170,7 @@ module.exports = {
// Restrict file extensions that may be required
// https://github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/require-extension.md
'react/require-extension': [0, { extensions: ['.jsx'] }],
'react/require-extension': [2, { extensions: ['.jsx', '.js'] }],
// Require render() methods to return something
// https://github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/require-render-return.md
@@ -196,12 +199,13 @@ module.exports = {
}],
// Prevent missing parentheses around multilines JSX
// https://github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/wrap-multilines.md
'react/wrap-multilines': [2, {
// https://github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/jsx-wrap-multilines.md
'react/jsx-wrap-multilines': [2, {
declaration: true,
assignment: true,
return: true
}],
'react/wrap-multilines': 0, // deprecated version
// Require that the first prop in a JSX element be on a new line when the element is multiline
// https://github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/jsx-first-prop-new-line.md
@@ -217,8 +221,28 @@ module.exports = {
// Disallow target="_blank" on links
// https://github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/jsx-no-target-blank.md
// TODO: enable
'react/jsx-no-target-blank': 0
'react/jsx-no-target-blank': 2,
// only .jsx files may have JSX
// https://github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/jsx-filename-extension.md
'react/jsx-filename-extension': [2, { extensions: ['.jsx'] }],
// prevent accidental JS comments from being injected into JSX as text
// https://github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/jsx-no-comment-textnodes.md
'react/jsx-no-comment-textnodes': 2,
'react/no-comment-textnodes': 0, // deprecated version
// disallow using React.render/ReactDOM.render's return value
// https://github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/no-render-return-value.md
'react/no-render-return-value': 2,
// require a shouldComponentUpdate method, or PureRenderMixin
// https://github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/require-optimization.md
'react/require-optimization': [0, { allowDecorators: [] }],
// warn against using findDOMNode()
// https://github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/no-find-dom-node.md
'react/no-find-dom-node': 2,
},
settings: {

View File

@@ -9,9 +9,6 @@ const cli = new CLIEngine({
baseConfig: eslintrc,
rules: {
// This rule fails when executing on text.
indent: 0,
// It is okay to import devDependencies in tests.
'import/no-extraneous-dependencies': [2, { devDependencies: true }],
},
@@ -27,6 +24,7 @@ function lint(text) {
function wrapComponent(body) {
return `
import React from 'react';
export default class MyComponent extends React.Component {
/* eslint no-empty-function: 0 */
${body}

View File

@@ -101,7 +101,32 @@
// good
import Footer from './Footer';
```
- **Higher-order Component Naming**: Use a composite of the higher-order component's name and the passed-in component's name as the `displayName` on the generated component. For example, the higher-order component `withFoo()`, when passed a component `Bar` should produce a component with a `displayName` of `withFoo(Bar)`.
> Why? A component's `displayName` may be used by developer tools or in error messages, and having a value that clearly expresses this relationship helps people understand what is happening.
```jsx
// bad
export default function withFoo(WrappedComponent) {
return function WithFoo(props) {
return <WrappedComponent {...props} foo />;
}
}
// good
export default function withFoo(WrappedComponent) {
function WithFoo(props) {
return <WrappedComponent {...props} foo />;
}
const wrappedComponentName = WrappedComponent.displayName
|| WrappedComponent.name
|| 'Component';
WithFoo.displayName = `withFoo(${wrappedComponentName})`;
return WithFoo;
}
```
## Declaration
- Do not use `displayName` for naming components. Instead, name the component by reference.
@@ -549,6 +574,6 @@
- ![cn](https://raw.githubusercontent.com/gosquared/flags/master/flags/flags/shiny/24/China.png) **Chinese (Simplified)**: [JasonBoy/javascript](https://github.com/JasonBoy/javascript/tree/master/react)
- ![pl](https://raw.githubusercontent.com/gosquared/flags/master/flags/flags/shiny/24/Poland.png) **Polish**: [pietraszekl/javascript](https://github.com/pietraszekl/javascript/tree/master/react)
- ![kr](https://raw.githubusercontent.com/gosquared/flags/master/flags/flags/shiny/24/South-Korea.png) **Korean**: [apple77y/javascript](https://github.com/apple77y/javascript/tree/master/react)
- ![Br](https://raw.githubusercontent.com/gosquared/flags/master/flags/flags/shiny/24/Brazil.png) **Brazilian**: [ronal2do/javascript](https://github.com/ronal2do/airbnb-react-styleguide)
- ![Br](https://raw.githubusercontent.com/gosquared/flags/master/flags/flags/shiny/24/Brazil.png) **Portuguese**: [ronal2do/javascript](https://github.com/ronal2do/airbnb-react-styleguide)
**[⬆ back to top](#table-of-contents)**