diff --git a/docs/rules/split-platform-components.md b/docs/rules/split-platform-components.md
index 039cb8b..9d2dcc8 100644
--- a/docs/rules/split-platform-components.md
+++ b/docs/rules/split-platform-components.md
@@ -52,6 +52,16 @@ const Hello = React.createClass({
});
```
+Using `import` declaration pattern: Hello.js
+```js
+import React from 'react'
+import { ActivityIndicatiorIOS } from 'react-native'
+
+export default function Hello() {
+ return
+}
+```
+
The following patterns are not considered warnings:
filename: Hello.ios.js
@@ -81,3 +91,13 @@ const Hello = React.createClass({
}
});
```
+
+Using `import` declaration pattern: Hello.ios.js
+```js
+import React from 'react'
+import { ActivityIndicatiorIOS } from 'react-native'
+
+export default function Hello() {
+ return
+}
+```
diff --git a/lib/rules/split-platform-components.js b/lib/rules/split-platform-components.js
index 100307e..4fa5916 100644
--- a/lib/rules/split-platform-components.js
+++ b/lib/rules/split-platform-components.js
@@ -12,14 +12,18 @@ module.exports = function (context) {
const iosMessage = 'IOS components should be placed in ios files';
const conflictMessage = 'IOS and Android components can\'t be mixed';
- function getKeyValue(node) {
- const key = node.key || node.argument;
- return key.type === 'Identifier' ? key.name : key.value;
+ function getName(node) {
+ if (node.type === 'Property') {
+ const key = node.key || node.argument;
+ return key.type === 'Identifier' ? key.name : key.value;
+ } else if (node.type === 'Identifier') {
+ return node.name;
+ }
}
function hasNodeWithName(nodes, name) {
return nodes.some((node) => {
- const nodeName = getKeyValue(node);
+ const nodeName = getName(node);
return nodeName && nodeName.includes(name);
});
}
@@ -31,7 +35,7 @@ module.exports = function (context) {
);
components.forEach((node) => {
- const propName = getKeyValue(node);
+ const propName = getName(node);
if (propName.includes('IOS') && !filename.endsWith('.ios.js')) {
context.report(node, containsAndroidAndIOS ? conflictMessage : iosMessage);
@@ -51,6 +55,15 @@ module.exports = function (context) {
reactComponents = reactComponents.concat(node.id.properties);
}
},
+ ImportDeclaration: function (node) {
+ if (node.source.value === 'react-native') {
+ node.specifiers.forEach((importSpecifier) => {
+ if (importSpecifier.type === 'ImportSpecifier') {
+ reactComponents = reactComponents.concat(importSpecifier.imported);
+ }
+ });
+ }
+ },
'Program:exit': function () {
const filename = context.getFilename();
reportErrors(reactComponents, filename);
diff --git a/tests/lib/rules/split-platform-components.js b/tests/lib/rules/split-platform-components.js
index 7e4eb5c..10d8a8f 100644
--- a/tests/lib/rules/split-platform-components.js
+++ b/tests/lib/rules/split-platform-components.js
@@ -20,7 +20,7 @@ require('babel-eslint');
// ------------------------------------------------------------------------------
const ruleTester = new RuleTester();
-ruleTester.run('no-unused-styles', rule, {
+ruleTester.run('split-platform-components', rule, {
valid: [{
code: [
@@ -76,6 +76,42 @@ ruleTester.run('no-unused-styles', rule, {
classes: true,
jsx: true,
},
+ }, {
+ code: [
+ 'import {',
+ ' ActivityIndicatiorIOS,',
+ '} from \'react-native\'',
+ ].join('\n'),
+ filename: 'Hello.ios.js',
+ parser: 'babel-eslint',
+ ecmaFeatures: {
+ classes: true,
+ jsx: true,
+ },
+ }, {
+ code: [
+ 'import {',
+ ' ProgressBarAndroid,',
+ '} from \'react-native\'',
+ ].join('\n'),
+ parser: 'babel-eslint',
+ filename: 'Hello.android.js',
+ ecmaFeatures: {
+ classes: true,
+ jsx: true,
+ },
+ }, {
+ code: [
+ 'import {',
+ ' View,',
+ '} from \'react-native\'',
+ ].join('\n'),
+ parser: 'babel-eslint',
+ filename: 'Hello.js',
+ ecmaFeatures: {
+ classes: true,
+ jsx: true,
+ },
}],
invalid: [{
@@ -144,5 +180,53 @@ ruleTester.run('no-unused-styles', rule, {
}, {
message: 'IOS and Android components can\'t be mixed',
}],
+ }, {
+ code: [
+ 'import {',
+ ' ProgressBarAndroid,',
+ '} from \'react-native\'',
+ ].join('\n'),
+ parser: 'babel-eslint',
+ filename: 'Hello.js',
+ ecmaFeatures: {
+ classes: true,
+ jsx: true,
+ },
+ errors: [{
+ message: 'Android components should be placed in android files',
+ }],
+ }, {
+ code: [
+ 'import {',
+ ' ActivityIndicatiorIOS,',
+ '} from \'react-native\'',
+ ].join('\n'),
+ parser: 'babel-eslint',
+ filename: 'Hello.js',
+ ecmaFeatures: {
+ classes: true,
+ jsx: true,
+ },
+ errors: [{
+ message: 'IOS components should be placed in ios files',
+ }],
+ }, {
+ code: [
+ 'import {',
+ ' ActivityIndicatiorIOS,',
+ ' ProgressBarAndroid,',
+ '} from \'react-native\'',
+ ].join('\n'),
+ parser: 'babel-eslint',
+ filename: 'Hello.js',
+ ecmaFeatures: {
+ classes: true,
+ jsx: true,
+ },
+ errors: [{
+ message: 'IOS and Android components can\'t be mixed',
+ }, {
+ message: 'IOS and Android components can\'t be mixed',
+ }],
}],
});