From 495a4cf85e6e810802e9de1b5f6efe730cb485c7 Mon Sep 17 00:00:00 2001 From: Johnny Zabala Date: Mon, 13 Jul 2020 20:53:24 -0400 Subject: [PATCH 01/16] [New] component detection: add componentWrapperFunctions setting Closes #2268. Co-authored-by: Johnny Zabala Co-authored-by: Landon Schropp --- CHANGELOG.md | 5 +++ README.md | 7 +++++ lib/util/Components.js | 39 ++++++++++++++++++----- tests/lib/rules/prop-types.js | 59 +++++++++++++++++++++++++++++++++++ 4 files changed, 102 insertions(+), 8 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a610df6244..8a24f0341d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,11 @@ This change log adheres to standards from [Keep a CHANGELOG](http://keepachangel ## Unreleased +### Added +* component detection: add componentWrapperFunctions setting ([#2713][] @@jzabala @LandonSchropp) + +[#2713]: https://github.com/yannickcr/eslint-plugin-react/pull/2713 + ## [7.23.2] - 2021.04.08 ### Fixed diff --git a/README.md b/README.md index 503fc9e64d..ae2522d6d6 100644 --- a/README.md +++ b/README.md @@ -52,6 +52,13 @@ You should also specify settings that will be shared across all the plugin rules {"property": "freeze", "object": "Object"}, {"property": "myFavoriteWrapper"} ], + "componentWrapperFunctions": [ + // The name of any function used to wrap components, e.g. Mobx `observer` function. If this isn't set, components wrapped by these functions will be skipped. + "observer", // `property` + {"property": "styled"} // `object` is optional + {"property": "observer", "object": "Mobx"}, + {"property": "observer", "object": ""}, // sets `object` to whatever value `settings.react.pragma` is set to + ], "linkComponents": [ // Components used as alternatives to for linking, eg. "Hyperlink", diff --git a/lib/util/Components.js b/lib/util/Components.js index ff65e367aa..4cbd62e750 100644 --- a/lib/util/Components.js +++ b/lib/util/Components.js @@ -212,11 +212,28 @@ class Components { } } +function getWrapperFunctions(context, pragma) { + const componentWrapperFunctions = context.settings.componentWrapperFunctions || []; + + // eslint-disable-next-line arrow-body-style + return componentWrapperFunctions.map((wrapperFunction) => { + return typeof wrapperFunction === 'string' + ? {property: wrapperFunction} + : Object.assign({}, wrapperFunction, { + object: wrapperFunction.object === '' ? pragma : wrapperFunction.object + }); + }).concat([ + {property: 'forwardRef', object: pragma}, + {property: 'memo', object: pragma} + ]); +} + function componentRule(rule, context) { const createClass = pragmaUtil.getCreateClassFromContext(context); const pragma = pragmaUtil.getFromContext(context); const sourceCode = context.getSourceCode(); const components = new Components(); + const wrapperFunctions = getWrapperFunctions(context, pragma); // Utilities for component detection const utils = { @@ -597,14 +614,20 @@ function componentRule(rule, context) { if (!node || node.type !== 'CallExpression') { return false; } - const propertyNames = ['forwardRef', 'memo']; - const calleeObject = node.callee.object; - if (calleeObject && node.callee.property) { - return arrayIncludes(propertyNames, node.callee.property.name) - && calleeObject.name === pragma - && !this.nodeWrapsComponent(node); - } - return arrayIncludes(propertyNames, node.callee.name) && this.isDestructuredFromPragmaImport(node.callee.name); + + return wrapperFunctions.some((wrapperFunction) => { + if (node.callee.type === 'MemberExpression') { + return wrapperFunction.object + && wrapperFunction.object === node.callee.object.name + && wrapperFunction.property === node.callee.property.name + && !this.nodeWrapsComponent(node); + } + return wrapperFunction.property === node.callee.name + && (!wrapperFunction.object + // Functions coming from the current pragma need special handling + || (wrapperFunction.object === pragma && this.isDestructuredFromPragmaImport(node.callee.name)) + ); + }); }, /** diff --git a/tests/lib/rules/prop-types.js b/tests/lib/rules/prop-types.js index 8c80feb15d..2475d85257 100644 --- a/tests/lib/rules/prop-types.js +++ b/tests/lib/rules/prop-types.js @@ -2515,6 +2515,26 @@ ruleTester.run('prop-types', rule, { } ` }, + { + code: ` + const SideMenu = styled( + ({ componentId }) => ( + + + + + + + ), + ); + SideMenu.propTypes = { + componentId: PropTypes.string.isRequired + } + `, + settings: { + componentWrapperFunctions: [{property: 'styled'}] + } + }, parsers.TS([ { code: ` @@ -6037,6 +6057,45 @@ ruleTester.run('prop-types', rule, { data: {name: 'name'} }] }, + { + code: ` + const SideMenu = observer( + ({ componentId }) => ( + + + + + + + ), + );`, + settings: { + componentWrapperFunctions: ['observer'] + }, + errors: [{ + message: '\'componentId\' is missing in props validation' + }] + }, + { + code: ` + const SideMenu = Mobx.observer( + ({ id }) => ( + + + + + + + ), + ); + `, + settings: { + componentWrapperFunctions: [{property: 'observer', object: 'Mobx'}] + }, + errors: [{ + message: '\'id\' is missing in props validation' + }] + }, parsers.TS([ { code: ` From cad79bbfa1ed78a337d327a8500ee261a5026538 Mon Sep 17 00:00:00 2001 From: Gareth Jones Date: Sun, 25 Apr 2021 16:29:32 +1200 Subject: [PATCH 02/16] [Fix] `jsx-handler-names`: properly substitute value into message --- CHANGELOG.md | 4 ++++ lib/rules/jsx-handler-names.js | 2 +- tests/lib/rules/jsx-handler-names.js | 5 +++++ 3 files changed, 10 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8a24f0341d..3d6c8e5240 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,10 @@ This change log adheres to standards from [Keep a CHANGELOG](http://keepachangel ### Added * component detection: add componentWrapperFunctions setting ([#2713][] @@jzabala @LandonSchropp) +### Fixed +* [`jsx-handler-names`]: properly substitute value into message ([#2975][] @G-Rath) + +[#2975]: https://github.com/yannickcr/eslint-plugin-react/pull/2975 [#2713]: https://github.com/yannickcr/eslint-plugin-react/pull/2713 ## [7.23.2] - 2021.04.08 diff --git a/lib/rules/jsx-handler-names.js b/lib/rules/jsx-handler-names.js index c792bc040c..0d28c966e8 100644 --- a/lib/rules/jsx-handler-names.js +++ b/lib/rules/jsx-handler-names.js @@ -22,7 +22,7 @@ module.exports = { messages: { badHandlerName: 'Handler function for {{propKey}} prop key must be a camelCase name beginning with \'{{handlerPrefix}}\' only', - badPropKey: 'Prop key for {{propValue}} must begin with \'{{handlerPropPrefix}\'' + badPropKey: 'Prop key for {{propValue}} must begin with \'{{handlerPropPrefix}}\'' }, schema: [{ diff --git a/tests/lib/rules/jsx-handler-names.js b/tests/lib/rules/jsx-handler-names.js index 03d2eb351f..da17432f3d 100644 --- a/tests/lib/rules/jsx-handler-names.js +++ b/tests/lib/rules/jsx-handler-names.js @@ -210,6 +210,11 @@ ruleTester.run('jsx-handler-names', rule, { options: [{ checkInlineFunction: true }] + }, { + code: '', + errors: [{ + message: 'Prop key for handleChange must begin with \'on\'' + }] }, { code: '', errors: [{ From 6d7e5a164ecf76dff050f317dfcbb1652af14452 Mon Sep 17 00:00:00 2001 From: Dennis Skoko Date: Wed, 21 Apr 2021 16:08:46 +0200 Subject: [PATCH 03/16] [Docs] `jsx-newline`: Fix minor spelling error on rule name --- CHANGELOG.md | 4 ++++ docs/rules/jsx-newline.md | 4 ++-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3d6c8e5240..71b6095916 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,7 +11,11 @@ This change log adheres to standards from [Keep a CHANGELOG](http://keepachangel ### Fixed * [`jsx-handler-names`]: properly substitute value into message ([#2975][] @G-Rath) +### Changed +* [Docs] [`jsx-newline`]: Fix minor spelling error on rule name ([#2974][] @DennisSkoko) + [#2975]: https://github.com/yannickcr/eslint-plugin-react/pull/2975 +[#2974]: https://github.com/yannickcr/eslint-plugin-react/pull/2974 [#2713]: https://github.com/yannickcr/eslint-plugin-react/pull/2713 ## [7.23.2] - 2021.04.08 diff --git a/docs/rules/jsx-newline.md b/docs/rules/jsx-newline.md index 4096c00229..2135e70e12 100644 --- a/docs/rules/jsx-newline.md +++ b/docs/rules/jsx-newline.md @@ -9,7 +9,7 @@ This is a stylistic rule intended to make JSX code more readable by requiring or ## Rule Options ```json ... -"react/jsx-new-line": [, { "prevent": }] +"react/jsx-newline": [, { "prevent": }] ... ``` @@ -129,4 +129,4 @@ Examples of **correct** code for this rule, when configured with `{ "prevent": t ## When Not To Use It -You can turn this rule off if you are not concerned with spacing between your JSX elements and expressions. \ No newline at end of file +You can turn this rule off if you are not concerned with spacing between your JSX elements and expressions. From 2ddedd5ca01a1c1b08424a9a05015cb35834cc78 Mon Sep 17 00:00:00 2001 From: Jordan Harband Date: Wed, 28 Apr 2021 08:31:25 -0700 Subject: [PATCH 04/16] [meta] ensure trailing newlines on files --- .github/workflows/readme.yml | 2 +- docs/rules/button-has-type.md | 2 +- docs/rules/destructuring-assignment.md | 2 +- docs/rules/display-name.md | 2 +- docs/rules/jsx-boolean-value.md | 2 +- docs/rules/jsx-closing-tag-location.md | 2 +- docs/rules/jsx-curly-brace-presence.md | 2 +- docs/rules/jsx-equals-spacing.md | 2 +- docs/rules/jsx-filename-extension.md | 2 +- docs/rules/jsx-first-prop-new-line.md | 2 +- docs/rules/jsx-fragments.md | 2 +- docs/rules/jsx-handler-names.md | 2 +- docs/rules/jsx-indent-props.md | 2 +- docs/rules/jsx-indent.md | 2 +- docs/rules/jsx-key.md | 2 +- docs/rules/jsx-max-depth.md | 2 +- docs/rules/jsx-max-props-per-line.md | 2 +- docs/rules/jsx-no-bind.md | 2 +- docs/rules/jsx-no-comment-textnodes.md | 2 +- docs/rules/jsx-no-duplicate-props.md | 2 +- docs/rules/jsx-no-literals.md | 2 +- docs/rules/jsx-no-script-url.md | 2 +- docs/rules/jsx-props-no-multi-spaces.md | 2 +- docs/rules/jsx-sort-default-props.md | 2 +- docs/rules/jsx-sort-props.md | 2 +- docs/rules/jsx-space-before-closing.md | 2 +- docs/rules/jsx-tag-spacing.md | 2 +- docs/rules/jsx-uses-react.md | 2 +- docs/rules/jsx-uses-vars.md | 2 +- docs/rules/jsx-wrap-multilines.md | 2 +- docs/rules/no-unused-state.md | 2 +- docs/rules/prefer-stateless-function.md | 2 +- 32 files changed, 32 insertions(+), 32 deletions(-) diff --git a/.github/workflows/readme.yml b/.github/workflows/readme.yml index c865d7320e..eeedbc53a1 100644 --- a/.github/workflows/readme.yml +++ b/.github/workflows/readme.yml @@ -13,4 +13,4 @@ jobs: with: node-version: 'lts/*' skip-ls-check: true - - run: npm run generate-list-of-rules \ No newline at end of file + - run: npm run generate-list-of-rules diff --git a/docs/rules/button-has-type.md b/docs/rules/button-has-type.md index a3a2b5fb75..d18af5afd4 100644 --- a/docs/rules/button-has-type.md +++ b/docs/rules/button-has-type.md @@ -60,4 +60,4 @@ var Hello = React.createElement('button', {type: condition ? "button" : "reset"} ## When Not To Use It -If you use only `"submit"` buttons, you can disable this rule \ No newline at end of file +If you use only `"submit"` buttons, you can disable this rule diff --git a/docs/rules/destructuring-assignment.md b/docs/rules/destructuring-assignment.md index c482051b6f..622d348665 100644 --- a/docs/rules/destructuring-assignment.md +++ b/docs/rules/destructuring-assignment.md @@ -103,4 +103,4 @@ When configured with `true`, the rule will ignore class field declarations. Exam class Foo extends React.PureComponent { bar = this.props.bar } -``` \ No newline at end of file +``` diff --git a/docs/rules/display-name.md b/docs/rules/display-name.md index 6c4087c62c..9c0d911623 100644 --- a/docs/rules/display-name.md +++ b/docs/rules/display-name.md @@ -120,4 +120,4 @@ For now we should detect components created with: * `createReactClass()` * an ES6 class that inherit from `React.Component` or `Component` -* a stateless function that return JSX or the result of a `React.createElement` call. \ No newline at end of file +* a stateless function that return JSX or the result of a `React.createElement` call. diff --git a/docs/rules/jsx-boolean-value.md b/docs/rules/jsx-boolean-value.md index 199767e8de..c6a7593335 100644 --- a/docs/rules/jsx-boolean-value.md +++ b/docs/rules/jsx-boolean-value.md @@ -36,4 +36,4 @@ var Hello = ; ## When Not To Use It -If you do not want to enforce any style for boolean attributes, then you can disable this rule. \ No newline at end of file +If you do not want to enforce any style for boolean attributes, then you can disable this rule. diff --git a/docs/rules/jsx-closing-tag-location.md b/docs/rules/jsx-closing-tag-location.md index 5cf44bc6a8..2095934df7 100644 --- a/docs/rules/jsx-closing-tag-location.md +++ b/docs/rules/jsx-closing-tag-location.md @@ -35,4 +35,4 @@ Examples of **correct** code for this rule: ## When not to use -If you do not care about closing tag JSX alignment then you can disable this rule. \ No newline at end of file +If you do not care about closing tag JSX alignment then you can disable this rule. diff --git a/docs/rules/jsx-curly-brace-presence.md b/docs/rules/jsx-curly-brace-presence.md index ee8fae8149..645d6536f2 100644 --- a/docs/rules/jsx-curly-brace-presence.md +++ b/docs/rules/jsx-curly-brace-presence.md @@ -156,4 +156,4 @@ Examples of **correct** code for this rule, even when configured with `"never"`: ## When Not To Use It -You should turn this rule off if you are not concerned about maintaining consistency regarding the use of curly braces in JSX props and/or children as well as the use of unnecessary JSX expressions. \ No newline at end of file +You should turn this rule off if you are not concerned about maintaining consistency regarding the use of curly braces in JSX props and/or children as well as the use of unnecessary JSX expressions. diff --git a/docs/rules/jsx-equals-spacing.md b/docs/rules/jsx-equals-spacing.md index 38deeff33b..dccca8c0eb 100644 --- a/docs/rules/jsx-equals-spacing.md +++ b/docs/rules/jsx-equals-spacing.md @@ -59,4 +59,4 @@ Examples of **correct** code for this rule, when configured with `"always"`: ## When Not To Use It -You can turn this rule off if you are not concerned with the consistency of spacing around equal signs in JSX attributes. \ No newline at end of file +You can turn this rule off if you are not concerned with the consistency of spacing around equal signs in JSX attributes. diff --git a/docs/rules/jsx-filename-extension.md b/docs/rules/jsx-filename-extension.md index 176d6f40ea..2dda499f23 100644 --- a/docs/rules/jsx-filename-extension.md +++ b/docs/rules/jsx-filename-extension.md @@ -46,4 +46,4 @@ The set of allowed extensions is configurable. By default '.jsx' is allowed. If ## When Not To Use It -If you don't care about restricting the file extensions that may contain JSX. \ No newline at end of file +If you don't care about restricting the file extensions that may contain JSX. diff --git a/docs/rules/jsx-first-prop-new-line.md b/docs/rules/jsx-first-prop-new-line.md index 11ccc09901..e9e2353c6d 100644 --- a/docs/rules/jsx-first-prop-new-line.md +++ b/docs/rules/jsx-first-prop-new-line.md @@ -107,4 +107,4 @@ Examples of **correct** code for this rule, when configured with `"multiline-mul ## When not to use -If you are not using JSX then you can disable this rule. \ No newline at end of file +If you are not using JSX then you can disable this rule. diff --git a/docs/rules/jsx-fragments.md b/docs/rules/jsx-fragments.md index 748b7984e3..8b5990a45d 100644 --- a/docs/rules/jsx-fragments.md +++ b/docs/rules/jsx-fragments.md @@ -56,4 +56,4 @@ Examples of **correct** code for this rule: [fragments]: https://reactjs.org/docs/fragments.html [shared_settings]: /README.md#configuration -[short_syntax]: https://reactjs.org/docs/fragments.html#short-syntax \ No newline at end of file +[short_syntax]: https://reactjs.org/docs/fragments.html#short-syntax diff --git a/docs/rules/jsx-handler-names.md b/docs/rules/jsx-handler-names.md index 9a8c612fd8..4decd5eb93 100644 --- a/docs/rules/jsx-handler-names.md +++ b/docs/rules/jsx-handler-names.md @@ -44,4 +44,4 @@ Examples of **correct** code for this rule: ## When Not To Use It -If you are not using JSX, or if you don't want to enforce specific naming conventions for event handlers. \ No newline at end of file +If you are not using JSX, or if you don't want to enforce specific naming conventions for event handlers. diff --git a/docs/rules/jsx-indent-props.md b/docs/rules/jsx-indent-props.md index 510f85ed64..09ff048e4a 100644 --- a/docs/rules/jsx-indent-props.md +++ b/docs/rules/jsx-indent-props.md @@ -121,4 +121,4 @@ firstName="John" ## When not to use -If you are not using JSX then you can disable this rule. \ No newline at end of file +If you are not using JSX then you can disable this rule. diff --git a/docs/rules/jsx-indent.md b/docs/rules/jsx-indent.md index 064417052c..4950cd459e 100644 --- a/docs/rules/jsx-indent.md +++ b/docs/rules/jsx-indent.md @@ -112,4 +112,4 @@ Examples of **correct** code for this rule: ## When not to use -If you are not using JSX then you can disable this rule. \ No newline at end of file +If you are not using JSX then you can disable this rule. diff --git a/docs/rules/jsx-key.md b/docs/rules/jsx-key.md index 39d9f28d28..e454db186c 100644 --- a/docs/rules/jsx-key.md +++ b/docs/rules/jsx-key.md @@ -65,4 +65,4 @@ Also, if you have some prevalent situation where you use arrow functions to return JSX that will not be held in an iterable, you may want to disable this rule. -[short_syntax]: https://reactjs.org/docs/fragments.html#short-syntax \ No newline at end of file +[short_syntax]: https://reactjs.org/docs/fragments.html#short-syntax diff --git a/docs/rules/jsx-max-depth.md b/docs/rules/jsx-max-depth.md index 004f950075..c95fc4ec02 100644 --- a/docs/rules/jsx-max-depth.md +++ b/docs/rules/jsx-max-depth.md @@ -81,4 +81,4 @@ Examples of **correct** code for this rule: ## When not to use -If you are not using JSX then you can disable this rule. \ No newline at end of file +If you are not using JSX then you can disable this rule. diff --git a/docs/rules/jsx-max-props-per-line.md b/docs/rules/jsx-max-props-per-line.md index 15b0236f40..d40180c716 100644 --- a/docs/rules/jsx-max-props-per-line.md +++ b/docs/rules/jsx-max-props-per-line.md @@ -86,4 +86,4 @@ Examples of **correct** code for this rule: ## When not to use -If you are not using JSX then you can disable this rule. \ No newline at end of file +If you are not using JSX then you can disable this rule. diff --git a/docs/rules/jsx-no-bind.md b/docs/rules/jsx-no-bind.md index 0cd5c6bf3a..d7335ed182 100644 --- a/docs/rules/jsx-no-bind.md +++ b/docs/rules/jsx-no-bind.md @@ -182,4 +182,4 @@ const Button = () => { ## When Not To Use It -If you do not use JSX or do not want to enforce that `bind` or arrow functions are not used in props, then you can disable this rule. \ No newline at end of file +If you do not use JSX or do not want to enforce that `bind` or arrow functions are not used in props, then you can disable this rule. diff --git a/docs/rules/jsx-no-comment-textnodes.md b/docs/rules/jsx-no-comment-textnodes.md index 5d77bd5af8..7e849520c9 100644 --- a/docs/rules/jsx-no-comment-textnodes.md +++ b/docs/rules/jsx-no-comment-textnodes.md @@ -64,4 +64,4 @@ var Hello = createReactClass({ ); } }); -``` \ No newline at end of file +``` diff --git a/docs/rules/jsx-no-duplicate-props.md b/docs/rules/jsx-no-duplicate-props.md index 4ffdc44985..cee7984873 100644 --- a/docs/rules/jsx-no-duplicate-props.md +++ b/docs/rules/jsx-no-duplicate-props.md @@ -30,4 +30,4 @@ When `true` the rule ignores the case of the props. Default to `false`. ## When Not To Use It -If you are not using JSX then you can disable this rule. \ No newline at end of file +If you are not using JSX then you can disable this rule. diff --git a/docs/rules/jsx-no-literals.md b/docs/rules/jsx-no-literals.md index 2b9936c1b1..b41355fb11 100644 --- a/docs/rules/jsx-no-literals.md +++ b/docs/rules/jsx-no-literals.md @@ -133,4 +133,4 @@ class Comp1 extends Component { ## When Not To Use It -If you do not want to enforce any style JSX literals, then you can disable this rule. \ No newline at end of file +If you do not want to enforce any style JSX literals, then you can disable this rule. diff --git a/docs/rules/jsx-no-script-url.md b/docs/rules/jsx-no-script-url.md index a77d0d1ddb..a3b4fa0180 100644 --- a/docs/rules/jsx-no-script-url.md +++ b/docs/rules/jsx-no-script-url.md @@ -54,4 +54,4 @@ Examples of **incorrect** code for this rule, when configured with the above opt -``` \ No newline at end of file +``` diff --git a/docs/rules/jsx-props-no-multi-spaces.md b/docs/rules/jsx-props-no-multi-spaces.md index b3b0c03fcf..984e7f6119 100644 --- a/docs/rules/jsx-props-no-multi-spaces.md +++ b/docs/rules/jsx-props-no-multi-spaces.md @@ -43,4 +43,4 @@ Examples of **correct** code for this rule: If you are not using JSX or don't care about the space between two props in the same line. -If you have enabled the core rule `no-multi-spaces` with eslint >= 3, you don't need this rule. \ No newline at end of file +If you have enabled the core rule `no-multi-spaces` with eslint >= 3, you don't need this rule. diff --git a/docs/rules/jsx-sort-default-props.md b/docs/rules/jsx-sort-default-props.md index 88ffeea893..9aaf44a4db 100644 --- a/docs/rules/jsx-sort-default-props.md +++ b/docs/rules/jsx-sort-default-props.md @@ -182,4 +182,4 @@ When `true` the rule ignores the case-sensitivity of the declarations order. ## When not to use -This rule is a formatting preference and not following it won't negatively affect the quality of your code. If alphabetizing `defaultProps` declarations isn't a part of your coding standards, then you can leave this rule off. \ No newline at end of file +This rule is a formatting preference and not following it won't negatively affect the quality of your code. If alphabetizing `defaultProps` declarations isn't a part of your coding standards, then you can leave this rule off. diff --git a/docs/rules/jsx-sort-props.md b/docs/rules/jsx-sort-props.md index 6914037211..2b8e36e295 100644 --- a/docs/rules/jsx-sort-props.md +++ b/docs/rules/jsx-sort-props.md @@ -100,4 +100,4 @@ With `reservedFirst: ["key"]`, the following will **not** warn: ## When not to use -This rule is a formatting preference and not following it won't negatively affect the quality of your code. If alphabetizing props isn't a part of your coding standards, then you can leave this rule off. \ No newline at end of file +This rule is a formatting preference and not following it won't negatively affect the quality of your code. If alphabetizing props isn't a part of your coding standards, then you can leave this rule off. diff --git a/docs/rules/jsx-space-before-closing.md b/docs/rules/jsx-space-before-closing.md index 0a259535aa..9a4470d90c 100644 --- a/docs/rules/jsx-space-before-closing.md +++ b/docs/rules/jsx-space-before-closing.md @@ -50,4 +50,4 @@ Examples of **correct** code for this rule, when configured with `"never"`: ## When Not To Use It -You can turn this rule off if you are not concerned with the consistency of spacing before closing brackets. \ No newline at end of file +You can turn this rule off if you are not concerned with the consistency of spacing before closing brackets. diff --git a/docs/rules/jsx-tag-spacing.md b/docs/rules/jsx-tag-spacing.md index 87859d3d08..fbf47aea8d 100644 --- a/docs/rules/jsx-tag-spacing.md +++ b/docs/rules/jsx-tag-spacing.md @@ -221,4 +221,4 @@ Examples of **correct** code for this rule, when configured with `{ "beforeClosi ## When Not To Use It -You can turn this rule off if you are not concerned with the consistency of spacing in or around JSX brackets. \ No newline at end of file +You can turn this rule off if you are not concerned with the consistency of spacing in or around JSX brackets. diff --git a/docs/rules/jsx-uses-react.md b/docs/rules/jsx-uses-react.md index 8dc6f3b4eb..9adc6d9526 100644 --- a/docs/rules/jsx-uses-react.md +++ b/docs/rules/jsx-uses-react.md @@ -43,4 +43,4 @@ var Hello =
Hello {this.props.name}
; ## When Not To Use It -If you are not using JSX, if React is declared as global variable or if you do not use the `no-unused-vars` rule then you can disable this rule. \ No newline at end of file +If you are not using JSX, if React is declared as global variable or if you do not use the `no-unused-vars` rule then you can disable this rule. diff --git a/docs/rules/jsx-uses-vars.md b/docs/rules/jsx-uses-vars.md index d1342f7de5..7da383c2bf 100644 --- a/docs/rules/jsx-uses-vars.md +++ b/docs/rules/jsx-uses-vars.md @@ -22,4 +22,4 @@ var Hello = require('./Hello'); ## When Not To Use It -If you are not using JSX or if you do not use the `no-unused-vars` rule then you can disable this rule. \ No newline at end of file +If you are not using JSX or if you do not use the `no-unused-vars` rule then you can disable this rule. diff --git a/docs/rules/jsx-wrap-multilines.md b/docs/rules/jsx-wrap-multilines.md index d53ab2152f..3d15ce03af 100644 --- a/docs/rules/jsx-wrap-multilines.md +++ b/docs/rules/jsx-wrap-multilines.md @@ -475,4 +475,4 @@ Examples of **correct** code for this rule, when configured with `{ prop: "paren )}>

Hello

; -``` \ No newline at end of file +``` diff --git a/docs/rules/no-unused-state.md b/docs/rules/no-unused-state.md index 1aad461dea..91afb3ae81 100644 --- a/docs/rules/no-unused-state.md +++ b/docs/rules/no-unused-state.md @@ -42,4 +42,4 @@ var UnusedGetInitialStateTest = createReactClass({ return ; } }) -``` \ No newline at end of file +``` diff --git a/docs/rules/prefer-stateless-function.md b/docs/rules/prefer-stateless-function.md index e44d157165..2503a0020a 100644 --- a/docs/rules/prefer-stateless-function.md +++ b/docs/rules/prefer-stateless-function.md @@ -80,4 +80,4 @@ class Bar extends React.PureComponent { return
Baz
; } } -``` \ No newline at end of file +``` From 6cf3812559cdab36bd8d21fd0e3333564d20271e Mon Sep 17 00:00:00 2001 From: Geraint White Date: Wed, 21 Apr 2021 12:18:52 +0100 Subject: [PATCH 05/16] [New] `no-unused-prop-types`: add `ignore` option --- CHANGELOG.md | 2 + docs/rules/no-unused-prop-types.md | 3 +- lib/rules/no-unused-prop-types.js | 20 ++++++- tests/lib/rules/no-unused-prop-types.js | 72 ++++++++++++++++++++++--- 4 files changed, 88 insertions(+), 9 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 71b6095916..fc9aa80b18 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,7 @@ This change log adheres to standards from [Keep a CHANGELOG](http://keepachangel ### Added * component detection: add componentWrapperFunctions setting ([#2713][] @@jzabala @LandonSchropp) +* [`no-unused-prop-types`]: add ignore option ([#2972][] @grit96) ### Fixed * [`jsx-handler-names`]: properly substitute value into message ([#2975][] @G-Rath) @@ -16,6 +17,7 @@ This change log adheres to standards from [Keep a CHANGELOG](http://keepachangel [#2975]: https://github.com/yannickcr/eslint-plugin-react/pull/2975 [#2974]: https://github.com/yannickcr/eslint-plugin-react/pull/2974 +[#2972]: https://github.com/yannickcr/eslint-plugin-react/pull/2972 [#2713]: https://github.com/yannickcr/eslint-plugin-react/pull/2713 ## [7.23.2] - 2021.04.08 diff --git a/docs/rules/no-unused-prop-types.md b/docs/rules/no-unused-prop-types.md index 810a2a5304..c9950dbfc5 100644 --- a/docs/rules/no-unused-prop-types.md +++ b/docs/rules/no-unused-prop-types.md @@ -75,11 +75,12 @@ This rule can take one argument to ignore some specific props during validation. ```js ... -"react/no-unused-prop-types": [, { customValidators: , skipShapeProps: }] +"react/no-unused-prop-types": [, { ignore: , customValidators: , skipShapeProps: }] ... ``` * `enabled`: for enabling the rule. 0=off, 1=warn, 2=error. Defaults to 0. +* `ignore`: optional array of props name to ignore during validation. * `customValidators`: optional array of validators used for propTypes validation. * `skipShapeProps`: In some cases it is impossible to accurately detect whether or not a `PropTypes.shape`'s values are being used. Setting this option to `true` will skip validation of `PropTypes.shape` (`true` by default). diff --git a/lib/rules/no-unused-prop-types.js b/lib/rules/no-unused-prop-types.js index 0df5d1a851..8f5de2083b 100644 --- a/lib/rules/no-unused-prop-types.js +++ b/lib/rules/no-unused-prop-types.js @@ -31,6 +31,13 @@ module.exports = { schema: [{ type: 'object', properties: { + ignore: { + type: 'array', + items: { + type: 'string' + }, + uniqueItems: true + }, customValidators: { type: 'array', items: { @@ -46,9 +53,18 @@ module.exports = { }, create: Components.detect((context, components) => { - const defaults = {skipShapeProps: true, customValidators: []}; + const defaults = {skipShapeProps: true, customValidators: [], ignore: []}; const configuration = Object.assign({}, defaults, context.options[0] || {}); + /** + * Checks if the prop is ignored + * @param {String} name Name of the prop to check. + * @returns {Boolean} True if the prop is ignored, false if not. + */ + function isIgnored(name) { + return configuration.ignore.indexOf(name) !== -1; + } + /** * Checks if the component must be validated * @param {Object} component The component to process @@ -111,7 +127,7 @@ module.exports = { return; } - if (prop.node && !isPropUsed(component, prop)) { + if (prop.node && !isIgnored(prop.fullName) && !isPropUsed(component, prop)) { context.report({ node: prop.node.key || prop.node, messageId: 'unusedPropType', diff --git a/tests/lib/rules/no-unused-prop-types.js b/tests/lib/rules/no-unused-prop-types.js index 57d2e841bd..5b41d0e777 100644 --- a/tests/lib/rules/no-unused-prop-types.js +++ b/tests/lib/rules/no-unused-prop-types.js @@ -3202,6 +3202,33 @@ ruleTester.run('no-unused-prop-types', rule, { } `, parser: parsers.BABEL_ESLINT + }, { + code: ` + class Hello extends React.Component { + render() { + return
{this.props.used}
; + } + } + Hello.propTypes = { + used: PropTypes.string, + foo: PropTypes.string + }; + `, + options: [{ignore: ['foo']}] + }, { + code: ` + type Props = { + used: string, + foo: string, + } + class Hello extends React.Component { + render() { + return
{this.props.used}
; + } + } + `, + parser: parsers.BABEL_ESLINT, + options: [{ignore: ['foo']}] }, { code: ` export default class Foo extends React.Component { @@ -5488,6 +5515,41 @@ ruleTester.run('no-unused-prop-types', rule, { errors: [{ message: '\'lastname\' PropType is defined but prop is never used' }] + }, { + code: ` + class MyComponent extends React.Component { + render() { + return
Hello {this.props.firstname}
+ } + } + MyComponent.propTypes = { + firstname: PropTypes.string, + lastname: PropTypes.string, + foo: PropTypes.string, + }; + `, + options: [{ignore: ['foo']}], + errors: [{ + message: '\'lastname\' PropType is defined but prop is never used' + }] + }, { + code: ` + type Props = { + firstname: string, + lastname: string, + foo: string, + } + class MyComponent extends React.Component { + render() { + return
Hello {this.props.firstname}
+ } + } + `, + parser: parsers.BABEL_ESLINT, + options: [{ignore: ['foo']}], + errors: [{ + message: '\'lastname\' PropType is defined but prop is never used' + }] }, { code: ` type Person = string; @@ -6941,11 +7003,9 @@ ruleTester.run('no-unused-prop-types', rule, { errors: [{ message: '\'prop1\' PropType is defined but prop is never used' }] - }]) - - /* , { - // Enable this when the following issue is fixed - // https://github.com/yannickcr/eslint-plugin-react/issues/296 + }]), + // Issue: #296 + { code: [ 'function Foo(props) {', ' const { bar: { nope } } = props;', @@ -6963,6 +7023,6 @@ ruleTester.run('no-unused-prop-types', rule, { errors: [{ message: '\'foo\' PropType is defined but prop is never used' }] - } */ + } ) }); From 1185b3799798d5b2b31ef39abe55231ce7e0e875 Mon Sep 17 00:00:00 2001 From: Chiawen Chen Date: Thu, 29 Apr 2021 01:16:00 +0800 Subject: [PATCH 06/16] [Refactor] `void-dom-elements-no-children`: improve performance --- CHANGELOG.md | 2 ++ lib/util/Components.js | 20 ++++++++++++-------- 2 files changed, 14 insertions(+), 8 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index fc9aa80b18..96a82a18b8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,7 +14,9 @@ This change log adheres to standards from [Keep a CHANGELOG](http://keepachangel ### Changed * [Docs] [`jsx-newline`]: Fix minor spelling error on rule name ([#2974][] @DennisSkoko) +* [Refactor] [`void-dom-elements-no-children`]: improve performance +[#2977]: https://github.com/yannickcr/eslint-plugin-react/pull/2977 [#2975]: https://github.com/yannickcr/eslint-plugin-react/pull/2975 [#2974]: https://github.com/yannickcr/eslint-plugin-react/pull/2974 [#2972]: https://github.com/yannickcr/eslint-plugin-react/pull/2972 diff --git a/lib/util/Components.js b/lib/util/Components.js index 4cbd62e750..27dd09c0a6 100644 --- a/lib/util/Components.js +++ b/lib/util/Components.js @@ -393,25 +393,29 @@ function componentRule(rule, context) { * @returns {Boolean} True if createElement called from pragma */ isCreateElement(node) { - const calledOnPragma = ( + // match `React.createElement()` + if ( node && node.callee && node.callee.object && node.callee.object.name === pragma && node.callee.property && node.callee.property.name === 'createElement' - ); + ) { + return true; + } - const calledDirectly = ( + // match `createElement()` + if ( node && node.callee && node.callee.name === 'createElement' - ); - - if (this.isDestructuredFromPragmaImport('createElement')) { - return calledDirectly || calledOnPragma; + && this.isDestructuredFromPragmaImport('createElement') + ) { + return true; } - return calledOnPragma; + + return false; }, /** From 0f4b6264d72c71ebc39d08075a945acf4878661d Mon Sep 17 00:00:00 2001 From: sugardon Date: Tue, 4 May 2021 19:04:20 +0900 Subject: [PATCH 07/16] [readme] fix missing trailing commas --- CHANGELOG.md | 2 ++ README.md | 4 ++-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 96a82a18b8..a1fac3cabc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,7 +15,9 @@ This change log adheres to standards from [Keep a CHANGELOG](http://keepachangel ### Changed * [Docs] [`jsx-newline`]: Fix minor spelling error on rule name ([#2974][] @DennisSkoko) * [Refactor] [`void-dom-elements-no-children`]: improve performance +* [readme] fix missing trailing commas ([#2980][] @sugardon) +[#2980]: https://github.com/yannickcr/eslint-plugin-react/pull/2980 [#2977]: https://github.com/yannickcr/eslint-plugin-react/pull/2977 [#2975]: https://github.com/yannickcr/eslint-plugin-react/pull/2975 [#2974]: https://github.com/yannickcr/eslint-plugin-react/pull/2974 diff --git a/README.md b/README.md index ae2522d6d6..7baf89a529 100644 --- a/README.md +++ b/README.md @@ -55,9 +55,9 @@ You should also specify settings that will be shared across all the plugin rules "componentWrapperFunctions": [ // The name of any function used to wrap components, e.g. Mobx `observer` function. If this isn't set, components wrapped by these functions will be skipped. "observer", // `property` - {"property": "styled"} // `object` is optional + {"property": "styled"}, // `object` is optional {"property": "observer", "object": "Mobx"}, - {"property": "observer", "object": ""}, // sets `object` to whatever value `settings.react.pragma` is set to + {"property": "observer", "object": ""} // sets `object` to whatever value `settings.react.pragma` is set to ], "linkComponents": [ // Components used as alternatives to
for linking, eg. From 89ba8c51aa3f68b4b5b0404678b950f790a71f70 Mon Sep 17 00:00:00 2001 From: vzvu3k6k Date: Sat, 8 May 2021 03:15:43 +0900 Subject: [PATCH 08/16] [readme] fix broken anchor link Documentation about "Adding Shared Settings" is moved by eslint/eslint#13837 and eslint/eslint#14036. --- CHANGELOG.md | 2 ++ README.md | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a1fac3cabc..9ccb61a300 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,7 +16,9 @@ This change log adheres to standards from [Keep a CHANGELOG](http://keepachangel * [Docs] [`jsx-newline`]: Fix minor spelling error on rule name ([#2974][] @DennisSkoko) * [Refactor] [`void-dom-elements-no-children`]: improve performance * [readme] fix missing trailing commas ([#2980][] @sugardon) +* [readme] fix broken anchor link ([#2982][] @vzvu3k6k) +[#2982]: https://github.com/yannickcr/eslint-plugin-react/pull/2982 [#2980]: https://github.com/yannickcr/eslint-plugin-react/pull/2980 [#2977]: https://github.com/yannickcr/eslint-plugin-react/pull/2977 [#2975]: https://github.com/yannickcr/eslint-plugin-react/pull/2975 diff --git a/README.md b/README.md index 7baf89a529..c3cda1b72f 100644 --- a/README.md +++ b/README.md @@ -30,7 +30,7 @@ Use [our preset](#recommended) to get reasonable defaults: ] ``` -You should also specify settings that will be shared across all the plugin rules. ([More about eslint shared settings](https://eslint.org/docs/user-guide/configuring#adding-shared-settings)) +You should also specify settings that will be shared across all the plugin rules. ([More about eslint shared settings](https://eslint.org/docs/user-guide/configuring/configuration-files#adding-shared-settings)) ```json5 { From f864ac1bbae6f704cc24f064f23dc3d0eebfabc2 Mon Sep 17 00:00:00 2001 From: Remco Haszing Date: Tue, 11 May 2021 22:17:41 +0200 Subject: [PATCH 09/16] [Fix] `jsx-uses-vars`: ignore namespaces JSX namespaces are transpiled into strings, not identifiers. --- CHANGELOG.md | 2 ++ lib/rules/jsx-uses-vars.js | 7 ++++--- tests/lib/rules/jsx-uses-vars.js | 8 +------- 3 files changed, 7 insertions(+), 10 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9ccb61a300..99148c8af5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,7 @@ This change log adheres to standards from [Keep a CHANGELOG](http://keepachangel ### Fixed * [`jsx-handler-names`]: properly substitute value into message ([#2975][] @G-Rath) +* [`jsx-uses-vars`]: ignore namespaces ([#2985][] @remcohaszing) ### Changed * [Docs] [`jsx-newline`]: Fix minor spelling error on rule name ([#2974][] @DennisSkoko) @@ -18,6 +19,7 @@ This change log adheres to standards from [Keep a CHANGELOG](http://keepachangel * [readme] fix missing trailing commas ([#2980][] @sugardon) * [readme] fix broken anchor link ([#2982][] @vzvu3k6k) +[#2985]: https://github.com/yannickcr/eslint-plugin-react/pull/2985 [#2982]: https://github.com/yannickcr/eslint-plugin-react/pull/2982 [#2980]: https://github.com/yannickcr/eslint-plugin-react/pull/2980 [#2977]: https://github.com/yannickcr/eslint-plugin-react/pull/2977 diff --git a/lib/rules/jsx-uses-vars.js b/lib/rules/jsx-uses-vars.js index 86a32f1f46..2ccdc5d360 100644 --- a/lib/rules/jsx-uses-vars.js +++ b/lib/rules/jsx-uses-vars.js @@ -26,10 +26,11 @@ module.exports = { return { JSXOpeningElement(node) { let name; - if (node.name.namespace && node.name.namespace.name) { + if (node.name.namespace) { // - name = node.name.namespace.name; - } else if (node.name.name) { + return; + } + if (node.name.name) { // name = node.name.name; } else if (node.name.object) { diff --git a/tests/lib/rules/jsx-uses-vars.js b/tests/lib/rules/jsx-uses-vars.js index b93e7c3547..ce02d7fc29 100644 --- a/tests/lib/rules/jsx-uses-vars.js +++ b/tests/lib/rules/jsx-uses-vars.js @@ -79,12 +79,6 @@ ruleTester.run('no-unused-vars', ruleNoUnusedVars, { var App; ` - }, { - code: ` - /* eslint jsx-uses-vars: 1 */ - var App; - - ` }, { code: ` /* eslint jsx-uses-vars: 1 */ @@ -143,7 +137,7 @@ ruleTester.run('no-unused-vars', ruleNoUnusedVars, { var Hello; React.render(); `, - errors: [{message: '\'Hello\' is defined but never used.'}] + errors: [{message: '\'App\' is defined but never used.'}, {message: '\'Hello\' is defined but never used.'}] }, { code: ` /* eslint jsx-uses-vars: 1 */ From 9aa539d04a724246025ceb7b3d287338df0a8148 Mon Sep 17 00:00:00 2001 From: Remco Haszing Date: Tue, 11 May 2021 22:23:57 +0200 Subject: [PATCH 10/16] [Fix] `jsx-no-undef`: ignore namespaces JSX namespaces are transpiled into strings, not identifiers. --- CHANGELOG.md | 2 ++ lib/rules/jsx-no-undef.js | 3 +-- tests/lib/rules/jsx-no-undef.js | 8 ++------ 3 files changed, 5 insertions(+), 8 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 99148c8af5..1f2a4bec16 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,7 @@ This change log adheres to standards from [Keep a CHANGELOG](http://keepachangel ### Fixed * [`jsx-handler-names`]: properly substitute value into message ([#2975][] @G-Rath) * [`jsx-uses-vars`]: ignore namespaces ([#2985][] @remcohaszing) +* [`jsx-no-undef`]: ignore namespaces ([#2986][] @remcohaszing) ### Changed * [Docs] [`jsx-newline`]: Fix minor spelling error on rule name ([#2974][] @DennisSkoko) @@ -19,6 +20,7 @@ This change log adheres to standards from [Keep a CHANGELOG](http://keepachangel * [readme] fix missing trailing commas ([#2980][] @sugardon) * [readme] fix broken anchor link ([#2982][] @vzvu3k6k) +[#2986]: https://github.com/yannickcr/eslint-plugin-react/pull/2986 [#2985]: https://github.com/yannickcr/eslint-plugin-react/pull/2985 [#2982]: https://github.com/yannickcr/eslint-plugin-react/pull/2982 [#2980]: https://github.com/yannickcr/eslint-plugin-react/pull/2980 diff --git a/lib/rules/jsx-no-undef.js b/lib/rules/jsx-no-undef.js index f4e94c4059..939027ddac 100644 --- a/lib/rules/jsx-no-undef.js +++ b/lib/rules/jsx-no-undef.js @@ -102,8 +102,7 @@ module.exports = { } while (node && node.type !== 'JSXIdentifier'); break; case 'JSXNamespacedName': - node = node.name.namespace; - break; + return; default: break; } diff --git a/tests/lib/rules/jsx-no-undef.js b/tests/lib/rules/jsx-no-undef.js index e2bcb30abb..40f498befd 100644 --- a/tests/lib/rules/jsx-no-undef.js +++ b/tests/lib/rules/jsx-no-undef.js @@ -45,6 +45,8 @@ ruleTester.run('jsx-no-undef', rule, { code: '/*eslint no-undef:1*/ var React, app; React.render();' }, { code: '/*eslint no-undef:1*/ var React, app; React.render();' + }, { + code: '/*eslint no-undef:1*/ var React; React.render();' }, { code: ` /*eslint no-undef:1*/ @@ -87,12 +89,6 @@ ruleTester.run('jsx-no-undef', rule, { messageId: 'undefined', data: {identifier: 'Appp'} }] - }, { - code: '/*eslint no-undef:1*/ var React; React.render();', - errors: [{ - messageId: 'undefined', - data: {identifier: 'Apppp'} - }] }, { code: '/*eslint no-undef:1*/ var React; React.render();', errors: [{ From 9a140a57c314d02ec7fd0acb479ad6fd8658bc76 Mon Sep 17 00:00:00 2001 From: Pascal Date: Tue, 18 May 2021 12:35:47 -0400 Subject: [PATCH 11/16] [Fix] `jsx-child-element-spacing`: Don't flag whitespace around `
` tags Fixes #2988. --- CHANGELOG.md | 4 +++- lib/rules/jsx-child-element-spacing.js | 3 ++- tests/lib/rules/jsx-child-element-spacing.js | 25 ++++++++++++++++++++ 3 files changed, 30 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1f2a4bec16..1398575bff 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,6 +13,7 @@ This change log adheres to standards from [Keep a CHANGELOG](http://keepachangel * [`jsx-handler-names`]: properly substitute value into message ([#2975][] @G-Rath) * [`jsx-uses-vars`]: ignore namespaces ([#2985][] @remcohaszing) * [`jsx-no-undef`]: ignore namespaces ([#2986][] @remcohaszing) +* [`jsx-child-element-spacing`]: Don't flag whitespace around `
` tags ([#2989][] @pascalpp) ### Changed * [Docs] [`jsx-newline`]: Fix minor spelling error on rule name ([#2974][] @DennisSkoko) @@ -20,6 +21,7 @@ This change log adheres to standards from [Keep a CHANGELOG](http://keepachangel * [readme] fix missing trailing commas ([#2980][] @sugardon) * [readme] fix broken anchor link ([#2982][] @vzvu3k6k) +[#2989]: https://github.com/yannickcr/eslint-plugin-react/pull/2989 [#2986]: https://github.com/yannickcr/eslint-plugin-react/pull/2986 [#2985]: https://github.com/yannickcr/eslint-plugin-react/pull/2985 [#2982]: https://github.com/yannickcr/eslint-plugin-react/pull/2982 @@ -3362,4 +3364,4 @@ If you're still not using React 15 you can keep the old behavior by setting the [`function-component-definition`]: docs/rules/function-component-definition.md [`jsx-newline`]: docs/rules/jsx-newline.md [`jsx-no-constructed-context-values`]: docs/rules/jsx-no-constructed-context-values.md -[`no-unstable-nested-components`]: docs/rules/no-unstable-nested-components.md +[`no-unstable-nested-components`]: docs/rules/no-unstable-nested-components.md \ No newline at end of file diff --git a/lib/rules/jsx-child-element-spacing.js b/lib/rules/jsx-child-element-spacing.js index f2bfa60483..ada192f6d4 100644 --- a/lib/rules/jsx-child-element-spacing.js +++ b/lib/rules/jsx-child-element-spacing.js @@ -3,6 +3,8 @@ const docsUrl = require('../util/docsUrl'); // This list is taken from https://developer.mozilla.org/en-US/docs/Web/HTML/Inline_elements + +// Note: 'br' is not included because whitespace around br tags is inconsequential to the rendered output const INLINE_ELEMENTS = new Set([ 'a', 'abbr', @@ -10,7 +12,6 @@ const INLINE_ELEMENTS = new Set([ 'b', 'bdo', 'big', - 'br', 'button', 'cite', 'code', diff --git a/tests/lib/rules/jsx-child-element-spacing.js b/tests/lib/rules/jsx-child-element-spacing.js index 4567ef11b1..025bef1afd 100644 --- a/tests/lib/rules/jsx-child-element-spacing.js +++ b/tests/lib/rules/jsx-child-element-spacing.js @@ -139,6 +139,31 @@ ruleTester.run('jsx-child-element-spacing', rule, { B ` + }, { + code: ` + + A +
+ B +
+ ` + }, { + code: ` + + A
+ B +
+ ` + }, { + code: ` + + A
B +
+ ` + }, { + code: ` + A
B
+ ` }], invalid: [{ From 6c1e5b3866d55f5bf33364113927896b4dec4bcf Mon Sep 17 00:00:00 2001 From: Pascal Date: Tue, 18 May 2021 12:43:42 -0400 Subject: [PATCH 12/16] [Docs] [`jsx-child-element-spacing`]: fixes sentence which ends abruptly --- CHANGELOG.md | 2 ++ docs/rules/jsx-child-element-spacing.md | 4 +--- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1398575bff..b68294fb5f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -20,7 +20,9 @@ This change log adheres to standards from [Keep a CHANGELOG](http://keepachangel * [Refactor] [`void-dom-elements-no-children`]: improve performance * [readme] fix missing trailing commas ([#2980][] @sugardon) * [readme] fix broken anchor link ([#2982][] @vzvu3k6k) +* [Docs] [`jsx-child-element-spacing`]: fixes sentence which ends abruptly ([#2990][] @pascalpp) +[#2990]: https://github.com/yannickcr/eslint-plugin-react/pull/2990 [#2989]: https://github.com/yannickcr/eslint-plugin-react/pull/2989 [#2986]: https://github.com/yannickcr/eslint-plugin-react/pull/2986 [#2985]: https://github.com/yannickcr/eslint-plugin-react/pull/2985 diff --git a/docs/rules/jsx-child-element-spacing.md b/docs/rules/jsx-child-element-spacing.md index 0374c05c28..3deb7dc041 100644 --- a/docs/rules/jsx-child-element-spacing.md +++ b/docs/rules/jsx-child-element-spacing.md @@ -2,9 +2,7 @@ ## Rule Details -Since React removes extraneous new lines between elements when possible, -it is possible to end up with inline elements that are not rendered with spaces between them and adjacent text. -This is often indicative of an error, so this rule attempts to detect +Since React removes extraneous new lines between elements when possible, it is possible to end up with inline elements that are not rendered with spaces between them and adjacent text. This is often indicative of an error, so this rule attempts to detect JSX markup with ambiguous spacing. Examples of **incorrect** code for this rule: From f0e67007afbffe828b16a671787c2f207302e253 Mon Sep 17 00:00:00 2001 From: Jordan Harband Date: Thu, 27 May 2021 22:24:16 -0700 Subject: [PATCH 13/16] [Dev Deps] pin `@types/eslint` due to a breaking change in a patch See https://github.com/DefinitelyTyped/DefinitelyTyped/pull/52730#pullrequestreview-670937218 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 620db84fb2..5c2dd26355 100644 --- a/package.json +++ b/package.json @@ -42,7 +42,7 @@ "string.prototype.matchall": "^4.0.4" }, "devDependencies": { - "@types/eslint": "^7.2.8", + "@types/eslint": "=7.2.10", "@types/estree": "^0.0.47", "@types/node": "^14.14.37", "@typescript-eslint/parser": "^2.34.0", From 880ab8c9ed8a5d1c44110d3f313193346f8e6c48 Mon Sep 17 00:00:00 2001 From: JounQin Date: Tue, 13 Apr 2021 10:06:37 +0000 Subject: [PATCH 14/16] [Fix] version detection: support recursive processor virtual filename --- CHANGELOG.md | 4 +++- lib/util/version.js | 15 +++++++-------- tests/util/version.js | 8 ++++++++ 3 files changed, 18 insertions(+), 9 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b68294fb5f..a3fdb5b93d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,7 @@ This change log adheres to standards from [Keep a CHANGELOG](http://keepachangel ### Added * component detection: add componentWrapperFunctions setting ([#2713][] @@jzabala @LandonSchropp) * [`no-unused-prop-types`]: add ignore option ([#2972][] @grit96) +* version detection: support recursive processor virtual filename ([#2965][] @JounQin) ### Fixed * [`jsx-handler-names`]: properly substitute value into message ([#2975][] @G-Rath) @@ -32,6 +33,7 @@ This change log adheres to standards from [Keep a CHANGELOG](http://keepachangel [#2975]: https://github.com/yannickcr/eslint-plugin-react/pull/2975 [#2974]: https://github.com/yannickcr/eslint-plugin-react/pull/2974 [#2972]: https://github.com/yannickcr/eslint-plugin-react/pull/2972 +[#2965]: https://github.com/yannickcr/eslint-plugin-react/pull/2965 [#2713]: https://github.com/yannickcr/eslint-plugin-react/pull/2713 ## [7.23.2] - 2021.04.08 @@ -3366,4 +3368,4 @@ If you're still not using React 15 you can keep the old behavior by setting the [`function-component-definition`]: docs/rules/function-component-definition.md [`jsx-newline`]: docs/rules/jsx-newline.md [`jsx-no-constructed-context-values`]: docs/rules/jsx-no-constructed-context-values.md -[`no-unstable-nested-components`]: docs/rules/no-unstable-nested-components.md \ No newline at end of file +[`no-unstable-nested-components`]: docs/rules/no-unstable-nested-components.md diff --git a/lib/util/version.js b/lib/util/version.js index 8534f10025..b778c8b940 100644 --- a/lib/util/version.js +++ b/lib/util/version.js @@ -22,25 +22,24 @@ function resetDetectedVersion() { cachedDetectedReactVersion = undefined; } -function resolveBasedir(context) { - let basedir = process.cwd(); - if (context) { - const filename = context.getFilename(); +function resolveBasedir(contextOrFilename) { + if (contextOrFilename) { + const filename = typeof contextOrFilename === 'string' ? contextOrFilename : contextOrFilename.getFilename(); const dirname = path.dirname(filename); try { if (fs.statSync(filename).isFile()) { // dirname must be dir here - basedir = dirname; + return dirname; } } catch (err) { // https://github.com/eslint/eslint/issues/11989 if (err.code === 'ENOTDIR') { - // the error code alreay indicates that dirname is a file - basedir = path.dirname(dirname); + // virtual filename could be recursive + return resolveBasedir(dirname); } } } - return basedir; + return process.cwd(); } // TODO, semver-major: remove context fallback diff --git a/tests/util/version.js b/tests/util/version.js index bd08f2922c..f43c603f53 100644 --- a/tests/util/version.js +++ b/tests/util/version.js @@ -87,6 +87,14 @@ describe('Version', () => { assert.equal(versionUtil.testReactVersion(context, '2.3.5'), false); assert.equal(versionUtil.testFlowVersion(context, '2.92.0'), true); }); + + it('works with recursive virtual filename', () => { + sinon.stub(context, 'getFilename').callsFake(() => path.resolve(base, 'detect-version-sibling', 'test.js/0_fake.md/1_fake.js')); + + assert.equal(versionUtil.testReactVersion(context, '2.3.4'), true); + assert.equal(versionUtil.testReactVersion(context, '2.3.5'), false); + assert.equal(versionUtil.testFlowVersion(context, '2.92.0'), true); + }); }); describe('string version', () => { From 58123c48dd3ebab8ca41ab0e5246213cfdab4a51 Mon Sep 17 00:00:00 2001 From: Jordan Harband Date: Thu, 27 May 2021 23:01:26 -0700 Subject: [PATCH 15/16] [Deps] update `object.entries`, `object.values`, `string.prototype.matchall` --- package.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/package.json b/package.json index 5c2dd26355..80a2d1c09e 100644 --- a/package.json +++ b/package.json @@ -34,12 +34,12 @@ "has": "^1.0.3", "jsx-ast-utils": "^2.4.1 || ^3.0.0", "minimatch": "^3.0.4", - "object.entries": "^1.1.3", + "object.entries": "^1.1.4", "object.fromentries": "^2.0.4", - "object.values": "^1.1.3", + "object.values": "^1.1.4", "prop-types": "^15.7.2", "resolve": "^2.0.0-next.3", - "string.prototype.matchall": "^4.0.4" + "string.prototype.matchall": "^4.0.5" }, "devDependencies": { "@types/eslint": "=7.2.10", From 291acbfd6a2caf3934179683c559bb686ff4dbc7 Mon Sep 17 00:00:00 2001 From: Jordan Harband Date: Sat, 29 May 2021 13:05:15 -0700 Subject: [PATCH 16/16] Update CHANGELOG and bump version --- CHANGELOG.md | 3 +++ package.json | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a3fdb5b93d..16a472d6a2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,8 @@ This change log adheres to standards from [Keep a CHANGELOG](http://keepachangel ## Unreleased +## [7.24.0] - 2021.05.27 + ### Added * component detection: add componentWrapperFunctions setting ([#2713][] @@jzabala @LandonSchropp) * [`no-unused-prop-types`]: add ignore option ([#2972][] @grit96) @@ -23,6 +25,7 @@ This change log adheres to standards from [Keep a CHANGELOG](http://keepachangel * [readme] fix broken anchor link ([#2982][] @vzvu3k6k) * [Docs] [`jsx-child-element-spacing`]: fixes sentence which ends abruptly ([#2990][] @pascalpp) +[7.24.0]: https://github.com/yannickcr/eslint-plugin-react/compare/v7.23.2...v7.24.0 [#2990]: https://github.com/yannickcr/eslint-plugin-react/pull/2990 [#2989]: https://github.com/yannickcr/eslint-plugin-react/pull/2989 [#2986]: https://github.com/yannickcr/eslint-plugin-react/pull/2986 diff --git a/package.json b/package.json index 80a2d1c09e..56bb9842d8 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "eslint-plugin-react", - "version": "7.23.2", + "version": "7.24.0", "author": "Yannick Croissant ", "description": "React specific linting rules for ESLint", "main": "index.js",