Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Do not consider namespaces when checking for DOM #2638

Merged
merged 1 commit into from May 9, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
16 changes: 9 additions & 7 deletions lib/rules/jsx-pascal-case.js
Expand Up @@ -54,22 +54,24 @@ module.exports = {

return {
JSXOpeningElement(node) {
const isCompatTag = jsxUtil.isDOMComponent(node);
if (isCompatTag) return undefined;

let name = elementType(node);
if (name.length === 1) return undefined;

// Get namespace if the type is JSXNamespacedName or JSXMemberExpression
if (name.indexOf(':') > -1) {
name = name.substring(0, name.indexOf(':'));
} else if (name.indexOf('.') > -1) {
name = name.substring(0, name.indexOf('.'));
// Get JSXIdentifier if the type is JSXNamespacedName or JSXMemberExpression
if (name.lastIndexOf(':') > -1) {
name = name.substring(name.lastIndexOf(':') + 1);
} else if (name.lastIndexOf('.') > -1) {
name = name.substring(name.lastIndexOf('.') + 1);
}

const isPascalCase = PASCAL_CASE_REGEX.test(name);
const isCompatTag = jsxUtil.isDOMComponent(node);
const isAllowedAllCaps = allowAllCaps && ALL_CAPS_TAG_REGEX.test(name);
const isIgnored = ignore.indexOf(name) !== -1;

if (!isPascalCase && !isCompatTag && !isAllowedAllCaps && !isIgnored) {
if (!isPascalCase && !isAllowedAllCaps && !isIgnored) {
let message = `Imported JSX component ${name} must be in PascalCase`;

if (allowAllCaps) {
Expand Down
16 changes: 5 additions & 11 deletions lib/util/jsx.js
Expand Up @@ -6,23 +6,17 @@

const elementType = require('jsx-ast-utils/elementType');

const COMPAT_TAG_REGEX = /^[a-z]|-/;
// See https://github.com/babel/babel/blob/ce420ba51c68591e057696ef43e028f41c6e04cd/packages/babel-types/src/validators/react/isCompatTag.js
// for why we only test for the first character
const COMPAT_TAG_REGEX = /^[a-z]/;

/**
* Checks if a node represents a DOM element.
* Checks if a node represents a DOM element according to React.
* @param {object} node - JSXOpeningElement to check.
* @returns {boolean} Whether or not the node corresponds to a DOM element.
*/
function isDOMComponent(node) {
let name = elementType(node);

// Get namespace if the type is JSXNamespacedName or JSXMemberExpression
if (name.indexOf(':') > -1) {
name = name.slice(0, name.indexOf(':'));
} else if (name.indexOf('.') > -1) {
name = name.slice(0, name.indexOf('.'));
}

const name = elementType(node);
return COMPAT_TAG_REGEX.test(name);
}

Expand Down
6 changes: 6 additions & 0 deletions tests/lib/rules/jsx-pascal-case.js
Expand Up @@ -29,6 +29,10 @@ const parserOptions = {
const ruleTester = new RuleTester({parserOptions});
ruleTester.run('jsx-pascal-case', rule, {
valid: [{
// The rule must not warn on components that start with a lowercase
// because they are interpreted as HTML elements by React
code: '<testcomponent />'
}, {
code: '<testComponent />'
}, {
code: '<test_component />'
Expand All @@ -52,6 +56,8 @@ ruleTester.run('jsx-pascal-case', rule, {
code: '<Año />'
}, {
code: '<Søknad />'
}, {
code: '<T />'
}, {
code: '<T />',
parser: parsers.BABEL_ESLINT
Expand Down