diff --git a/index.js b/index.js
index 9ba7f1e5e3..ad33d96eb1 100644
--- a/index.js
+++ b/index.js
@@ -23,6 +23,7 @@ module.exports = {
'jsx-quotes': require('./lib/rules/jsx-quotes'),
'no-unknown-property': require('./lib/rules/no-unknown-property'),
'jsx-curly-spacing': require('./lib/rules/jsx-curly-spacing'),
+ 'jsx-equals-spacing': require('./lib/rules/jsx-equals-spacing'),
'jsx-sort-props': require('./lib/rules/jsx-sort-props'),
'jsx-sort-prop-types': require('./lib/rules/jsx-sort-prop-types'),
'jsx-boolean-value': require('./lib/rules/jsx-boolean-value'),
@@ -62,6 +63,7 @@ module.exports = {
'jsx-quotes': 0,
'no-unknown-property': 0,
'jsx-curly-spacing': 0,
+ 'jsx-equals-spacing': 0,
'jsx-sort-props': 0,
'jsx-sort-prop-types': 0,
'jsx-boolean-value': 0,
diff --git a/lib/rules/jsx-equals-spacing.js b/lib/rules/jsx-equals-spacing.js
new file mode 100644
index 0000000000..7773c10381
--- /dev/null
+++ b/lib/rules/jsx-equals-spacing.js
@@ -0,0 +1,69 @@
+/**
+ * @fileoverview Disallow or enforce spaces around equal signs in JSX attributes.
+ * @author ryym
+ */
+'use strict';
+
+// ------------------------------------------------------------------------------
+// Rule Definition
+// ------------------------------------------------------------------------------
+
+module.exports = function(context) {
+ var config = context.options[0];
+ var sourceCode = context.getSourceCode();
+
+ /**
+ * Determines a given attribute node has an equal sign.
+ * @param {ASTNode} attrNode - The attribute node.
+ * @returns {boolean} Whether or not the attriute node has an equal sign.
+ */
+ function hasEqual(attrNode) {
+ return attrNode.type !== 'JSXSpreadAttribute' && attrNode.value !== null;
+ }
+
+ // --------------------------------------------------------------------------
+ // Public
+ // --------------------------------------------------------------------------
+
+ return {
+ JSXOpeningElement: function(node) {
+ node.attributes.forEach(function(attrNode) {
+ if (!hasEqual(attrNode)) {
+ return;
+ }
+
+ var equalToken = sourceCode.getTokenAfter(attrNode.name);
+ var spacedBefore = sourceCode.isSpaceBetweenTokens(attrNode.name, equalToken);
+ var spacedAfter = sourceCode.isSpaceBetweenTokens(equalToken, attrNode.value);
+
+ switch (config) {
+ default:
+ case 'never':
+ if (spacedBefore) {
+ context.report(attrNode, equalToken.loc.start,
+ 'There should be no space before \'=\'');
+ }
+ if (spacedAfter) {
+ context.report(attrNode, equalToken.loc.start,
+ 'There should be no space after \'=\'');
+ }
+ break;
+ case 'always':
+ if (!spacedBefore) {
+ context.report(attrNode, equalToken.loc.start,
+ 'A space is required before \'=\'');
+ }
+ if (!spacedAfter) {
+ context.report(attrNode, equalToken.loc.start,
+ 'A space is required after \'=\'');
+ }
+ break;
+ }
+ });
+ }
+ };
+};
+
+module.exports.schema = [{
+ enum: ['always', 'never']
+}];
diff --git a/tests/lib/rules/jsx-equals-spacing.js b/tests/lib/rules/jsx-equals-spacing.js
new file mode 100644
index 0000000000..dce47af12d
--- /dev/null
+++ b/tests/lib/rules/jsx-equals-spacing.js
@@ -0,0 +1,154 @@
+/**
+ * @fileoverview Disallow or enforce spaces around equal signs in JSX attributes.
+ * @author ryym
+ */
+'use strict';
+
+// ------------------------------------------------------------------------------
+// Requirements
+// ------------------------------------------------------------------------------
+
+var rule = require('../../../lib/rules/jsx-equals-spacing');
+var RuleTester = require('eslint').RuleTester;
+
+var parserOptions = {
+ ecmaVersion: 6,
+ ecmaFeatures: {
+ jsx: true
+ }
+};
+
+// ------------------------------------------------------------------------------
+// Tests
+// ------------------------------------------------------------------------------
+
+var ruleTester = new RuleTester();
+ruleTester.run('jsx-equals-spacing', rule, {
+ valid: [{
+ code: '',
+ parserOptions: parserOptions
+ }, {
+ code: '',
+ parserOptions: parserOptions
+ }, {
+ code: '',
+ parserOptions: parserOptions
+ }, {
+ code: ' bar(e)} />',
+ parserOptions: parserOptions
+ }, {
+ code: '',
+ parserOptions: parserOptions
+ }, {
+ code: '',
+ options: ['never'],
+ parserOptions: parserOptions
+ }, {
+ code: '',
+ options: ['never'],
+ parserOptions: parserOptions
+ }, {
+ code: '',
+ options: ['never'],
+ parserOptions: parserOptions
+ }, {
+ code: ' bar(e)} />',
+ options: ['never'],
+ parserOptions: parserOptions
+ }, {
+ code: '',
+ options: ['never'],
+ parserOptions: parserOptions
+ }, {
+ code: '',
+ options: ['always'],
+ parserOptions: parserOptions
+ }, {
+ code: '',
+ options: ['always'],
+ parserOptions: parserOptions
+ }, {
+ code: '',
+ options: ['always'],
+ parserOptions: parserOptions
+ }, {
+ code: ' bar(e)} />',
+ options: ['always'],
+ parserOptions: parserOptions
+ }, {
+ code: '',
+ options: ['always'],
+ parserOptions: parserOptions
+ }],
+
+ invalid: [{
+ code: '',
+ parserOptions: parserOptions,
+ errors: [
+ {message: 'There should be no space before \'=\''},
+ {message: 'There should be no space after \'=\''}
+ ]
+ }, {
+ code: '',
+ options: ['never'],
+ parserOptions: parserOptions,
+ errors: [
+ {message: 'There should be no space before \'=\''},
+ {message: 'There should be no space after \'=\''}
+ ]
+ }, {
+ code: '',
+ options: ['never'],
+ parserOptions: parserOptions,
+ errors: [
+ {message: 'There should be no space before \'=\''}
+ ]
+ }, {
+ code: '',
+ options: ['never'],
+ parserOptions: parserOptions,
+ errors: [
+ {message: 'There should be no space after \'=\''}
+ ]
+ }, {
+ code: '',
+ options: ['never'],
+ parserOptions: parserOptions,
+ errors: [
+ {message: 'There should be no space after \'=\''},
+ {message: 'There should be no space before \'=\''},
+ {message: 'There should be no space after \'=\''}
+ ]
+ }, {
+ code: '',
+ options: ['always'],
+ parserOptions: parserOptions,
+ errors: [
+ {message: 'A space is required before \'=\''},
+ {message: 'A space is required after \'=\''}
+ ]
+ }, {
+ code: '',
+ options: ['always'],
+ parserOptions: parserOptions,
+ errors: [
+ {message: 'A space is required after \'=\''}
+ ]
+ }, {
+ code: '',
+ options: ['always'],
+ parserOptions: parserOptions,
+ errors: [
+ {message: 'A space is required before \'=\''}
+ ]
+ }, {
+ code: '',
+ options: ['always'],
+ parserOptions: parserOptions,
+ errors: [
+ {message: 'A space is required before \'=\''},
+ {message: 'A space is required after \'=\''},
+ {message: 'A space is required after \'=\''}
+ ]
+ }]
+});