Skip to content

Commit

Permalink
[New] jsx-pascal-case: add allowLeadingUnderscore option
Browse files Browse the repository at this point in the history
  • Loading branch information
mwaddell authored and ljharb committed Aug 11, 2021
1 parent 0894132 commit e0c0812
Show file tree
Hide file tree
Showing 4 changed files with 52 additions and 3 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Expand Up @@ -9,6 +9,7 @@ This change log adheres to standards from [Keep a CHANGELOG](http://keepachangel
* [`jsx-no-useless-fragments`]: add option to allow single expressions in fragments ([#3006][] @mattdarveniza)
* add [`prefer-exact-props`] rule ([#1547][] @jomasti)
* [`jsx-no-target-blank`]: add `forms` option ([#1617][] @jaaberg)
* [`jsx-pascal-case`]: add `allowLeadingUnderscore` option ([#3039][] @pangaeatech)

### Fixed
* component detection: use `estraverse` to improve component detection ([#2992][] @Wesitos)
Expand All @@ -25,6 +26,7 @@ This change log adheres to standards from [Keep a CHANGELOG](http://keepachangel
* [Docs] [`require-default-props`]: fix small typo ([#2994][] @evsasse)
* [Tests] add weekly scheduled smoke tests ([#2963][] @AriPerkkio)

[#3039]: https://github.com/yannickcr/eslint-plugin-react/pull/3039
[#3038]: https://github.com/yannickcr/eslint-plugin-react/pull/3038
[#3036]: https://github.com/yannickcr/eslint-plugin-react/issues/3036
[#3026]: https://github.com/yannickcr/eslint-plugin-react/pull/3026
Expand Down
16 changes: 15 additions & 1 deletion docs/rules/jsx-pascal-case.md
Expand Up @@ -40,12 +40,13 @@ Examples of **correct** code for this rule:

```js
...
"react/jsx-pascal-case": [<enabled>, { allowAllCaps: <allowAllCaps>, allowNamespace: <allowNamespace>, ignore: <ignore> }]
"react/jsx-pascal-case": [<enabled>, { allowAllCaps: <allowAllCaps>, allowNamespace: <allowNamespace>, allowLeadingUnderscore: <allowLeadingUnderscore>, ignore: <ignore> }]
...
```

* `enabled`: for enabling the rule. 0=off, 1=warn, 2=error. Defaults to 0.
* `allowAllCaps`: optional boolean set to `true` to allow components name in all caps (default to `false`).
* `allowLeadingUnderscore`: optional boolean set to `true` to allow components name with that starts with an underscore (default to `false`).
* `allowNamespace`: optional boolean set to `true` to ignore namespaced components (default to `false`).
* `ignore`: optional string-array of component names to ignore during validation (supports [minimatch](https://github.com/isaacs/minimatch)-style globs).

Expand All @@ -67,6 +68,19 @@ Examples of **correct** code for this rule, when `allowNamespace` is `true`:
<TestComponent.p />
```

### `allowLeadingUnderscore`

Examples of **correct** code for this rule, when `allowLeadingUnderscore` is `true`:

```jsx
<_AllowedComponent />
<_AllowedComponent>
<div />
</_AllowedComponent>
```

**WARNING:** Adding a leading underscore to the name of a component does **NOT** affect the visibilty or accessibility of that component. Attempting to use leading underscores to enforce privacy of your components is an error.

## When Not To Use It

If you are not using JSX.
10 changes: 8 additions & 2 deletions lib/rules/jsx-pascal-case.js
Expand Up @@ -90,6 +90,9 @@ module.exports = {
allowAllCaps: {
type: 'boolean'
},
allowLeadingUnderscore: {
type: 'boolean'
},
allowNamespace: {
type: 'boolean'
},
Expand All @@ -111,6 +114,7 @@ module.exports = {
create(context) {
const configuration = context.options[0] || {};
const allowAllCaps = configuration.allowAllCaps || false;
const allowLeadingUnderscore = configuration.allowLeadingUnderscore || false;
const allowNamespace = configuration.allowNamespace || false;
const ignore = configuration.ignore || [];

Expand All @@ -132,10 +136,12 @@ module.exports = {
do {
const splitName = checkNames[index];
if (splitName.length === 1) return undefined;
const isPascalCase = testPascalCase(splitName);
const isAllowedAllCaps = allowAllCaps && testAllCaps(splitName);
const isIgnored = ignoreCheck(ignore, splitName);

const checkName = allowLeadingUnderscore && splitName.startsWith('_') ? splitName.slice(1) : splitName;
const isPascalCase = testPascalCase(checkName);
const isAllowedAllCaps = allowAllCaps && testAllCaps(checkName);

if (!isPascalCase && !isAllowedAllCaps && !isIgnored) {
context.report({
node,
Expand Down
27 changes: 27 additions & 0 deletions tests/lib/rules/jsx-pascal-case.js
Expand Up @@ -93,6 +93,12 @@ ruleTester.run('jsx-pascal-case', rule, {
}, {
code: '<Styled.h1 />',
options: [{allowNamespace: true}]
}, {
code: '<_TEST_COMPONENT />',
options: [{allowAllCaps: true, allowLeadingUnderscore: true}]
}, {
code: '<_TestComponent />',
options: [{allowLeadingUnderscore: true}]
}],

invalid: [{
Expand Down Expand Up @@ -127,13 +133,34 @@ ruleTester.run('jsx-pascal-case', rule, {
messageId: 'usePascalOrSnakeCase',
data: {name: 'TEST_COMPONENT_'}
}]
}, {
code: '<TEST-COMPONENT />',
options: [{allowAllCaps: true}],
errors: [{
messageId: 'usePascalOrSnakeCase',
data: {name: 'TEST-COMPONENT'}
}]
}, {
code: '<__ />',
options: [{allowAllCaps: true}],
errors: [{
messageId: 'usePascalOrSnakeCase',
data: {name: '__'}
}]
}, {
code: '<_div />',
options: [{allowLeadingUnderscore: true}],
errors: [{
messageId: 'usePascalCase',
data: {name: '_div'}
}]
}, {
code: '<__ />',
options: [{allowAllCaps: true, allowLeadingUnderscore: true}],
errors: [{
messageId: 'usePascalOrSnakeCase',
data: {name: '__'}
}]
}, {
code: '<$a />',
errors: [{
Expand Down

0 comments on commit e0c0812

Please sign in to comment.