diff --git a/.editorconfig b/.editorconfig index 4a7ea3036a..319299684a 100644 --- a/.editorconfig +++ b/.editorconfig @@ -7,6 +7,7 @@ end_of_line = lf charset = utf-8 trim_trailing_whitespace = true insert_final_newline = true +quote_type = single [*.md] trim_trailing_whitespace = false diff --git a/lib/rules/jsx-props-no-spreading.js b/lib/rules/jsx-props-no-spreading.js index 2a311a0a6f..f23879a4d6 100644 --- a/lib/rules/jsx-props-no-spreading.js +++ b/lib/rules/jsx-props-no-spreading.js @@ -79,11 +79,23 @@ module.exports = { const exceptions = configuration.exceptions || DEFAULTS.exceptions; const isException = (tag, allExceptions) => allExceptions.indexOf(tag) !== -1; const isProperty = property => property.type === 'Property'; + const getTagNameFromMemberExpression = ({property}) => `${property.parent.object.name}.${property.name}`; return { JSXSpreadAttribute(node) { - const tagName = node.parent.name.name; + const jsxOpeningElement = node.parent.name; + const type = jsxOpeningElement.type; + + let tagName; + if (type === 'JSXIdentifier') { + tagName = jsxOpeningElement.name; + } else if (type === 'JSXMemberExpression') { + tagName = getTagNameFromMemberExpression(jsxOpeningElement); + } else { + tagName = undefined; + } + const isHTMLTag = tagName && tagName[0] !== tagName[0].toUpperCase(); - const isCustomTag = tagName && tagName[0] === tagName[0].toUpperCase(); + const isCustomTag = tagName && (tagName[0] === tagName[0].toUpperCase() || tagName.includes('.')); if ( isHTMLTag && ((ignoreHtmlTags && !isException(tagName, exceptions)) || diff --git a/tests/lib/rules/jsx-props-no-spreading.js b/tests/lib/rules/jsx-props-no-spreading.js index fbb22504b3..69e514e965 100644 --- a/tests/lib/rules/jsx-props-no-spreading.js +++ b/tests/lib/rules/jsx-props-no-spreading.js @@ -89,6 +89,37 @@ ruleTester.run('jsx-props-no-spreading', rule, { `, options: [{explicitSpread: 'ignore'}] + }, { + code: [ + 'const props = {};', + '', + ' ', + ' ', + '' + ].join('\n'), + options: [{exceptions: ['components.Group', 'Nav.Item']}] + }, { + code: [ + 'const props = {};', + '', + ' ', + ' ', + '' + ].join('\n'), + options: [{custom: 'ignore'}] + }, { + code: [ + 'const props = {};', + '', + ' ', + ' ', + '' + ].join('\n'), + options: [{ + custom: 'enforce', + html: 'ignore', + exceptions: ['components.Group', 'Nav.Item'] + }] }], invalid: [{ @@ -192,5 +223,15 @@ ruleTester.run('jsx-props-no-spreading', rule, { `, options: [{explicitSpread: 'ignore'}], errors: [expectedError] + }, { + code: [ + 'const props = {};', + '', + ' ', + ' ', + '' + ].join('\n'), + options: [{exceptions: ['components.DropdownIndicator', 'Nav.Item']}], + errors: [expectedError] }] -}); +}); \ No newline at end of file