Skip to content

Commit ab28224

Browse files
yacinehmitoljharb
authored andcommitted
[Fix] jsx-pascal-case: Do not consider namespaces when checking for DOM
1 parent 25b1936 commit ab28224

File tree

3 files changed

+20
-18
lines changed

3 files changed

+20
-18
lines changed

lib/rules/jsx-pascal-case.js

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -54,22 +54,24 @@ module.exports = {
5454

5555
return {
5656
JSXOpeningElement(node) {
57+
const isCompatTag = jsxUtil.isDOMComponent(node);
58+
if (isCompatTag) return undefined;
59+
5760
let name = elementType(node);
5861
if (name.length === 1) return undefined;
5962

60-
// Get namespace if the type is JSXNamespacedName or JSXMemberExpression
61-
if (name.indexOf(':') > -1) {
62-
name = name.substring(0, name.indexOf(':'));
63-
} else if (name.indexOf('.') > -1) {
64-
name = name.substring(0, name.indexOf('.'));
63+
// Get JSXIdentifier if the type is JSXNamespacedName or JSXMemberExpression
64+
if (name.lastIndexOf(':') > -1) {
65+
name = name.substring(name.lastIndexOf(':') + 1);
66+
} else if (name.lastIndexOf('.') > -1) {
67+
name = name.substring(name.lastIndexOf('.') + 1);
6568
}
6669

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

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

7577
if (allowAllCaps) {

lib/util/jsx.js

Lines changed: 5 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -6,23 +6,17 @@
66

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

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

1113
/**
12-
* Checks if a node represents a DOM element.
14+
* Checks if a node represents a DOM element according to React.
1315
* @param {object} node - JSXOpeningElement to check.
1416
* @returns {boolean} Whether or not the node corresponds to a DOM element.
1517
*/
1618
function isDOMComponent(node) {
17-
let name = elementType(node);
18-
19-
// Get namespace if the type is JSXNamespacedName or JSXMemberExpression
20-
if (name.indexOf(':') > -1) {
21-
name = name.slice(0, name.indexOf(':'));
22-
} else if (name.indexOf('.') > -1) {
23-
name = name.slice(0, name.indexOf('.'));
24-
}
25-
19+
const name = elementType(node);
2620
return COMPAT_TAG_REGEX.test(name);
2721
}
2822

tests/lib/rules/jsx-pascal-case.js

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,10 @@ const parserOptions = {
2929
const ruleTester = new RuleTester({parserOptions});
3030
ruleTester.run('jsx-pascal-case', rule, {
3131
valid: [{
32+
// The rule must not warn on components that start with a lowercase
33+
// because they are interpreted as HTML elements by React
34+
code: '<testcomponent />'
35+
}, {
3236
code: '<testComponent />'
3337
}, {
3438
code: '<test_component />'
@@ -52,6 +56,8 @@ ruleTester.run('jsx-pascal-case', rule, {
5256
code: '<Año />'
5357
}, {
5458
code: '<Søknad />'
59+
}, {
60+
code: '<T />'
5561
}, {
5662
code: '<T />',
5763
parser: parsers.BABEL_ESLINT

0 commit comments

Comments
 (0)