Skip to content

Commit f2869fd

Browse files
justisbljharb
authored andcommitted
[New] jsx-props-no-multi-spaces: improve autofix for multi-line
1 parent dd2e968 commit f2869fd

File tree

3 files changed

+79
-10
lines changed

3 files changed

+79
-10
lines changed

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,13 @@ This change log adheres to standards from [Keep a CHANGELOG](https://keepachange
66

77
## Unreleased
88

9+
### Added
10+
* [`jsx-props-no-multi-spaces`]: improve autofix for multi-line ([#3930][] @justisb)
11+
912
### Fixed
1013
* [`no-unknown-property`]: allow `onLoad` on `body` ([#3923][] @DerekStapleton)
1114

15+
[#3930]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3930
1216
[#3923]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3923
1317

1418
## [7.37.5] - 2025.04.03

lib/rules/jsx-props-no-multi-spaces.js

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,22 @@ module.exports = {
8080
prop1: getPropName(prev),
8181
prop2: getPropName(node),
8282
},
83+
fix(fixer) {
84+
const comments = sourceCode.getCommentsBefore ? sourceCode.getCommentsBefore(node) : [];
85+
const nodes = [].concat(prev, comments, node);
86+
const fixes = [];
87+
88+
for (let i = 1; i < nodes.length; i += 1) {
89+
const prevNode = nodes[i - 1];
90+
const currNode = nodes[i];
91+
if (currNode.loc.start.line - prevNode.loc.end.line >= 2) {
92+
const indent = ' '.repeat(currNode.loc.start.column);
93+
fixes.push(fixer.replaceTextRange([prevNode.range[1], currNode.range[0]], `\n${indent}`));
94+
}
95+
}
96+
97+
return fixes;
98+
},
8399
});
84100
}
85101

tests/lib/rules/jsx-props-no-multi-spaces.js

Lines changed: 59 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -84,15 +84,15 @@ ruleTester.run('jsx-props-no-multi-spaces', rule, {
8484
{
8585
code: `
8686
<button
87-
title="Some button"
87+
title="Some button 8"
8888
type="button"
8989
/>
9090
`,
9191
},
9292
{
9393
code: `
9494
<button
95-
title="Some button"
95+
title="Some button 8"
9696
onClick={(value) => {
9797
console.log(value);
9898
}}
@@ -104,7 +104,7 @@ ruleTester.run('jsx-props-no-multi-spaces', rule, {
104104
{
105105
code: `
106106
<button
107-
title="Some button"
107+
title="Some button 2"
108108
// this is a comment
109109
onClick={(value) => {
110110
console.log(value);
@@ -116,7 +116,7 @@ ruleTester.run('jsx-props-no-multi-spaces', rule, {
116116
{
117117
code: `
118118
<button
119-
title="Some button"
119+
title="Some button 2"
120120
// this is a comment
121121
// this is a second comment
122122
onClick={(value) => {
@@ -129,7 +129,7 @@ ruleTester.run('jsx-props-no-multi-spaces', rule, {
129129
{
130130
code: `
131131
<App
132-
foo="Some button" // comment
132+
foo="Some button 3" // comment
133133
// comment
134134
bar=""
135135
/>
@@ -138,7 +138,7 @@ ruleTester.run('jsx-props-no-multi-spaces', rule, {
138138
{
139139
code: `
140140
<button
141-
title="Some button"
141+
title="Some button 3"
142142
/* this is a multiline comment
143143
...
144144
... */
@@ -263,6 +263,12 @@ ruleTester.run('jsx-props-no-multi-spaces', rule, {
263263
type="button"
264264
/>
265265
`,
266+
output: `
267+
<button
268+
title='Some button'${semver.satisfies(eslintPkg.version, '> 3') ? '' : '\n'}
269+
type="button"
270+
/>
271+
`,
266272
errors: [
267273
{
268274
messageId: 'noLineGap',
@@ -273,7 +279,7 @@ ruleTester.run('jsx-props-no-multi-spaces', rule, {
273279
{
274280
code: `
275281
<button
276-
title="Some button"
282+
title="Some button 4"
277283
278284
onClick={(value) => {
279285
console.log(value);
@@ -282,6 +288,15 @@ ruleTester.run('jsx-props-no-multi-spaces', rule, {
282288
type="button"
283289
/>
284290
`,
291+
output: `
292+
<button
293+
title="Some button 4"${semver.satisfies(eslintPkg.version, '> 3') ? '' : '\n'}
294+
onClick={(value) => {
295+
console.log(value);
296+
}}${semver.satisfies(eslintPkg.version, '> 3') ? '' : '\n'}
297+
type="button"
298+
/>
299+
`,
285300
errors: [
286301
{
287302
messageId: 'noLineGap',
@@ -297,7 +312,7 @@ ruleTester.run('jsx-props-no-multi-spaces', rule, {
297312
{
298313
code: `
299314
<button
300-
title="Some button"
315+
title="Some button 5"
301316
// this is a comment
302317
onClick={(value) => {
303318
console.log(value);
@@ -306,6 +321,16 @@ ruleTester.run('jsx-props-no-multi-spaces', rule, {
306321
type="button"
307322
/>
308323
`,
324+
output: `
325+
<button
326+
title="Some button 5"
327+
// this is a comment
328+
onClick={(value) => {
329+
console.log(value);
330+
}}
331+
type="button"
332+
/>
333+
`,
309334
errors: [
310335
{
311336
messageId: 'noLineGap',
@@ -316,7 +341,7 @@ ruleTester.run('jsx-props-no-multi-spaces', rule, {
316341
{
317342
code: `
318343
<button
319-
title="Some button"
344+
title="Some button 6"
320345
// this is a comment
321346
// second comment
322347
@@ -327,6 +352,17 @@ ruleTester.run('jsx-props-no-multi-spaces', rule, {
327352
type="button"
328353
/>
329354
`,
355+
output: `
356+
<button
357+
title="Some button 6"
358+
// this is a comment
359+
// second comment
360+
onClick={(value) => {
361+
console.log(value);
362+
}}
363+
type="button"
364+
/>
365+
`,
330366
errors: [
331367
{
332368
messageId: 'noLineGap',
@@ -341,7 +377,7 @@ ruleTester.run('jsx-props-no-multi-spaces', rule, {
341377
{
342378
code: `
343379
<button
344-
title="Some button"
380+
title="Some button 7"
345381
/*this is a
346382
multiline
347383
comment
@@ -354,6 +390,19 @@ ruleTester.run('jsx-props-no-multi-spaces', rule, {
354390
type="button"
355391
/>
356392
`,
393+
output: `
394+
<button
395+
title="Some button 7"
396+
/*this is a
397+
multiline
398+
comment
399+
*/
400+
onClick={(value) => {
401+
console.log(value);
402+
}}
403+
type="button"
404+
/>
405+
`,
357406
errors: [
358407
{
359408
messageId: 'noLineGap',

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy