Skip to content

Commit

Permalink
Add ignoreStateless option to no-multi-comp (fixes #290)
Browse files Browse the repository at this point in the history
  • Loading branch information
yannickcr committed Nov 7, 2015
1 parent 2929aaa commit 794a05a
Show file tree
Hide file tree
Showing 3 changed files with 122 additions and 2 deletions.
35 changes: 35 additions & 0 deletions docs/rules/no-multi-comp.md
Expand Up @@ -32,6 +32,41 @@ var HelloJohn = React.createClass({
});
```

## Rule Options

```js
...
"no-multi-comp": [<enabled>, { "ignoreStateless": <boolean> }]
...
```

### `ignoreStateless`

When `true` the rule will ignore stateless components and will allow you to have multiple stateless components, or one statefull component and some stateless components in the same file.

The following patterns are considered okay and do not cause warnings:

```js
function Hello(props) {
return <div>Hello {props.name}</div>;
}
function HelloAgain(props) {
return <div>Hello again {props.name}</div>;
}
```

```js
function Hello(props) {
return <div>Hello {props.name}</div>;
}
class HelloJohn extends React.Component {
render() {
return <Hello name="John" />;
}
}
module.exports = HelloJohn;
```

## When Not To Use It

If you prefer to declare multiple components per files you can disable this rule.
25 changes: 23 additions & 2 deletions lib/rules/no-multi-comp.js
Expand Up @@ -12,8 +12,20 @@ var Components = require('../util/Components');

module.exports = Components.detect(function(context, components) {

var configuration = context.options[0] || {};
var ignoreStateless = configuration.ignoreStateless || false;

var MULTI_COMP_MESSAGE = 'Declare only one React component per file';

/**
* Checks if the component is ignored
* @param {Object} component The component being checked.
* @returns {Boolean} True if the component is ignored, false if not.
*/
function isIgnored(component) {
return ignoreStateless === true && /Function/.test(component.node.type);
}

// --------------------------------------------------------------------------
// Public
// --------------------------------------------------------------------------
Expand All @@ -28,7 +40,7 @@ module.exports = Components.detect(function(context, components) {
var i = 0;

for (var component in list) {
if (!list.hasOwnProperty(component) || ++i === 1) {
if (!list.hasOwnProperty(component) || isIgnored(list[component]) || ++i === 1) {
continue;
}
context.report(list[component].node, MULTI_COMP_MESSAGE);
Expand All @@ -37,4 +49,13 @@ module.exports = Components.detect(function(context, components) {
};
});

module.exports.schema = [];
module.exports.schema = [{
type: 'object',
properties: {
ignoreStateless: {
default: false,
type: 'boolean'
}
},
additionalProperties: false
}];
64 changes: 64 additions & 0 deletions tests/lib/rules/no-multi-comp.js
Expand Up @@ -76,6 +76,37 @@ ruleTester.run('no-multi-comp', rule, {
'};'
].join('\n'),
parser: 'babel-eslint'
}, {
code: [
'function Hello(props) {',
' return <div>Hello {props.name}</div>;',
'}',
'function HelloAgain(props) {',
' return <div>Hello again {props.name}</div>;',
'}'
].join('\n'),
parser: 'babel-eslint',
options: [{
ignoreStateless: true
}]
}, {
code: [
'function Hello(props) {',
' return <div>Hello {props.name}</div>;',
'}',
'class HelloJohn extends React.Component {',
' render() {',
' return <Hello name="John" />;',
' }',
'}'
].join('\r'),
ecmaFeatures: {
classes: true,
jsx: true
},
options: [{
ignoreStateless: true
}]
}],

invalid: [{
Expand Down Expand Up @@ -127,5 +158,38 @@ ruleTester.run('no-multi-comp', rule, {
message: 'Declare only one React component per file',
line: 11
}]
}, {
code: [
'function Hello(props) {',
' return <div>Hello {props.name}</div>;',
'}',
'function HelloAgain(props) {',
' return <div>Hello again {props.name}</div>;',
'}'
].join('\n'),
parser: 'babel-eslint',
errors: [{
message: 'Declare only one React component per file',
line: 4
}]
}, {
code: [
'function Hello(props) {',
' return <div>Hello {props.name}</div>;',
'}',
'class HelloJohn extends React.Component {',
' render() {',
' return <Hello name="John" />;',
' }',
'}'
].join('\r'),
ecmaFeatures: {
classes: true,
jsx: true
},
errors: [{
message: 'Declare only one React component per file',
line: 4
}]
}]
});

0 comments on commit 794a05a

Please sign in to comment.