'Prettier react/jsx-max-props-per-line format with VSCode

I use Prettier in JavaScript project with React. All my component props is formated in 1 line :

<Icon icon="arrow-left" width={15} height={18} />

And i would like this :

<Icon
  icon="arrow-left"
  width={15}
  height={18}
/>

I've add "react/jsx-max-props-per-line": [1, { "when": "multiline" }] to my .prettierrc, but no result.

I've an ESLint config too, with this rules :

{
  "extends": [
    "eslint:recommended",
    "plugin:react/recommended",
    "plugin:prettier/recommended"
  ],
  "plugins": ["react", "prettier", "standard"],
  "rules": {
    "indent": [2, 2, { "SwitchCase": 1 }],
    "quotes": [2, "single"],
    "linebreak-style": [2, "unix"],
    "semi": [2, "always"],
    "no-console": [0],
    "no-loop-func": [0],
    "new-cap": [0],
    "no-trailing-spaces": [0],
    "no-param-reassign": [0],
    "func-names": [0],
    "comma-dangle": [0],
    "no-unused-expressions": [0],
    "block-scoped-var": [0],
    "react/prop-types": [0],
    "prettier/prettier": "error"
  }
}

My .prettier file config :

  "bracketSpacing": true,
  "jsxBracketSameLine": true,
  "printWidth": 80,
  "singleQuote": true,
  "trailingComma": "all",
  "tabWidth": 2,
  "useTabs": false,
  "react/jsx-max-props-per-line": [1, { "when": "always" }]

Maybe a conflict ? I've try to move the react/jsx-max-props-per-line to ESLint rules, but no result too. No change.

Anyone can help me ?



Solution 1:[1]

I was able to get it to work with the following:

// .eslintrc.js
module.exports = {
  extends: [
    'react-app',
    'prettier',
    'plugin:prettier/recommended',
  ],
  plugins: ['prettier'],
  rules: {
    'react/jsx-first-prop-new-line': [2, 'multiline'],
    'react/jsx-max-props-per-line': [
      2,
      { maximum: 1, when: 'multiline' },
    ],
    'react/jsx-indent-props': [2, 2],
    'react/jsx-closing-bracket-location': [
      2,
      'tag-aligned',
    ],
  },
}

// .prettierrc
{
 "semi": false,
 "singleQuote": true,
 "printWidth":80 // default
}

Along with my dev dependencies which is essentially from eslint-config-react-app

"devDependencies": {
"@types/node": "^14.6.0",
"@types/react": "^16.9.46",
"@types/react-dom": "^16.9.8",
"@typescript-eslint/eslint-plugin": "^4.0.0",
"@typescript-eslint/parser": "^4.0.0",
"babel-eslint": "^10.0.0",
"eslint": "^7.5.0",
"eslint-config-prettier": "^7.2.0",
"eslint-config-react-app": "^6.0.0",
"eslint-plugin-flowtype": "^5.2.0",
"eslint-plugin-import": "^2.22.0",
"eslint-plugin-jest": "^24.0.0",
"eslint-plugin-jsx-a11y": "^6.3.1",
"eslint-plugin-prettier": "^3.3.1",
"eslint-plugin-react": "^7.20.3",
"eslint-plugin-react-hooks": "^4.0.8",
"eslint-plugin-testing-library": "^3.9.0",
"jest": "^26.6.3",
"prettier": "^2.2.1",
"typescript": "4.0.5"
},

Which formats the code ONLY if the line exceeds printWidth: 80 characters.

<InputField name="password" placeholder="password" label="Password" type="password" />
  
// transforms to this if line exceeds 'printWidth'

<InputField
  name="username"
  placeholder="username"
  label="Username"
  type="text" 
/>

Solution 2:[2]

module.exports = {
    'extends': [
        'eslint:recommended',

    ],
    'env': {
        'es6': true
    },
    'plugins': ['react'],
    'parser': 'babel-eslint',
    'rules': {

        // you rules....

        'react/jsx-first-prop-new-line': [1, 'multiline'],
        'react/jsx-max-props-per-line': [1,
            {
                'maximum': 1
            }
        ]
    },
};

yarn add --dev prettier-eslint-cli

VS code userConfig

"prettier.eslintIntegration": true,

Solution 3:[3]

First, you should only ESLint rules to your ESLint config, not your .prettierrc file.. they will be ignored since they're not valid Prettier configuration. Also, ESLint does not affect Prettier behavior. You can run Prettier via ESLint (as an auto-fixable rule via eslint-plugin-prettier) or run Prettier and run ESLint after, using prettier-eslint) which VSCode uses if you have prettier.eslintIntegration turned on.

Now you probably need to change the ESLint rule to use {"when": "always"} option. According to the docs, using "multiline" will only complain if your component is already multiline, but you have more than 1 prop per line:

<Icon 
  icon="arrow-left"
  widht={15} height={18}
/>

Using "always" will never allow more than 1 prop per line, even when the tag is not originally multiline.

Solution 4:[4]

The thing is that "react/jsx-max-props-per-line" is not a valid prettier rule, it's a rule of ESLint. I suggest keeping this rule in ESLint config file, but also set your editor to make all possible ESLint fixes on save.

You can turn on linting on save by following this tutorial. Or just put these:

  "editor.codeActionsOnSave": {
      "source.fixAll.eslint": true
  },
  "eslint.validate": ["javascript"]

lines in your user or local workspace settings.json object. This will solve your problem.

In my experience Prettier and ESLint auto-formatting can work well together.

Solution 5:[5]

If you are looking to only change line for props on save with Prettier in Vscode then there is an option to do that.

In settings.json add the following line

"prettier.printWidth": 100,

enter image description here

Before: enter image description here

After: enter image description here

Solution 6:[6]

Since Prettier 2.6.0 you can enforce single attribute per line in HTML or JSX if you add the following to your config:

"singleAttributePerLine": true

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 jinusean
Solution 2 joey
Solution 3
Solution 4
Solution 5 rahulxyz
Solution 6 Michal