From 493e23ab211532f65711204d444c63f7f1b8b9f8 Mon Sep 17 00:00:00 2001
From: etherealm13 <finitehour@gmail.com>
Date: Mon, 22 Jul 2024 22:56:44 +0530
Subject: [PATCH 1/3] [New] `padding-lines-between-tags`: add rule and test
 cases

---
 README.md                                |  84 +++++-----
 docs/rules/padding-lines-between-tags.md | 152 ++++++++++++++++++
 lib/rules/index.js                       |   1 +
 lib/rules/padding-lines-between-tags.js  | 189 +++++++++++++++++++++++
 4 files changed, 381 insertions(+), 45 deletions(-)
 create mode 100644 docs/rules/padding-lines-between-tags.md
 create mode 100644 lib/rules/padding-lines-between-tags.js

diff --git a/README.md b/README.md
index e77a809efe..1a13ff5d99 100644
--- a/README.md
+++ b/README.md
@@ -34,47 +34,47 @@ You should also specify settings that will be shared across all the plugin rules
 
 ```json5
 {
-  "settings": {
-    "react": {
-      "createClass": "createReactClass", // Regex for Component Factory to use,
-                                         // default to "createReactClass"
-      "pragma": "React",  // Pragma to use, default to "React"
-      "fragment": "Fragment",  // Fragment to use (may be a property of <pragma>), default to "Fragment"
-      "version": "detect", // React version. "detect" automatically picks the version you have installed.
-                           // You can also use `16.0`, `16.3`, etc, if you want to override the detected value.
-                           // Defaults to the "defaultVersion" setting and warns if missing, and to "detect" in the future
-      "defaultVersion": "", // Default React version to use when the version you have installed cannot be detected.
-                            // If not provided, defaults to the latest React version.
-      "flowVersion": "0.53" // Flow version
+  settings: {
+    react: {
+      createClass: 'createReactClass', // Regex for Component Factory to use,
+      // default to "createReactClass"
+      pragma: 'React', // Pragma to use, default to "React"
+      fragment: 'Fragment', // Fragment to use (may be a property of <pragma>), default to "Fragment"
+      version: 'detect', // React version. "detect" automatically picks the version you have installed.
+      // You can also use `16.0`, `16.3`, etc, if you want to override the detected value.
+      // Defaults to the "defaultVersion" setting and warns if missing, and to "detect" in the future
+      defaultVersion: '', // Default React version to use when the version you have installed cannot be detected.
+      // If not provided, defaults to the latest React version.
+      flowVersion: '0.53', // Flow version
     },
-    "propWrapperFunctions": [
-        // The names of any function used to wrap propTypes, e.g. `forbidExtraProps`. If this isn't set, any propTypes wrapped in a function will be skipped.
-        "forbidExtraProps",
-        {"property": "freeze", "object": "Object"},
-        {"property": "myFavoriteWrapper"},
-        // for rules that check exact prop wrappers
-        {"property": "forbidExtraProps", "exact": true}
+    propWrapperFunctions: [
+      // The names of any function used to wrap propTypes, e.g. `forbidExtraProps`. If this isn't set, any propTypes wrapped in a function will be skipped.
+      'forbidExtraProps',
+      { property: 'freeze', object: 'Object' },
+      { property: 'myFavoriteWrapper' },
+      // for rules that check exact prop wrappers
+      { property: 'forbidExtraProps', exact: true },
     ],
-    "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": "<pragma>"} // sets `object` to whatever value `settings.react.pragma` is set to
+    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: '<pragma>' }, // sets `object` to whatever value `settings.react.pragma` is set to
     ],
-    "formComponents": [
+    formComponents: [
       // Components used as alternatives to <form> for forms, eg. <Form endpoint={ url } />
-      "CustomForm",
-      {"name": "SimpleForm", "formAttribute": "endpoint"},
-      {"name": "Form", "formAttribute": ["registerEndpoint", "loginEndpoint"]}, // allows specifying multiple properties if necessary
+      'CustomForm',
+      { name: 'SimpleForm', formAttribute: 'endpoint' },
+      { name: 'Form', formAttribute: ['registerEndpoint', 'loginEndpoint'] }, // allows specifying multiple properties if necessary
     ],
-    "linkComponents": [
+    linkComponents: [
       // Components used as alternatives to <a> for linking, eg. <Link to={ url } />
-      "Hyperlink",
-      {"name": "MyLink", "linkAttribute": "to"},
-      {"name": "Link", "linkAttribute": ["to", "href"]}, // allows specifying multiple properties if necessary
-    ]
-  }
+      'Hyperlink',
+      { name: 'MyLink', linkAttribute: 'to' },
+      { name: 'Link', linkAttribute: ['to', 'href'] }, // allows specifying multiple properties if necessary
+    ],
+  },
 }
 ```
 
@@ -84,9 +84,7 @@ Add "react" to the plugins section.
 
 ```json
 {
-  "plugins": [
-    "react"
-  ]
+  "plugins": ["react"]
 }
 ```
 
@@ -136,9 +134,7 @@ This pairs well with the `eslint:all` rule.
 
 ```json
 {
-  "plugins": [
-    "react"
-  ],
+  "plugins": ["react"],
   "extends": ["eslint:all", "plugin:react/all"]
 }
 ```
@@ -205,6 +201,7 @@ Refer to the [official docs](https://eslint.org/docs/latest/user-guide/configuri
 The schema of the `settings.react` object would be identical to that of what's already described above in the legacy config section.
 
 <!-- markdownlint-disable-next-line no-duplicate-heading -->
+
 ### Flat Configs
 
 This plugin exports 3 flat configs:
@@ -375,6 +372,7 @@ module.exports = [
 | [no-unused-prop-types](docs/rules/no-unused-prop-types.md)                                   | Disallow definitions of unused propTypes                                                                                                     |    |    |    |    |    |
 | [no-unused-state](docs/rules/no-unused-state.md)                                             | Disallow definitions of unused state                                                                                                         |    |    |    |    |    |
 | [no-will-update-set-state](docs/rules/no-will-update-set-state.md)                           | Disallow usage of setState in componentWillUpdate                                                                                            |    |    |    |    |    |
+| [padding-lines-between-tags](docs/rules/padding-lines-between-tags.md)                       | Enforce no padding lines between tags for React Components                                                                                   |    |    | 🔧 |    |    |
 | [prefer-es6-class](docs/rules/prefer-es6-class.md)                                           | Enforce ES5 or ES6 class for React Components                                                                                                |    |    |    |    |    |
 | [prefer-exact-props](docs/rules/prefer-exact-props.md)                                       | Prefer exact proptype definitions                                                                                                            |    |    |    |    |    |
 | [prefer-read-only-props](docs/rules/prefer-read-only-props.md)                               | Enforce that props are read-only                                                                                                             |    |    | 🔧 |    |    |
@@ -407,15 +405,11 @@ module.exports = [
 
 [npm-url]: https://npmjs.org/package/eslint-plugin-react
 [npm-image]: https://img.shields.io/npm/v/eslint-plugin-react.svg
-
 [status-url]: https://github.com/jsx-eslint/eslint-plugin-react/pulse
 [status-image]: https://img.shields.io/github/last-commit/jsx-eslint/eslint-plugin-react.svg
-
 [tidelift-url]: https://tidelift.com/subscription/pkg/npm-eslint-plugin-react?utm_source=npm-eslint-plugin-react&utm_medium=referral&utm_campaign=readme
 [tidelift-image]: https://tidelift.com/badges/package/npm/eslint-plugin-react?style=flat
-
 [package-url]: https://npmjs.org/package/eslint-plugin-react
 [npm-version-svg]: https://versionbadg.es/jsx-eslint/eslint-plugin-react.svg
-
 [actions-image]: https://img.shields.io/endpoint?url=https://github-actions-badge-u3jn4tfpocch.runkit.sh/jsx-eslint/eslint-plugin-react
 [actions-url]: https://github.com/jsx-eslint/eslint-plugin-react/actions
diff --git a/docs/rules/padding-lines-between-tags.md b/docs/rules/padding-lines-between-tags.md
new file mode 100644
index 0000000000..42e2c0067c
--- /dev/null
+++ b/docs/rules/padding-lines-between-tags.md
@@ -0,0 +1,152 @@
+# Enforce no padding lines between tags for React Components (`react/padding-lines-between-tags`)
+
+🔧 This rule is automatically fixable by the [`--fix` CLI option](https://eslint.org/docs/latest/user-guide/command-line-interface#--fix).
+
+<!-- end auto-generated rule header -->
+
+Require or disallow newlines between sibling tags in React.
+
+## Rule Details Options
+
+```json
+{
+  "padding-line-between-tags": [
+    "error",
+    [{ "blankLine": "always", "prev": "*", "next": "*" }]
+  ]
+}
+```
+
+This rule requires blank lines between each sibling HTML tag by default.
+
+A configuration is an object which has 3 properties; `blankLine`, `prev` and `next`. For example, `{ blankLine: "always", prev: "br", next: "div" }` means “one or more blank lines are required between a `br` tag and a `div` tag.” You can supply any number of configurations. If a tag pair matches multiple configurations, the last matched configuration will be used.
+
+- `blankLine` is one of the following:
+  - `always` requires one or more blank lines.
+  - `never` disallows blank lines.
+  - `consistent` requires or disallows a blank line based on the first sibling element.
+- `prev` any tag name without brackets.
+- `next` any tag name without brackets.
+
+### Disallow blank lines between all tags
+
+`{ blankLine: 'never', prev: '*', next: '*' }`
+
+<eslint-code-block fix :rules="{'padding-line-between-tags': ['error', [
+  { blankLine: 'never', prev: '*', next: '*' }
+]]}">
+
+```react
+<App>
+  <div>
+    <div></div>
+    <div>
+    </div>
+    <div />
+  </div>
+</App>
+```
+
+</eslint-code-block>
+
+### Require newlines after `<br>`
+
+`{ blankLine: 'always', prev: 'br', next: '*' }`
+
+<eslint-code-block fix :rules="{'react/padding-line-between-tags': ['error', [
+  { blankLine: 'always', prev: 'br', next: '*' }
+]]}">
+
+```react
+<App>
+  <div>
+    <ul>
+      <li>
+      </li>
+      <br />
+
+      <li>
+      </li>
+    </ul>
+  </div>
+</App>
+```
+
+</eslint-code-block>
+
+### Require newlines between `<br>` and `<img>`
+
+`{ blankLine: 'always', prev: 'br', next: 'img' }`
+
+<eslint-code-block fix :rules="{'react/padding-line-between-tags': ['error', [
+{ blankLine: 'always', prev: 'br', next: 'img' },
+{ blankLine: 'always', prev: 'li', next: 'li' },
+]]}">
+
+```react
+<App>
+  <div>
+    <ul>
+      <li>
+      </li>
+      <li>
+      </li>
+      <br />
+      <img />
+      <li>
+      </li>
+    </ul>
+  </div>
+</App>
+```
+
+```react [Fixed]
+<App>
+  <div>
+    <ul>
+      <li>
+      </li>
+
+      <li>
+      </li>
+      <br />
+
+      <img />
+      <li>
+      </li>
+    </ul>
+  </div>
+</App>
+```
+
+</eslint-code-block>
+
+### Require consistent newlines
+
+`{ blankLine: 'consistent', prev: '*', next: '*' }`
+
+<eslint-code-block fix :rules="{'react/padding-line-between-tags': ['error', [
+  { blankLine: 'consistent', prev: '*', next: '*' }
+]]}">
+
+```react
+<App>
+  <div>
+    <ul>
+      <li />
+      <li />
+      <li />
+    </ul>
+
+    <div />
+
+    <div />
+  </div>
+</App>
+```
+
+</eslint-code-block>
+
+## When Not To Use It
+
+If you are not using React.
diff --git a/lib/rules/index.js b/lib/rules/index.js
index 11a4475ba2..2b17db2401 100644
--- a/lib/rules/index.js
+++ b/lib/rules/index.js
@@ -89,6 +89,7 @@ module.exports = {
   'no-unused-state': require('./no-unused-state'),
   'no-object-type-as-default-prop': require('./no-object-type-as-default-prop'),
   'no-will-update-set-state': require('./no-will-update-set-state'),
+  'padding-lines-between-tags': require('./padding-lines-between-tags'),
   'prefer-es6-class': require('./prefer-es6-class'),
   'prefer-exact-props': require('./prefer-exact-props'),
   'prefer-read-only-props': require('./prefer-read-only-props'),
diff --git a/lib/rules/padding-lines-between-tags.js b/lib/rules/padding-lines-between-tags.js
new file mode 100644
index 0000000000..c3fbc2583a
--- /dev/null
+++ b/lib/rules/padding-lines-between-tags.js
@@ -0,0 +1,189 @@
+/**
+ * @fileoverview Enforce no padding lines between tags for React Components
+ * @author Alankar Anand
+ * Based on https://github.com/vuejs/eslint-plugin-vue/blob/master/lib/rules/padding-line-between-tags.js
+ * https://github.com/jsx-eslint/eslint-plugin-react/issues/3554
+ */
+
+'use strict';
+
+const docsUrl = require('../util/docsUrl');
+
+/**
+ * Split the source code into multiple lines based on the line delimiters.
+ * Copied from padding-line-between-blocks
+ * @param {string} text Source code as a string.
+ * @returns {string[]} Array of source code lines.
+ */
+const messages = {
+  never: 'Unexpected blank line before this tag.',
+  always: 'Expected blank line before this tag.',
+};
+
+function splitLines(text) {
+  return text.split(/\r\n|[\r\n\u2028\u2029]/gu);
+}
+
+function insertNewLine(context, tag, sibling, lineDifference) {
+  const endTag = tag.closingElement || tag.openingElement;
+
+  if (lineDifference === 1) {
+    context.report({
+      messageId: 'always',
+      loc: sibling && sibling.loc,
+      // @ts-ignore
+      fix(fixer) {
+        return fixer.insertTextAfter(tag, '\n');
+      },
+    });
+  } else if (lineDifference === 0) {
+    context.report({
+      messageId: 'always',
+      loc: sibling && sibling.loc,
+      // @ts-ignore
+      fix(fixer) {
+        const lastSpaces = /** @type {RegExpExecArray} */ (
+          /^\s*/.exec(context.getSourceCode().lines[endTag.loc.start.line - 1])
+        )[0];
+
+        return fixer.insertTextAfter(endTag, `\n\n${lastSpaces}`);
+      },
+    });
+  }
+}
+
+function removeExcessLines(context, endTag, sibling, lineDifference) {
+  if (lineDifference > 1) {
+    let hasOnlyTextBetween = true;
+    for (
+      let i = endTag.loc && endTag.loc.start.line;
+      i < sibling.loc.start.line - 1 && hasOnlyTextBetween;
+      i++
+    ) {
+      hasOnlyTextBetween = !/^\s*$/.test(context.getSourceCode().lines[i]);
+    }
+    if (!hasOnlyTextBetween) {
+      context.report({
+        messageId: 'never',
+        loc: sibling && sibling.loc,
+        // @ts-ignore
+        fix(fixer) {
+          const start = endTag.range[1];
+          const end = sibling.range[0];
+          const paddingText = context.getSourceCode().text.slice(start, end);
+          const textBetween = splitLines(paddingText);
+          let newTextBetween = `\n${textBetween.pop()}`;
+          for (let i = textBetween.length - 1; i >= 0; i--) {
+            if (!/^\s*$/.test(textBetween[i])) {
+              newTextBetween = `${i === 0 ? '' : '\n'}${
+                textBetween[i]
+              }${newTextBetween}`;
+            }
+          }
+          return fixer.replaceTextRange([start, end], `${newTextBetween}`);
+        },
+      });
+    }
+  }
+}
+
+function checkNewLine(context, configureList) {
+  const firstConsistentBlankLines = new Map();
+
+  const reverseConfigureList = [...configureList].reverse();
+
+  return (node) => {
+    if (!node.parent.parent) {
+      return;
+    }
+
+    const endTag = node.closingElement || node.openingElement;
+
+    if (!node.parent.children) {
+      return;
+    }
+    const lowerSiblings = node.parent.children
+      .filter(
+        (element) => element.type === 'JSXElement' && element.range !== node.range
+      )
+      .filter((sibling) => sibling.range[0] - endTag.range[1] >= 0);
+
+    if (lowerSiblings.length === 0) {
+      return;
+    }
+    const closestSibling = lowerSiblings[0];
+
+    const lineDifference = closestSibling.loc.start.line - endTag.loc.end.line;
+
+    const configure = reverseConfigureList.find(
+      (config) => (config.prev === '*'
+          || node.openingElement.name.name === config.prev)
+        && (config.next === '*'
+          || closestSibling.openingElement.name.name === config.next)
+    );
+
+    if (!configure) {
+      return;
+    }
+
+    let blankLine = configure.blankLine;
+
+    if (blankLine === 'consistent') {
+      const firstConsistentBlankLine = firstConsistentBlankLines.get(
+        node.parent
+      );
+      if (firstConsistentBlankLine == null) {
+        firstConsistentBlankLines.set(
+          node.parent,
+          lineDifference > 1 ? 'always' : 'never'
+        );
+        return;
+      }
+      blankLine = firstConsistentBlankLine;
+    }
+
+    if (blankLine === 'always') {
+      insertNewLine(context, node, closestSibling, lineDifference);
+    } else {
+      removeExcessLines(context, endTag, closestSibling, lineDifference);
+    }
+  };
+}
+
+/** @type {import('eslint').Rule.RuleModule} */
+module.exports = {
+  meta: {
+    docs: {
+      description: 'Enforce no padding lines between tags for React Components',
+      category: 'Stylistic Issues',
+      recommended: false,
+      url: docsUrl('padding-lines-between-tags'),
+    },
+    fixable: 'code',
+    messages,
+    schema: [
+      {
+        type: 'array',
+        items: {
+          type: 'object',
+          properties: {
+            blankLine: { enum: ['always', 'never', 'consistent'] },
+            prev: { type: 'string' },
+            next: { type: 'string' },
+          },
+          additionalProperties: false,
+          required: ['blankLine', 'prev', 'next'],
+        },
+      },
+    ],
+  },
+
+  create(context) {
+    const configureList = context.options[0] || [
+      { blankLine: 'always', prev: '*', next: '*' },
+    ];
+    return {
+      JSXElement: checkNewLine(context, configureList),
+    };
+  },
+};

From 580b3038b44c04d85b959cd9097b0f7138998f9c Mon Sep 17 00:00:00 2001
From: etherealm13 <finitehour@gmail.com>
Date: Sat, 27 Jul 2024 00:22:15 +0530
Subject: [PATCH 2/3] resolved pr comments related to docs and rule

---
 README.md                                | 83 +++++++++++++-----------
 docs/rules/padding-lines-between-tags.md | 39 ++---------
 lib/rules/padding-lines-between-tags.js  | 36 +++++-----
 3 files changed, 69 insertions(+), 89 deletions(-)

diff --git a/README.md b/README.md
index 1a13ff5d99..56e7c3f670 100644
--- a/README.md
+++ b/README.md
@@ -34,47 +34,47 @@ You should also specify settings that will be shared across all the plugin rules
 
 ```json5
 {
-  settings: {
-    react: {
-      createClass: 'createReactClass', // Regex for Component Factory to use,
-      // default to "createReactClass"
-      pragma: 'React', // Pragma to use, default to "React"
-      fragment: 'Fragment', // Fragment to use (may be a property of <pragma>), default to "Fragment"
-      version: 'detect', // React version. "detect" automatically picks the version you have installed.
-      // You can also use `16.0`, `16.3`, etc, if you want to override the detected value.
-      // Defaults to the "defaultVersion" setting and warns if missing, and to "detect" in the future
-      defaultVersion: '', // Default React version to use when the version you have installed cannot be detected.
-      // If not provided, defaults to the latest React version.
-      flowVersion: '0.53', // Flow version
+  "settings": {
+    "react": {
+      "createClass": "createReactClass", // Regex for Component Factory to use,
+                                         // default to "createReactClass"
+      "pragma": "React",  // Pragma to use, default to "React"
+      "fragment": "Fragment",  // Fragment to use (may be a property of <pragma>), default to "Fragment"
+      "version": "detect", // React version. "detect" automatically picks the version you have installed.
+                           // You can also use `16.0`, `16.3`, etc, if you want to override the detected value.
+                           // Defaults to the "defaultVersion" setting and warns if missing, and to "detect" in the future
+      "defaultVersion": "", // Default React version to use when the version you have installed cannot be detected.
+                            // If not provided, defaults to the latest React version.
+      "flowVersion": "0.53" // Flow version
     },
-    propWrapperFunctions: [
-      // The names of any function used to wrap propTypes, e.g. `forbidExtraProps`. If this isn't set, any propTypes wrapped in a function will be skipped.
-      'forbidExtraProps',
-      { property: 'freeze', object: 'Object' },
-      { property: 'myFavoriteWrapper' },
-      // for rules that check exact prop wrappers
-      { property: 'forbidExtraProps', exact: true },
+    "propWrapperFunctions": [
+        // The names of any function used to wrap propTypes, e.g. `forbidExtraProps`. If this isn't set, any propTypes wrapped in a function will be skipped.
+        "forbidExtraProps",
+        {"property": "freeze", "object": "Object"},
+        {"property": "myFavoriteWrapper"},
+        // for rules that check exact prop wrappers
+        {"property": "forbidExtraProps", "exact": true}
     ],
-    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: '<pragma>' }, // sets `object` to whatever value `settings.react.pragma` is set to
+    "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": "<pragma>"} // sets `object` to whatever value `settings.react.pragma` is set to
     ],
-    formComponents: [
+    "formComponents": [
       // Components used as alternatives to <form> for forms, eg. <Form endpoint={ url } />
-      'CustomForm',
-      { name: 'SimpleForm', formAttribute: 'endpoint' },
-      { name: 'Form', formAttribute: ['registerEndpoint', 'loginEndpoint'] }, // allows specifying multiple properties if necessary
+      "CustomForm",
+      {"name": "SimpleForm", "formAttribute": "endpoint"},
+      {"name": "Form", "formAttribute": ["registerEndpoint", "loginEndpoint"]}, // allows specifying multiple properties if necessary
     ],
-    linkComponents: [
+    "linkComponents": [
       // Components used as alternatives to <a> for linking, eg. <Link to={ url } />
-      'Hyperlink',
-      { name: 'MyLink', linkAttribute: 'to' },
-      { name: 'Link', linkAttribute: ['to', 'href'] }, // allows specifying multiple properties if necessary
-    ],
-  },
+      "Hyperlink",
+      {"name": "MyLink", "linkAttribute": "to"},
+      {"name": "Link", "linkAttribute": ["to", "href"]}, // allows specifying multiple properties if necessary
+    ]
+  }
 }
 ```
 
@@ -84,7 +84,9 @@ Add "react" to the plugins section.
 
 ```json
 {
-  "plugins": ["react"]
+  "plugins": [
+    "react"
+  ]
 }
 ```
 
@@ -134,7 +136,9 @@ This pairs well with the `eslint:all` rule.
 
 ```json
 {
-  "plugins": ["react"],
+  "plugins": [
+    "react"
+  ],
   "extends": ["eslint:all", "plugin:react/all"]
 }
 ```
@@ -201,7 +205,6 @@ Refer to the [official docs](https://eslint.org/docs/latest/user-guide/configuri
 The schema of the `settings.react` object would be identical to that of what's already described above in the legacy config section.
 
 <!-- markdownlint-disable-next-line no-duplicate-heading -->
-
 ### Flat Configs
 
 This plugin exports 3 flat configs:
@@ -405,11 +408,15 @@ module.exports = [
 
 [npm-url]: https://npmjs.org/package/eslint-plugin-react
 [npm-image]: https://img.shields.io/npm/v/eslint-plugin-react.svg
+
 [status-url]: https://github.com/jsx-eslint/eslint-plugin-react/pulse
 [status-image]: https://img.shields.io/github/last-commit/jsx-eslint/eslint-plugin-react.svg
+
 [tidelift-url]: https://tidelift.com/subscription/pkg/npm-eslint-plugin-react?utm_source=npm-eslint-plugin-react&utm_medium=referral&utm_campaign=readme
 [tidelift-image]: https://tidelift.com/badges/package/npm/eslint-plugin-react?style=flat
+
 [package-url]: https://npmjs.org/package/eslint-plugin-react
 [npm-version-svg]: https://versionbadg.es/jsx-eslint/eslint-plugin-react.svg
+
 [actions-image]: https://img.shields.io/endpoint?url=https://github-actions-badge-u3jn4tfpocch.runkit.sh/jsx-eslint/eslint-plugin-react
 [actions-url]: https://github.com/jsx-eslint/eslint-plugin-react/actions
diff --git a/docs/rules/padding-lines-between-tags.md b/docs/rules/padding-lines-between-tags.md
index 42e2c0067c..f25fed53f1 100644
--- a/docs/rules/padding-lines-between-tags.md
+++ b/docs/rules/padding-lines-between-tags.md
@@ -19,7 +19,7 @@ Require or disallow newlines between sibling tags in React.
 
 This rule requires blank lines between each sibling HTML tag by default.
 
-A configuration is an object which has 3 properties; `blankLine`, `prev` and `next`. For example, `{ blankLine: "always", prev: "br", next: "div" }` means “one or more blank lines are required between a `br` tag and a `div` tag.” You can supply any number of configurations. If a tag pair matches multiple configurations, the last matched configuration will be used.
+A configuration is an object which has 3 properties; `blankLine`, `prev`, and `next`. For example, `{ blankLine: "always", prev: "br", next: "div" }` means “one or more blank lines are required between a `br` tag and a `div` tag.” You can supply any number of configurations. If a tag pair matches multiple configurations, the last matched configuration will be used.
 
 - `blankLine` is one of the following:
   - `always` requires one or more blank lines.
@@ -32,11 +32,7 @@ A configuration is an object which has 3 properties; `blankLine`, `prev` and `ne
 
 `{ blankLine: 'never', prev: '*', next: '*' }`
 
-<eslint-code-block fix :rules="{'padding-line-between-tags': ['error', [
-  { blankLine: 'never', prev: '*', next: '*' }
-]]}">
-
-```react
+```jsx
 <App>
   <div>
     <div></div>
@@ -47,17 +43,11 @@ A configuration is an object which has 3 properties; `blankLine`, `prev` and `ne
 </App>
 ```
 
-</eslint-code-block>
-
 ### Require newlines after `<br>`
 
 `{ blankLine: 'always', prev: 'br', next: '*' }`
 
-<eslint-code-block fix :rules="{'react/padding-line-between-tags': ['error', [
-  { blankLine: 'always', prev: 'br', next: '*' }
-]]}">
-
-```react
+```jsx
 <App>
   <div>
     <ul>
@@ -72,18 +62,11 @@ A configuration is an object which has 3 properties; `blankLine`, `prev` and `ne
 </App>
 ```
 
-</eslint-code-block>
-
 ### Require newlines between `<br>` and `<img>`
 
 `{ blankLine: 'always', prev: 'br', next: 'img' }`
 
-<eslint-code-block fix :rules="{'react/padding-line-between-tags': ['error', [
-{ blankLine: 'always', prev: 'br', next: 'img' },
-{ blankLine: 'always', prev: 'li', next: 'li' },
-]]}">
-
-```react
+```jsx
 <App>
   <div>
     <ul>
@@ -100,7 +83,7 @@ A configuration is an object which has 3 properties; `blankLine`, `prev` and `ne
 </App>
 ```
 
-```react [Fixed]
+```jsx [Fixed]
 <App>
   <div>
     <ul>
@@ -119,17 +102,11 @@ A configuration is an object which has 3 properties; `blankLine`, `prev` and `ne
 </App>
 ```
 
-</eslint-code-block>
-
 ### Require consistent newlines
 
 `{ blankLine: 'consistent', prev: '*', next: '*' }`
 
-<eslint-code-block fix :rules="{'react/padding-line-between-tags': ['error', [
-  { blankLine: 'consistent', prev: '*', next: '*' }
-]]}">
-
-```react
+```jsx
 <App>
   <div>
     <ul>
@@ -145,8 +122,6 @@ A configuration is an object which has 3 properties; `blankLine`, `prev` and `ne
 </App>
 ```
 
-</eslint-code-block>
-
 ## When Not To Use It
 
-If you are not using React.
+If you are not using jsx.
diff --git a/lib/rules/padding-lines-between-tags.js b/lib/rules/padding-lines-between-tags.js
index c3fbc2583a..2bba3bf678 100644
--- a/lib/rules/padding-lines-between-tags.js
+++ b/lib/rules/padding-lines-between-tags.js
@@ -8,6 +8,8 @@
 'use strict';
 
 const docsUrl = require('../util/docsUrl');
+const report = require('../util/report');
+const eslintUtil = require('../util/eslint');
 
 /**
  * Split the source code into multiple lines based on the line delimiters.
@@ -15,21 +17,17 @@ const docsUrl = require('../util/docsUrl');
  * @param {string} text Source code as a string.
  * @returns {string[]} Array of source code lines.
  */
-const messages = {
-  never: 'Unexpected blank line before this tag.',
-  always: 'Expected blank line before this tag.',
-};
 
 function splitLines(text) {
   return text.split(/\r\n|[\r\n\u2028\u2029]/gu);
 }
 
-function insertNewLine(context, tag, sibling, lineDifference) {
+function insertNewLine(tag, sibling, lineDifference) {
   const endTag = tag.closingElement || tag.openingElement;
 
   if (lineDifference === 1) {
-    context.report({
-      messageId: 'always',
+    report({
+      message: 'Unexpected blank line before {{endTag}}.',
       loc: sibling && sibling.loc,
       // @ts-ignore
       fix(fixer) {
@@ -37,13 +35,13 @@ function insertNewLine(context, tag, sibling, lineDifference) {
       },
     });
   } else if (lineDifference === 0) {
-    context.report({
-      messageId: 'always',
+    report({
+      message: 'Expected blank line before {{endTag}}.',
       loc: sibling && sibling.loc,
       // @ts-ignore
       fix(fixer) {
         const lastSpaces = /** @type {RegExpExecArray} */ (
-          /^\s*/.exec(context.getSourceCode().lines[endTag.loc.start.line - 1])
+          /^\s*/.exec(eslintUtil.getSourceCode().lines[endTag.loc.start.line - 1])
         )[0];
 
         return fixer.insertTextAfter(endTag, `\n\n${lastSpaces}`);
@@ -52,7 +50,7 @@ function insertNewLine(context, tag, sibling, lineDifference) {
   }
 }
 
-function removeExcessLines(context, endTag, sibling, lineDifference) {
+function removeExcessLines(endTag, sibling, lineDifference) {
   if (lineDifference > 1) {
     let hasOnlyTextBetween = true;
     for (
@@ -60,17 +58,17 @@ function removeExcessLines(context, endTag, sibling, lineDifference) {
       i < sibling.loc.start.line - 1 && hasOnlyTextBetween;
       i++
     ) {
-      hasOnlyTextBetween = !/^\s*$/.test(context.getSourceCode().lines[i]);
+      hasOnlyTextBetween = !/^\s*$/.test(eslintUtil.getSourceCode().lines[i]);
     }
     if (!hasOnlyTextBetween) {
-      context.report({
+      report({
         messageId: 'never',
         loc: sibling && sibling.loc,
         // @ts-ignore
         fix(fixer) {
           const start = endTag.range[1];
           const end = sibling.range[0];
-          const paddingText = context.getSourceCode().text.slice(start, end);
+          const paddingText = eslintUtil.getSourceCode().text.slice(start, end);
           const textBetween = splitLines(paddingText);
           let newTextBetween = `\n${textBetween.pop()}`;
           for (let i = textBetween.length - 1; i >= 0; i--) {
@@ -87,7 +85,7 @@ function removeExcessLines(context, endTag, sibling, lineDifference) {
   }
 }
 
-function checkNewLine(context, configureList) {
+function checkNewLine(configureList) {
   const firstConsistentBlankLines = new Map();
 
   const reverseConfigureList = [...configureList].reverse();
@@ -143,15 +141,16 @@ function checkNewLine(context, configureList) {
     }
 
     if (blankLine === 'always') {
-      insertNewLine(context, node, closestSibling, lineDifference);
+      insertNewLine(node, closestSibling, lineDifference);
     } else {
-      removeExcessLines(context, endTag, closestSibling, lineDifference);
+      removeExcessLines(endTag, closestSibling, lineDifference);
     }
   };
 }
 
 /** @type {import('eslint').Rule.RuleModule} */
 module.exports = {
+  // eslint-disable-next-line eslint-plugin/prefer-message-ids
   meta: {
     docs: {
       description: 'Enforce no padding lines between tags for React Components',
@@ -160,7 +159,6 @@ module.exports = {
       url: docsUrl('padding-lines-between-tags'),
     },
     fixable: 'code',
-    messages,
     schema: [
       {
         type: 'array',
@@ -183,7 +181,7 @@ module.exports = {
       { blankLine: 'always', prev: '*', next: '*' },
     ];
     return {
-      JSXElement: checkNewLine(context, configureList),
+      JSXElement: checkNewLine(configureList),
     };
   },
 };

From 1c0268438ea8c28fe90fddfc741fe268cd192922 Mon Sep 17 00:00:00 2001
From: etherealm13 <finitehour@gmail.com>
Date: Sat, 27 Jul 2024 00:26:48 +0530
Subject: [PATCH 3/3] resolved pr comments: updated from spread to concat

---
 lib/rules/padding-lines-between-tags.js | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/lib/rules/padding-lines-between-tags.js b/lib/rules/padding-lines-between-tags.js
index 2bba3bf678..a979d988bb 100644
--- a/lib/rules/padding-lines-between-tags.js
+++ b/lib/rules/padding-lines-between-tags.js
@@ -88,7 +88,7 @@ function removeExcessLines(endTag, sibling, lineDifference) {
 function checkNewLine(configureList) {
   const firstConsistentBlankLines = new Map();
 
-  const reverseConfigureList = [...configureList].reverse();
+  const reverseConfigureList = [].concat(configureList).reverse();
 
   return (node) => {
     if (!node.parent.parent) {