Skip to content
Permalink

Comparing changes

This is a direct comparison between two commits made in this repository or its related repositories. View the default comparison for this range or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: jsx-eslint/eslint-plugin-react
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: 831a97c34e6349bbe37a7ec3e3de0b15eb9e8a20
Choose a base ref
..
head repository: jsx-eslint/eslint-plugin-react
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: a2e9dacb188b8cba18bddb380d91d386302c69f5
Choose a head ref
Showing with 50 additions and 22 deletions.
  1. +1 −1 CHANGELOG.md
  2. +4 −4 docs/rules/forbid-dom-props.md
  3. +13 −9 lib/rules/forbid-dom-props.js
  4. +32 −8 tests/lib/rules/forbid-dom-props.js
2 changes: 1 addition & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -12,7 +12,7 @@ This change log adheres to standards from [Keep a CHANGELOG](https://keepachange
* [types] fix types of flat configs ([#3874][] @ljharb)

### Added
* [`forbid-dom-props`]: Add `valueRegex` option for forbidden props ([#3876][] @makxca)
* [`forbid-dom-props`]: Add `disallowedValues` option for forbidden props ([#3876][] @makxca)

[#3876]: https://github.com/jsx-eslint/eslint-plugin-react/issues/3876
[#3874]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3874
8 changes: 4 additions & 4 deletions docs/rules/forbid-dom-props.md
Original file line number Diff line number Diff line change
@@ -46,13 +46,13 @@ Examples of **correct** code for this rule:

An array of strings, with the names of props that are forbidden. The default value of this option is `[]`.
Each array element can either be a string with the property name or object specifying the property name, an optional
custom message, DOM nodes disallowed list (e.g. `<div />`) and a specific regular expression for prohibited prop values:
custom message, DOM nodes disallowed list (e.g. `<div />`) and a list of prohibited values:

```js
{
"propName": "someProp",
"disallowedFor": ["DOMNode", "AnotherDOMNode"],
"valueRegex": "^someValue$",
"disallowedValues": ["someValue"],
"message": "Avoid using someProp"
}
```
@@ -73,7 +73,7 @@ const First = (props) => (
);
```

Examples of **incorrect** code for this rule, when configured with `{ forbid: [{ propName: 'someProp', valueRegex: '^someValue$' }] }`.
Examples of **incorrect** code for this rule, when configured with `{ forbid: [{ propName: 'someProp', disallowedValues: ['someValue'] }] }`.

```jsx
const First = (props) => (
@@ -87,7 +87,7 @@ const First = (props) => (
);
```

Examples of **correct** code for this rule, when configured with `{ forbid: [{ propName: 'someProp', valueRegex: '^someValue$' }] }`.
Examples of **correct** code for this rule, when configured with `{ forbid: [{ propName: 'someProp', disallowedValues: ['someValue'] }] }`.

```jsx
const First = (props) => (
22 changes: 13 additions & 9 deletions lib/rules/forbid-dom-props.js
Original file line number Diff line number Diff line change
@@ -18,7 +18,7 @@ const DEFAULTS = [];
// Rule Definition
// ------------------------------------------------------------------------------

/** @typedef {{ disallowList: null | string[]; message: null | string; valueRegex: null | RegExp }} ForbidMapType */
/** @typedef {{ disallowList: null | string[]; message: null | string; disallowedValues: string[] | null }} ForbidMapType */
/**
* @param {Map<string, ForbidMapType>} forbidMap
* @param {string} prop
@@ -37,8 +37,8 @@ function isForbidden(forbidMap, prop, propValue, tagName) {
!options.disallowList
|| options.disallowList.indexOf(tagName) !== -1
) && (
!options.valueRegex
|| options.valueRegex.test(propValue)
!options.disallowedValues
|| options.disallowedValues.indexOf(propValue) !== -1
);
}

@@ -80,8 +80,12 @@ module.exports = {
type: 'string',
},
},
valueRegex: {
type: 'string',
disallowedValues: {
type: 'array',
uniqueItems: true,
items: {
type: 'string',
},
},
message: {
type: 'string',
@@ -103,8 +107,8 @@ module.exports = {
const propName = typeof value === 'string' ? value : value.propName;
return [propName, {
disallowList: typeof value === 'string' ? null : (value.disallowedFor || null),
disallowedValues: typeof value === 'string' ? null : (value.disallowedValues || null),
message: typeof value === 'string' ? null : value.message,
valueRegex: typeof value.valueRegex === 'string' ? new RegExp(value.valueRegex) : null,
}];
}));

@@ -124,9 +128,9 @@ module.exports = {
}

const customMessage = forbid.get(prop).message;
const isRegexSpecified = forbid.get(prop).valueRegex !== null;
const message = customMessage || (isRegexSpecified && messages.propIsForbiddenWithValue) || messages.propIsForbidden;
const messageId = !customMessage && ((isRegexSpecified && 'propIsForbiddenWithValue') || 'propIsForbidden');
const isValuesListSpecified = forbid.get(prop).disallowedValues !== null;
const message = customMessage || (isValuesListSpecified && messages.propIsForbiddenWithValue) || messages.propIsForbidden;
const messageId = !customMessage && ((isValuesListSpecified && 'propIsForbiddenWithValue') || 'propIsForbidden');

report(context, message, messageId, {
node,
40 changes: 32 additions & 8 deletions tests/lib/rules/forbid-dom-props.js
Original file line number Diff line number Diff line change
@@ -112,6 +112,23 @@ ruleTester.run('forbid-dom-props', rule, {
},
],
},
{
code: `
const First = (props) => (
<div someProp="someValue" />
);
`,
options: [
{
forbid: [
{
propName: 'someProp',
disallowedValues: [],
},
],
},
],
},
{
code: `
const First = (props) => (
@@ -123,7 +140,7 @@ ruleTester.run('forbid-dom-props', rule, {
forbid: [
{
propName: 'someProp',
valueRegex: '^someValue$',
disallowedValues: ['someValue'],
},
],
},
@@ -140,7 +157,7 @@ ruleTester.run('forbid-dom-props', rule, {
forbid: [
{
propName: 'someProp',
valueRegex: '^someValue$',
disallowedValues: ['someValue'],
},
],
},
@@ -157,7 +174,7 @@ ruleTester.run('forbid-dom-props', rule, {
forbid: [
{
propName: 'someProp',
valueRegex: '^someValue$',
disallowedValues: ['someValue'],
disallowedFor: ['span'],
},
],
@@ -280,7 +297,7 @@ ruleTester.run('forbid-dom-props', rule, {
forbid: [
{
propName: 'someProp',
valueRegex: '^someValue$',
disallowedValues: ['someValue'],
},
],
},
@@ -435,8 +452,9 @@ ruleTester.run('forbid-dom-props', rule, {
<input className="boo" />
<span className="foobar">Foobar</span>
<div otherProp="bar" />
<p thirdProp="bar" />
<p thirdProp="foo" />
<div thirdProp="baz" />
<p thirdProp="bar" />
<p thirdProp="baz" />
</div>
);
@@ -453,8 +471,8 @@ ruleTester.run('forbid-dom-props', rule, {
{
propName: 'thirdProp',
disallowedFor: ['p'],
valueRegex: '^baz$',
message: 'Do not use thirdProp with value baz on p',
disallowedValues: ['bar', 'baz'],
message: 'Do not use thirdProp with values bar and baz on p',
},
],
},
@@ -479,11 +497,17 @@ ruleTester.run('forbid-dom-props', rule, {
type: 'JSXAttribute',
},
{
message: 'Do not use thirdProp with value baz on p',
message: 'Do not use thirdProp with values bar and baz on p',
line: 9,
column: 16,
type: 'JSXAttribute',
},
{
message: 'Do not use thirdProp with values bar and baz on p',
line: 10,
column: 16,
type: 'JSXAttribute',
},
],
},
]),