Repository: jsx-eslint/eslint-plugin-react (JavaScript)

Issue:
autofix breaking all tags
Hello.
I can not say, confidently, that this is a bug or a problem with my code. But when I run eslint with --fix the lines under `jsx-sort-props` is breaking all the file and making such a mess.

Here is the output only to this file without the `--fix` flag:

```
 5:1  error  Imports should be sorted alphabetically  sort-imports-es6-autofix/sort-imports-es6
  118:9  error  Props should be sorted alphabetically    react/jsx-sort-props
  119:9  error  Props should be sorted alphabetically    react/jsx-sort-props
  120:9  error  Props should be sorted alphabetically    react/jsx-sort-props
  121:9  error  Props should be sorted alphabetically    react/jsx-sort-props
  122:9  error  Props should be sorted alphabetically    react/jsx-sort-props
  130:9  error  Props should be sorted alphabetically    react/jsx-sort-props
  132:9  error  Props should be sorted alphabetically    react/jsx-sort-props
  133:9  error  Props should be sorted alphabetically    react/jsx-sort-props
  134:9  error  Props should be sorted alphabetically    react/jsx-sort-props
  135:9  error  Props should be sorted alphabetically    react/jsx-sort-props
  136:9  error  Props should be sorted alphabetically    react/jsx-sort-props
  137:9  error  Props should be sorted alphabetically    react/jsx-sort-props
  138:9  error  Props should be sorted alphabetically    react/jsx-sort-props
  149:9  error  Props should be sorted alphabetically    react/jsx-sort-props
  150:9  error  Props should be sorted alphabetically    react/jsx-sort-props
  151:9  error  Props should be sorted alphabetically    react/jsx-sort-props
  159:9  error  Props should be sorted alphabetically    react/jsx-sort-props
  161:9  error  Props should be sorted alphabetically    react/jsx-sort-props
  162:9  error  Props should be sorted alphabetically    react/jsx-sort-props
  163:9  error  Props should be sorted alphabetically    react/jsx-sort-props
  164:9  error  Props should be sorted alphabetically    react/jsx-sort-props
  165:9  error  Props should be sorted alphabetically    react/jsx-sort-props
  166:9  error  Props should be sorted alphabetically    react/jsx-sort-props
  167:9  error  Props should be sorted alphabetically    react/jsx-sort-props
  178:9  error  Props should be sorted alphabetically    react/jsx-sort-props
```

Ok. When I run the --fix flag, the JSX Tags in my file turn from this:

```jsx
<CreateNewJob
        closed={false}
        flagOptions={flagOptions}
        jobHeight={300}
        jobWidth={200}
        campaign='Some Campaign name'
        campaignStart={moment('2018-07-28 00:00:00')}
        campaignFinish={moment('2018-09-01 00:00:00')}
        jobNumber={'Job Number can be a String'}
        jobTemplateOptions={jobTemplateOptions}
        numberOfPages={30}
        onChange={onChange}
        onClose={onClose}
        spreadSheetTemplateOptions={spreadSheetTemplateOptions}
        stateMachineOptions={stateMachineOptions}
        workflowTemplateOptions={workflowTemplateOptions}
        workflowTemplateSteps={workflowTemplateSteps}
        description='Some description for this job'

        jobTemplate='1'
        stateMachine='1'
        flag='1'
        spreadSheetTemplate='1'
        workflowTemplate='1'
        validation={validation}
        onSubmit={onSubmit}
      />
```

To this:

```jsx
<CreateNewJob
        campaign='Some Campaign name'
        campaignFinish={moment('2018-09-01 00:00:00')}
        campaignStart={moment('2closed={false}0:00')}
 description='Some description for thisflag='1'ampaignStart={moment('2018-07-28 00:00:00')}
 flagOptions={flagOptions}0:00')}
        jobNumber={'JojobHeight={300}mplateOptions={jobTemplateOptions}jobNumber={'Job Number can be a String'}hange={ojobTemplate='1'nClose={onCljobTemplateOptions={jobTempljobWidth={200}s={30}
        stateMachineOpti
        stateMachineOptions={stateMachineOptions}
        workflowTemplateOptions={workflowTemplateOptions}
        workflowTemplateSteps={workflowTemplateSteps}
        description='Some description for this job'

        jobTemplate='1'
        stateMachine='1'
        flag='1'
        spreadSheetTemplate='1'
        workflowTemplate='1'
        validation={validation}
        onSubmit={onSubmit}
      />
```
Is there anything I could do to make it auto fix work? It would be really tedious to fix them all manually.

Any suggestion is appreciated.

Thank you.
react/jsx-sort-props breaks the code
**Tell us about your environment**

    "babel-eslint": "^9.0.0",
    "eslint": "5.6.0",
    "eslint-plugin-react": "^7.11.1"

* **ESLint Version:** 9.0.0
* **Node Version:** 10.6.0
* **npm Version:** -
* **yarn Version:** 1.9.4

**What parser (default, Babel-ESLint, etc.) are you using?**
Babel-ESLint

**Please show your full configuration:**
I created a repo to reproduce the bug: https://github.com/davesnx/eslint-bug-react-sort-props

<details>
<summary>Configuration</summary>

<!-- Paste your configuration below: -->
```js
module.exports = {
  parser: 'babel-eslint',
  plugins: ['react'],
  rules: {
    'react/jsx-sort-props': 1
  }
}

```

</details>

**What did you do? Please include the actual source code causing the issue, as well as the command that you used to run ESLint.**

<!-- Paste the source code below: -->
```js
import React, { Component } from 'react'
import PropTypes from 'prop-types'

const PictureChoice = () => {
  return (
    <List
      className={className}
      onStageAnswer={onStageAnswer}
      onCommitAnswer={onCommitAnswer}
      isFocused={isFocused}
      direction={direction}
      allowMultipleSelection={allowMultipleSelection}
      measureLongestChildNode={measureLongestChildNode}
      layoutItemsSize={layoutItemsSize}
      handleAppScroll={handleAppScroll}
      isActive={isActive}
      resetSelection={resetSelection}
      onKeyboardChoiceHovered={onKeyboardChoiceHovered}
      keyboardShortcutType
    />
  )
}

export default PictureChoice

```

<!-- Paste the command you used to run ESLint: -->
```bash
npx eslint . --fix
```

**What did you expect to happen?**
So theorically the rule should re-order my props, in the worst case scenario, not sort them. But actually is breaking them. It's a weird output:

```js
import React, { Component } from 'react'
import PropTypes from 'prop-types'

const PictureChoice = () => {
  return (
    <List
      allowMultipleSelection={allowMultipleSelection}
      className={className}
      direction={direction}
      isFocused=handleAppScroll={handleAppScroll}ection=isActive={isActive}owMultiplisFocused={isFocused}ardShortcutType
      layoutItemsSize={layoutItemsSl
      layoutItemsSize={layoutItemsSize}
      handleAppScroll={handleAppScroll}
      isActive={isActive}
      resetSelection={resetSelection}
      onKeyboardChoiceHovered={onKeyboardChoiceHovered}
      keyboardShortcutType
    />
  )
}

export default PictureChoice
```

It's actually trying to sort in a weird way, and it's not consistent.
Happens with a boolean props as well

```js

      isFocused=
      
      handleAppScroll={handleAppScroll}
      
      ection=
      
      isActive={isActive}
      
      owMultiplisFocused={isFocused}
      
      ardShortcutType
      layoutItemsSize={layoutItemsSl
      
```




Discussion:
That definitely sounds like a bug.

Does this only happen with babel-eslint?
I think this is a duplicate of #1922. This rule doesn’t make an attempt of handling multiline props properly :/
In that case we should entirely disable the autofixer, pending making it behave properly.
the same happens for me with `autofixer`



Patch:
diff --git a/lib/rules/jsx-sort-props.js b/lib/rules/jsx-sort-props.js
index d6e5a982ef..7528c1905c 100644
--- a/lib/rules/jsx-sort-props.js
+++ b/lib/rules/jsx-sort-props.js
@@ -107,7 +107,7 @@ const generateFixerFunction = (node, context, reservedList) => {
       });
     });
 
-    fixers.sort((a, b) => a.range[0] < b.range[0]);
+    fixers.sort((a, b) => b.range[0] - a.range[0]);
 
     const rangeStart = fixers[fixers.length - 1].range[0];
     const rangeEnd = fixers[0].range[1];


Test patch:
diff --git a/tests/lib/rules/jsx-sort-props.js b/tests/lib/rules/jsx-sort-props.js
index 2f32e6b2ac..082ef11f4e 100644
--- a/tests/lib/rules/jsx-sort-props.js
+++ b/tests/lib/rules/jsx-sort-props.js
@@ -238,6 +238,101 @@ ruleTester.run('jsx-sort-props', rule, {
     `,
       errors: 3
     },
+    {
+      code: '<App b={2} c={3} d={4} e={5} f={6} g={7} h={8} i={9} j={10} k={11} a={1} />',
+      output: '<App a={1} b={2} c={3} d={4} e={5} f={6} g={7} h={8} i={9} j={10} k={11} />',
+      errors: 1
+    },
+    {
+      code: `<List
+        className={className}
+        onStageAnswer={onStageAnswer}
+        onCommitAnswer={onCommitAnswer}
+        isFocused={isFocused}
+        direction={direction}
+        allowMultipleSelection={allowMultipleSelection}
+        measureLongestChildNode={measureLongestChildNode}
+        layoutItemsSize={layoutItemsSize}
+        handleAppScroll={handleAppScroll}
+        isActive={isActive}
+        resetSelection={resetSelection}
+        onKeyboardChoiceHovered={onKeyboardChoiceHovered}
+        keyboardShortcutType
+      />`,
+      output: `<List
+        allowMultipleSelection={allowMultipleSelection}
+        className={className}
+        direction={direction}
+        handleAppScroll={handleAppScroll}
+        isActive={isActive}
+        isFocused={isFocused}
+        keyboardShortcutType
+        layoutItemsSize={layoutItemsSize}
+        measureLongestChildNode={measureLongestChildNode}
+        onCommitAnswer={onCommitAnswer}
+        onKeyboardChoiceHovered={onKeyboardChoiceHovered}
+        onStageAnswer={onStageAnswer}
+        resetSelection={resetSelection}
+      />`,
+      errors: 10
+    },
+    {
+      code: `<CreateNewJob
+        closed={false}
+        flagOptions={flagOptions}
+        jobHeight={300}
+        jobWidth={200}
+        campaign='Some Campaign name'
+        campaignStart={moment('2018-07-28 00:00:00')}
+        campaignFinish={moment('2018-09-01 00:00:00')}
+        jobNumber={'Job Number can be a String'}
+        jobTemplateOptions={jobTemplateOptions}
+        numberOfPages={30}
+        onChange={onChange}
+        onClose={onClose}
+        spreadSheetTemplateOptions={spreadSheetTemplateOptions}
+        stateMachineOptions={stateMachineOptions}
+        workflowTemplateOptions={workflowTemplateOptions}
+        workflowTemplateSteps={workflowTemplateSteps}
+        description='Some description for this job'
+
+        jobTemplate='1'
+        stateMachine='1'
+        flag='1'
+        spreadSheetTemplate='1'
+        workflowTemplate='1'
+        validation={validation}
+        onSubmit={onSubmit}
+      />`,
+      output: `<CreateNewJob
+        campaign='Some Campaign name'
+        campaignFinish={moment('2018-09-01 00:00:00')}
+        campaignStart={moment('2018-07-28 00:00:00')}
+        closed={false}
+        description='Some description for this job'
+        flag='1'
+        flagOptions={flagOptions}
+        jobHeight={300}
+        jobNumber={'Job Number can be a String'}
+        jobTemplate='1'
+        jobTemplateOptions={jobTemplateOptions}
+        jobWidth={200}
+        numberOfPages={30}
+        onChange={onChange}
+        onClose={onClose}
+        onSubmit={onSubmit}
+        spreadSheetTemplate='1'
+
+        spreadSheetTemplateOptions={spreadSheetTemplateOptions}
+        stateMachine='1'
+        stateMachineOptions={stateMachineOptions}
+        validation={validation}
+        workflowTemplate='1'
+        workflowTemplateOptions={workflowTemplateOptions}
+        workflowTemplateSteps={workflowTemplateSteps}
+      />`,
+      errors: 13
+    },
     {
       code: '<App key="key" b c="c" />',
       errors: [expectedShorthandLastError],