eslint-plugin-code-style 1.0.10 → 1.0.16
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1046 -156
- package/index.js +344 -10
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
[](https://github.com/Mohamed-Elhawary/eslint-plugin-code-style/blob/main/LICENSE)
|
|
8
8
|
|
|
9
9
|
[](https://eslint.org/)
|
|
10
|
-
[](https://nodejs.org/)
|
|
11
11
|
[](https://react.dev/)
|
|
12
12
|
|
|
13
13
|
[](https://github.com/Mohamed-Elhawary/eslint-plugin-code-style/stargazers)
|
|
@@ -17,20 +17,69 @@
|
|
|
17
17
|
|
|
18
18
|
**A powerful ESLint plugin for enforcing consistent code formatting and style rules in React/JSX projects.**
|
|
19
19
|
|
|
20
|
-
*
|
|
20
|
+
*47 auto-fixable rules to keep your codebase clean and consistent*
|
|
21
|
+
|
|
22
|
+
</div>
|
|
23
|
+
|
|
24
|
+
<br />
|
|
25
|
+
|
|
26
|
+
## 🎯 Why This Plugin?
|
|
27
|
+
|
|
28
|
+
This plugin provides **rules that don't exist in ESLint's built-in rule set** and are **not available in popular third-party ESLint packages**. These are the style requirements that teams often check manually, making them easy to miss and hard to enforce consistently.
|
|
29
|
+
|
|
30
|
+
**Key Benefits:**
|
|
31
|
+
- **Fills the gaps** — Covers formatting rules that ESLint and other plugins miss
|
|
32
|
+
- **Works alongside existing tools** — Complements ESLint's built-in rules and packages like `eslint-plugin-react`, `eslint-plugin-import`, etc.
|
|
33
|
+
- **Consistency at scale** — Reduces code-style differences between team members by enforcing uniform formatting across your projects
|
|
34
|
+
- **Fully automated** — All 47 rules support auto-fix, eliminating manual style reviews
|
|
35
|
+
|
|
36
|
+
When combined with ESLint's native rules and other popular plugins, this package helps create a **complete code style solution** that keeps your codebase clean and consistent.
|
|
37
|
+
|
|
38
|
+
<div align="center">
|
|
21
39
|
|
|
22
40
|
<br />
|
|
23
41
|
|
|
24
42
|
[Installation](#-installation) •
|
|
25
43
|
[Quick Start](#-quick-start) •
|
|
44
|
+
[Recommended Configs](#-recommended-configurations) •
|
|
26
45
|
[Rules](#-rules-reference) •
|
|
27
|
-
[Examples](#-examples) •
|
|
28
46
|
[Contributing](#-contributing)
|
|
29
47
|
|
|
30
48
|
</div>
|
|
31
49
|
|
|
32
50
|
<br />
|
|
33
51
|
|
|
52
|
+
## 📁 Recommended Configurations
|
|
53
|
+
|
|
54
|
+
We provide **ready-to-use ESLint flat configuration files** that combine `eslint-plugin-code-style` with carefully selected third-party plugins and ESLint built-in rules. These configurations represent our battle-tested setup that reduces code-style differences by ~95%.
|
|
55
|
+
|
|
56
|
+
### 💡 Why Use These Configs?
|
|
57
|
+
|
|
58
|
+
- **Complete Coverage** — Combines ESLint built-in rules, third-party plugins, and all 47 code-style rules
|
|
59
|
+
- **Ready-to-Use** — Copy the config file and start linting immediately
|
|
60
|
+
- **Battle-Tested** — These configurations have been refined through real-world usage
|
|
61
|
+
- **Fully Documented** — Each config includes detailed instructions and explanations
|
|
62
|
+
|
|
63
|
+
### 📋 Available Configurations
|
|
64
|
+
|
|
65
|
+
| Configuration | Description | Link |
|
|
66
|
+
|---------------|-------------|------|
|
|
67
|
+
| **React** | React.js projects (JavaScript, JSX) | [View Config](./recommended-configs/react/) |
|
|
68
|
+
| **React + TS + Tailwind** | React + TypeScript + Tailwind CSS | *Coming Soon* |
|
|
69
|
+
| **Next.js + TS + Tailwind** | Next.js + TypeScript + Tailwind CSS | *Coming Soon* |
|
|
70
|
+
|
|
71
|
+
### ⚡ Quick Start with Recommended Config
|
|
72
|
+
|
|
73
|
+
1. Navigate to the [recommended-configs](./recommended-configs/) folder
|
|
74
|
+
2. Choose the configuration for your project type
|
|
75
|
+
3. Follow the installation instructions in the README
|
|
76
|
+
4. Copy the `eslint.config.js` to your project root
|
|
77
|
+
5. Run `eslint src/ --fix`
|
|
78
|
+
|
|
79
|
+
> **Note:** Each configuration includes a detailed README with installation commands, plugin explanations, and rule documentation.
|
|
80
|
+
|
|
81
|
+
<br />
|
|
82
|
+
|
|
34
83
|
---
|
|
35
84
|
|
|
36
85
|
<br />
|
|
@@ -41,13 +90,13 @@
|
|
|
41
90
|
<tr>
|
|
42
91
|
<td width="50%">
|
|
43
92
|
|
|
44
|
-
### Auto-Fixable Rules
|
|
45
|
-
All **
|
|
93
|
+
### 🔧 Auto-Fixable Rules
|
|
94
|
+
All **47 rules** support automatic fixing with `eslint --fix`. No manual code changes needed.
|
|
46
95
|
|
|
47
96
|
</td>
|
|
48
97
|
<td width="50%">
|
|
49
98
|
|
|
50
|
-
### React & JSX Support
|
|
99
|
+
### ⚛️ React & JSX Support
|
|
51
100
|
Built specifically for React projects with comprehensive JSX formatting rules.
|
|
52
101
|
|
|
53
102
|
</td>
|
|
@@ -55,13 +104,13 @@ Built specifically for React projects with comprehensive JSX formatting rules.
|
|
|
55
104
|
<tr>
|
|
56
105
|
<td width="50%">
|
|
57
106
|
|
|
58
|
-
### ESLint v9+ Ready
|
|
107
|
+
### ✅ ESLint v9+ Ready
|
|
59
108
|
Designed for ESLint's new flat config system. Modern and future-proof.
|
|
60
109
|
|
|
61
110
|
</td>
|
|
62
111
|
<td width="50%">
|
|
63
112
|
|
|
64
|
-
### Zero Dependencies
|
|
113
|
+
### 📭 Zero Dependencies
|
|
65
114
|
Lightweight plugin with no external dependencies. Fast and efficient.
|
|
66
115
|
|
|
67
116
|
</td>
|
|
@@ -83,12 +132,12 @@ pnpm add eslint-plugin-code-style -D
|
|
|
83
132
|
yarn add eslint-plugin-code-style -D
|
|
84
133
|
```
|
|
85
134
|
|
|
86
|
-
### Requirements
|
|
135
|
+
### 📋 Requirements
|
|
87
136
|
|
|
88
137
|
| Dependency | Version |
|
|
89
138
|
|------------|---------|
|
|
90
139
|
| **ESLint** | `>= 9.0.0` |
|
|
91
|
-
| **Node.js** | `>=
|
|
140
|
+
| **Node.js** | `>= 18.0.0` |
|
|
92
141
|
|
|
93
142
|
<br />
|
|
94
143
|
|
|
@@ -126,25 +175,28 @@ eslint src/ --fix
|
|
|
126
175
|
|
|
127
176
|
```javascript
|
|
128
177
|
rules: {
|
|
129
|
-
"code-style/absolute-imports-only": "error",
|
|
130
178
|
"code-style/array-items-per-line": "error",
|
|
131
179
|
"code-style/array-objects-on-new-lines": "error",
|
|
132
180
|
"code-style/arrow-function-block-body": "error",
|
|
133
181
|
"code-style/arrow-function-simple-jsx": "error",
|
|
134
182
|
"code-style/arrow-function-simplify": "error",
|
|
183
|
+
"code-style/curried-arrow-same-line": "error",
|
|
135
184
|
"code-style/assignment-value-same-line": "error",
|
|
136
185
|
"code-style/block-statement-newlines": "error",
|
|
137
186
|
"code-style/comment-spacing": "error",
|
|
138
|
-
"code-style/curried-arrow-same-line": "error",
|
|
139
|
-
"code-style/export-format": "error",
|
|
140
187
|
"code-style/function-call-spacing": "error",
|
|
141
188
|
"code-style/function-naming-convention": "error",
|
|
142
189
|
"code-style/function-params-per-line": "error",
|
|
143
190
|
"code-style/hook-callback-format": "error",
|
|
144
191
|
"code-style/hook-deps-per-line": "error",
|
|
145
192
|
"code-style/if-statement-format": "error",
|
|
193
|
+
"code-style/multiline-if-conditions": "error",
|
|
194
|
+
"code-style/absolute-imports-only": "error",
|
|
195
|
+
"code-style/export-format": "error",
|
|
146
196
|
"code-style/import-format": "error",
|
|
147
197
|
"code-style/import-source-spacing": "error",
|
|
198
|
+
"code-style/index-export-style": "error",
|
|
199
|
+
"code-style/module-index-exports": "error",
|
|
148
200
|
"code-style/jsx-children-on-new-line": "error",
|
|
149
201
|
"code-style/jsx-closing-bracket-spacing": "error",
|
|
150
202
|
"code-style/jsx-element-child-new-line": "error",
|
|
@@ -155,9 +207,7 @@ rules: {
|
|
|
155
207
|
"code-style/jsx-string-value-trim": "error",
|
|
156
208
|
"code-style/jsx-ternary-format": "error",
|
|
157
209
|
"code-style/member-expression-bracket-spacing": "error",
|
|
158
|
-
"code-style/module-index-exports": "error",
|
|
159
210
|
"code-style/multiline-argument-newline": "error",
|
|
160
|
-
"code-style/multiline-if-conditions": "error",
|
|
161
211
|
"code-style/multiple-arguments-per-line": "error",
|
|
162
212
|
"code-style/nested-call-closing-brackets": "error",
|
|
163
213
|
"code-style/no-empty-lines-in-function-calls": "error",
|
|
@@ -178,237 +228,1077 @@ rules: {
|
|
|
178
228
|
|
|
179
229
|
<br />
|
|
180
230
|
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
> All rules are **auto-fixable** using `eslint --fix`
|
|
231
|
+
---
|
|
184
232
|
|
|
185
|
-
|
|
233
|
+
## 📖 Rules Summary
|
|
186
234
|
|
|
187
|
-
|
|
235
|
+
> All **47 rules** are auto-fixable. See detailed examples for each rule in the [Rules Reference](#-rules-reference) section below.
|
|
236
|
+
>
|
|
237
|
+
> Rules marked with ⚙️ support customization options (e.g., extending default folder lists).
|
|
188
238
|
|
|
189
239
|
| Rule | Description |
|
|
190
240
|
|------|-------------|
|
|
191
|
-
| `
|
|
192
|
-
| `
|
|
241
|
+
| `array-items-per-line` | Enforce array formatting: 3 or less items on one line, more than 3 each on new line |
|
|
242
|
+
| `array-objects-on-new-lines` | Enforce array of objects to have each object on a new line |
|
|
243
|
+
| `arrow-function-block-body` | Enforce parentheses for arrow functions with multiline expressions |
|
|
244
|
+
| `arrow-function-simple-jsx` | Simplify arrow functions returning simple JSX to single line |
|
|
245
|
+
| `arrow-function-simplify` | Simplify arrow functions in JSX props with single statement block body |
|
|
246
|
+
| `curried-arrow-same-line` | Enforce curried arrow function to start on same line as `=>` |
|
|
247
|
+
| `assignment-value-same-line` | Enforce assignment value on same line as equals sign |
|
|
248
|
+
| `block-statement-newlines` | Enforce newlines after opening brace and before closing brace |
|
|
249
|
+
| `comment-spacing` | Enforce comment spacing and formatting |
|
|
250
|
+
| `function-call-spacing` | Enforce no space between function name and opening parenthesis |
|
|
251
|
+
| `function-naming-convention` | Enforce function naming conventions (camelCase, verb prefix) |
|
|
252
|
+
| `function-params-per-line` | Enforce function parameters on separate lines when multiline |
|
|
253
|
+
| `hook-callback-format` | Enforce consistent formatting for React hooks callbacks |
|
|
254
|
+
| `hook-deps-per-line` | Enforce each hook dependency on its own line when more than 2 |
|
|
255
|
+
| `if-statement-format` | Ensure if statement has proper formatting |
|
|
256
|
+
| `multiline-if-conditions` | Enforce multiline if conditions when there are multiple operands |
|
|
257
|
+
| `absolute-imports-only` | Enforce absolute imports using `@/` alias instead of relative paths ⚙️ |
|
|
258
|
+
| `export-format` | Format exports: collapse 1-3 specifiers, multiline for 4+ |
|
|
259
|
+
| `import-format` | Format imports: collapse 1-3 specifiers, multiline for 4+ |
|
|
193
260
|
| `import-source-spacing` | Enforce no extra spaces inside import path quotes |
|
|
194
|
-
| `export-
|
|
195
|
-
| `module-index-exports` | Enforce proper exports in index files |
|
|
261
|
+
| `index-export-style` | Enforce consistent export style in index files (shorthand or import-then-export) ⚙️ |
|
|
262
|
+
| `module-index-exports` | Enforce proper exports in index files ⚙️ |
|
|
263
|
+
| `jsx-children-on-new-line` | Enforce JSX children on separate lines from parent tags |
|
|
264
|
+
| `jsx-closing-bracket-spacing` | No space before `>` or `/>` in JSX tags |
|
|
265
|
+
| `jsx-element-child-new-line` | JSX element children must be on new lines |
|
|
266
|
+
| `jsx-logical-expression-simplify` | Simplify logical expressions in JSX |
|
|
267
|
+
| `jsx-parentheses-position` | Enforce opening parenthesis position for JSX in arrow functions |
|
|
268
|
+
| `jsx-prop-naming-convention` | Enforce JSX prop naming conventions (camelCase) |
|
|
269
|
+
| `jsx-simple-element-one-line` | Simple JSX elements with single child on one line |
|
|
270
|
+
| `jsx-string-value-trim` | Disallow leading/trailing whitespace in JSX string values |
|
|
271
|
+
| `jsx-ternary-format` | Enforce consistent formatting for JSX ternary expressions |
|
|
272
|
+
| `member-expression-bracket-spacing` | Enforce no spaces inside brackets for member expressions |
|
|
273
|
+
| `multiline-argument-newline` | Enforce newlines for function calls with multiline arguments |
|
|
274
|
+
| `multiple-arguments-per-line` | Enforce multiple arguments to each be on their own line |
|
|
275
|
+
| `nested-call-closing-brackets` | Enforce nested function call closing brackets on same line |
|
|
276
|
+
| `no-empty-lines-in-function-calls` | Disallow empty lines in function calls |
|
|
277
|
+
| `no-empty-lines-in-function-params` | Disallow empty lines in function parameters |
|
|
278
|
+
| `no-empty-lines-in-jsx` | Disallow empty lines inside JSX elements |
|
|
279
|
+
| `no-empty-lines-in-objects` | Disallow empty lines inside objects |
|
|
280
|
+
| `no-empty-lines-in-switch-cases` | Prevent empty lines at the beginning of switch case logic |
|
|
281
|
+
| `object-property-per-line` | Enforce each property on its own line when object has 2+ properties |
|
|
282
|
+
| `object-property-value-brace` | Enforce opening brace on same line as colon for object values |
|
|
283
|
+
| `object-property-value-format` | Enforce property value on same line as colon |
|
|
284
|
+
| `opening-brackets-same-line` | Enforce opening brackets on same line for function calls |
|
|
285
|
+
| `simple-call-single-line` | Simplify simple function calls with arrow function to single line |
|
|
286
|
+
| `single-argument-on-one-line` | Enforce single simple argument calls to be on one line |
|
|
287
|
+
| `string-property-spacing` | Enforce no extra spaces inside string property keys |
|
|
288
|
+
| `variable-naming-convention` | Enforce variable naming conventions (camelCase, UPPER_CASE, PascalCase) |
|
|
196
289
|
|
|
197
290
|
<br />
|
|
198
291
|
|
|
199
|
-
|
|
292
|
+
---
|
|
200
293
|
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
| `arrow-function-simplify` | Simplify arrow functions returning simple JSX to single line |
|
|
205
|
-
| `arrow-function-simple-jsx` | Simplify arrow functions in JSX props with single statement block body |
|
|
206
|
-
| `function-call-spacing` | Enforce no space between function name and opening parenthesis |
|
|
207
|
-
| `function-naming-convention` | Enforce function naming conventions (camelCase) |
|
|
208
|
-
| `function-params-per-line` | Enforce function parameters on separate lines when more than 2 |
|
|
209
|
-
| `curried-arrow-same-line` | Enforce curried arrow function to start on same line as `=>` |
|
|
294
|
+
## 📖 Rules Reference
|
|
295
|
+
|
|
296
|
+
> All rules are **auto-fixable** using `eslint --fix`
|
|
210
297
|
|
|
211
298
|
<br />
|
|
212
299
|
|
|
213
|
-
|
|
300
|
+
## 📚 Array Rules
|
|
214
301
|
|
|
215
|
-
|
|
216
|
-
|------|-------------|
|
|
217
|
-
| `object-property-per-line` | Enforce each property on its own line when object has 2+ properties |
|
|
218
|
-
| `object-property-value-format` | Enforce property value on same line as colon with proper spacing |
|
|
219
|
-
| `object-property-value-brace` | Enforce opening brace on same line as colon for object property values |
|
|
220
|
-
| `no-empty-lines-in-objects` | Disallow empty lines inside objects |
|
|
221
|
-
| `string-property-spacing` | Enforce no extra spaces inside string property keys |
|
|
302
|
+
### `array-items-per-line`
|
|
222
303
|
|
|
223
|
-
|
|
304
|
+
Enforce array formatting based on item count. 3 or less items on one line, more than 3 items each on its own line.
|
|
224
305
|
|
|
225
|
-
|
|
306
|
+
```javascript
|
|
307
|
+
// Good
|
|
308
|
+
const arr = [1, 2, 3];
|
|
309
|
+
const arr = [
|
|
310
|
+
item1,
|
|
311
|
+
item2,
|
|
312
|
+
item3,
|
|
313
|
+
item4,
|
|
314
|
+
];
|
|
226
315
|
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
316
|
+
// Bad
|
|
317
|
+
const arr = [1, 2, 3, 4, 5];
|
|
318
|
+
const arr = [item1,
|
|
319
|
+
item2, item3];
|
|
320
|
+
```
|
|
321
|
+
|
|
322
|
+
---
|
|
323
|
+
|
|
324
|
+
### `array-objects-on-new-lines`
|
|
325
|
+
|
|
326
|
+
In arrays of objects, each object should start on a new line for better readability.
|
|
327
|
+
|
|
328
|
+
```javascript
|
|
329
|
+
// Good
|
|
330
|
+
const items = [
|
|
331
|
+
{ id: 1, name: "first" },
|
|
332
|
+
{ id: 2, name: "second" },
|
|
333
|
+
];
|
|
334
|
+
|
|
335
|
+
// Bad
|
|
336
|
+
const items = [{ id: 1, name: "first" },
|
|
337
|
+
{ id: 2, name: "second" }];
|
|
338
|
+
```
|
|
231
339
|
|
|
232
340
|
<br />
|
|
233
341
|
|
|
234
|
-
|
|
342
|
+
## ➡️ Arrow Function Rules
|
|
235
343
|
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
344
|
+
### `arrow-function-block-body`
|
|
345
|
+
|
|
346
|
+
Arrow functions with complex logic should use block body. Ensures consistent formatting when function body needs multiple statements or complex expressions.
|
|
347
|
+
|
|
348
|
+
```javascript
|
|
349
|
+
// Good
|
|
350
|
+
() => {
|
|
351
|
+
doSomething();
|
|
352
|
+
return value;
|
|
353
|
+
}
|
|
354
|
+
|
|
355
|
+
// Bad
|
|
356
|
+
() => (doSomething(), value)
|
|
357
|
+
```
|
|
358
|
+
|
|
359
|
+
---
|
|
360
|
+
|
|
361
|
+
### `arrow-function-simple-jsx`
|
|
362
|
+
|
|
363
|
+
Simplify arrow functions returning simple JSX to single line by removing unnecessary parentheses and line breaks.
|
|
364
|
+
|
|
365
|
+
```javascript
|
|
366
|
+
// Good
|
|
367
|
+
export const X = ({ children }) => <Sidebar>{children}</Sidebar>;
|
|
368
|
+
|
|
369
|
+
// Bad
|
|
370
|
+
export const X = ({ children }) => (
|
|
371
|
+
<Sidebar>{children}</Sidebar>
|
|
372
|
+
);
|
|
373
|
+
```
|
|
374
|
+
|
|
375
|
+
---
|
|
376
|
+
|
|
377
|
+
### `arrow-function-simplify`
|
|
378
|
+
|
|
379
|
+
Simplify arrow functions that have a single return statement by using implicit return instead of block body.
|
|
380
|
+
|
|
381
|
+
```javascript
|
|
382
|
+
// Good
|
|
383
|
+
() => value
|
|
384
|
+
(x) => x * 2
|
|
385
|
+
items.map(item => item.name)
|
|
386
|
+
|
|
387
|
+
// Bad
|
|
388
|
+
() => { return value; }
|
|
389
|
+
(x) => { return x * 2; }
|
|
390
|
+
items.map(item => { return item.name; })
|
|
391
|
+
```
|
|
392
|
+
|
|
393
|
+
---
|
|
394
|
+
|
|
395
|
+
### `curried-arrow-same-line`
|
|
396
|
+
|
|
397
|
+
Curried arrow function body must start on the same line as the arrow (=>), not on a new line.
|
|
398
|
+
|
|
399
|
+
```javascript
|
|
400
|
+
// Good
|
|
401
|
+
const fn = () => async (dispatch) => {
|
|
402
|
+
dispatch(action);
|
|
403
|
+
};
|
|
404
|
+
|
|
405
|
+
// Bad
|
|
406
|
+
const fn = () =>
|
|
407
|
+
async (dispatch) => {
|
|
408
|
+
dispatch(action);
|
|
409
|
+
};
|
|
410
|
+
```
|
|
248
411
|
|
|
249
412
|
<br />
|
|
250
413
|
|
|
251
|
-
|
|
414
|
+
## 📐 Spacing & Formatting Rules
|
|
252
415
|
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
416
|
+
### `assignment-value-same-line`
|
|
417
|
+
|
|
418
|
+
The value in an assignment should start on the same line as the equals sign, not on a new line.
|
|
419
|
+
|
|
420
|
+
```javascript
|
|
421
|
+
// Good
|
|
422
|
+
const name = "John";
|
|
423
|
+
const data = {
|
|
424
|
+
key: "value",
|
|
425
|
+
};
|
|
426
|
+
|
|
427
|
+
// Bad
|
|
428
|
+
const name =
|
|
429
|
+
"John";
|
|
430
|
+
const data =
|
|
431
|
+
{
|
|
432
|
+
key: "value",
|
|
433
|
+
};
|
|
434
|
+
```
|
|
435
|
+
|
|
436
|
+
---
|
|
437
|
+
|
|
438
|
+
### `block-statement-newlines`
|
|
439
|
+
|
|
440
|
+
Block statements should have proper newlines after the opening brace and before the closing brace.
|
|
441
|
+
|
|
442
|
+
```javascript
|
|
443
|
+
// Good
|
|
444
|
+
if (condition) {
|
|
445
|
+
doSomething();
|
|
446
|
+
}
|
|
447
|
+
|
|
448
|
+
// Bad
|
|
449
|
+
if (condition) { doSomething(); }
|
|
450
|
+
if (condition) {doSomething();}
|
|
451
|
+
```
|
|
452
|
+
|
|
453
|
+
---
|
|
454
|
+
|
|
455
|
+
### `comment-spacing`
|
|
456
|
+
|
|
457
|
+
Comments should have proper spacing: a space after the opening delimiter (// or block comment opener), and proper blank lines around comment blocks.
|
|
458
|
+
|
|
459
|
+
```javascript
|
|
460
|
+
// Good
|
|
461
|
+
// This is a comment
|
|
462
|
+
/* This is a block comment */
|
|
463
|
+
|
|
464
|
+
// Bad
|
|
465
|
+
//This is a comment (missing space)
|
|
466
|
+
/*No space after opener*/
|
|
467
|
+
```
|
|
468
|
+
|
|
469
|
+
---
|
|
470
|
+
|
|
471
|
+
### `member-expression-bracket-spacing`
|
|
472
|
+
|
|
473
|
+
No spaces inside brackets in computed member expressions. The property name should touch both brackets.
|
|
474
|
+
|
|
475
|
+
```javascript
|
|
476
|
+
// Good
|
|
477
|
+
arr[value]
|
|
478
|
+
obj[key]
|
|
479
|
+
|
|
480
|
+
// Bad
|
|
481
|
+
arr[ value ]
|
|
482
|
+
obj[ key ]
|
|
483
|
+
```
|
|
484
|
+
|
|
485
|
+
---
|
|
486
|
+
|
|
487
|
+
### `no-empty-lines-in-function-params`
|
|
488
|
+
|
|
489
|
+
Function parameter lists should not contain empty lines between parameters or after opening/before closing parens.
|
|
490
|
+
|
|
491
|
+
```javascript
|
|
492
|
+
// Good
|
|
493
|
+
function test(
|
|
494
|
+
param1,
|
|
495
|
+
param2,
|
|
496
|
+
) {}
|
|
497
|
+
|
|
498
|
+
// Bad
|
|
499
|
+
function test(
|
|
500
|
+
param1,
|
|
501
|
+
|
|
502
|
+
param2,
|
|
503
|
+
) {}
|
|
504
|
+
```
|
|
505
|
+
|
|
506
|
+
---
|
|
507
|
+
|
|
508
|
+
### `variable-naming-convention`
|
|
509
|
+
|
|
510
|
+
Variable names should follow naming conventions: camelCase for regular variables, UPPER_CASE for constants, and PascalCase for React components.
|
|
511
|
+
|
|
512
|
+
```javascript
|
|
513
|
+
// Good
|
|
514
|
+
const userName = "John";
|
|
515
|
+
const MAX_RETRIES = 3;
|
|
516
|
+
const UserProfile = () => <div />;
|
|
517
|
+
const useCustomHook = () => {};
|
|
518
|
+
|
|
519
|
+
// Bad
|
|
520
|
+
const user_name = "John";
|
|
521
|
+
const maxretries = 3;
|
|
522
|
+
const userProfile = () => <div />;
|
|
523
|
+
```
|
|
262
524
|
|
|
263
525
|
<br />
|
|
264
526
|
|
|
265
|
-
|
|
527
|
+
## ⚡ Function Rules
|
|
266
528
|
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
529
|
+
### `function-call-spacing`
|
|
530
|
+
|
|
531
|
+
No space between function name and opening parenthesis.
|
|
532
|
+
|
|
533
|
+
```javascript
|
|
534
|
+
// Good
|
|
535
|
+
useDispatch()
|
|
536
|
+
myFunction(arg)
|
|
537
|
+
|
|
538
|
+
// Bad
|
|
539
|
+
useDispatch ()
|
|
540
|
+
myFunction (arg)
|
|
541
|
+
```
|
|
542
|
+
|
|
543
|
+
---
|
|
544
|
+
|
|
545
|
+
### `function-naming-convention`
|
|
546
|
+
|
|
547
|
+
Function names should follow naming conventions: camelCase, starting with a verb, and handlers ending with "Handler".
|
|
548
|
+
|
|
549
|
+
```javascript
|
|
550
|
+
// Good
|
|
551
|
+
function getUserData() {}
|
|
552
|
+
function handleClick() {}
|
|
553
|
+
function isValidEmail() {}
|
|
554
|
+
const submitHandler = () => {}
|
|
555
|
+
|
|
556
|
+
// Bad
|
|
557
|
+
function GetUserData() {}
|
|
558
|
+
function user_data() {}
|
|
559
|
+
function click() {}
|
|
560
|
+
```
|
|
561
|
+
|
|
562
|
+
---
|
|
563
|
+
|
|
564
|
+
### `function-params-per-line`
|
|
565
|
+
|
|
566
|
+
When function parameters span multiple lines, each parameter should be on its own line with consistent indentation.
|
|
567
|
+
|
|
568
|
+
```javascript
|
|
569
|
+
// Good
|
|
570
|
+
function test(
|
|
571
|
+
param1,
|
|
572
|
+
param2,
|
|
573
|
+
param3,
|
|
574
|
+
) {}
|
|
575
|
+
|
|
576
|
+
// Bad
|
|
577
|
+
function test(param1,
|
|
578
|
+
param2, param3) {}
|
|
579
|
+
```
|
|
271
580
|
|
|
272
581
|
<br />
|
|
273
582
|
|
|
274
|
-
|
|
583
|
+
## 🪝 React Hooks Rules
|
|
275
584
|
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
585
|
+
### `hook-callback-format`
|
|
586
|
+
|
|
587
|
+
Enforce consistent formatting for React hooks like useEffect, useCallback, useMemo with callback and dependency array.
|
|
588
|
+
|
|
589
|
+
```javascript
|
|
590
|
+
// Good
|
|
591
|
+
useEffect(
|
|
592
|
+
() => { doSomething(); },
|
|
593
|
+
[dep1, dep2],
|
|
594
|
+
);
|
|
595
|
+
|
|
596
|
+
// Bad
|
|
597
|
+
useEffect(() => { doSomething(); }, [dep1, dep2]);
|
|
598
|
+
```
|
|
599
|
+
|
|
600
|
+
---
|
|
601
|
+
|
|
602
|
+
### `hook-deps-per-line`
|
|
603
|
+
|
|
604
|
+
React hook dependency arrays with more than 2 dependencies should have each dependency on its own line.
|
|
605
|
+
|
|
606
|
+
```javascript
|
|
607
|
+
// Good
|
|
608
|
+
useEffect(() => {}, [dep1, dep2])
|
|
609
|
+
useEffect(() => {}, [
|
|
610
|
+
dep1,
|
|
611
|
+
dep2,
|
|
612
|
+
dep3,
|
|
613
|
+
])
|
|
614
|
+
|
|
615
|
+
// Bad
|
|
616
|
+
useEffect(() => {}, [dep1, dep2, dep3, dep4])
|
|
617
|
+
```
|
|
281
618
|
|
|
282
619
|
<br />
|
|
283
620
|
|
|
284
|
-
|
|
621
|
+
## 🔀 Control Flow Rules
|
|
285
622
|
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
623
|
+
### `if-statement-format`
|
|
624
|
+
|
|
625
|
+
If statements should have consistent formatting with the opening brace on the same line as the condition and else on the same line as the closing brace.
|
|
626
|
+
|
|
627
|
+
```javascript
|
|
628
|
+
// Good
|
|
629
|
+
if (condition) {
|
|
630
|
+
doSomething();
|
|
631
|
+
} else {
|
|
632
|
+
doOther();
|
|
633
|
+
}
|
|
634
|
+
|
|
635
|
+
// Bad
|
|
636
|
+
if (condition)
|
|
637
|
+
{
|
|
638
|
+
doSomething();
|
|
639
|
+
}
|
|
640
|
+
else
|
|
641
|
+
{
|
|
642
|
+
doOther();
|
|
643
|
+
}
|
|
644
|
+
```
|
|
645
|
+
|
|
646
|
+
---
|
|
647
|
+
|
|
648
|
+
### `multiline-if-conditions`
|
|
649
|
+
|
|
650
|
+
When an if statement has multiple conditions that span multiple lines, each condition should be on its own line.
|
|
651
|
+
|
|
652
|
+
```javascript
|
|
653
|
+
// Good
|
|
654
|
+
if (
|
|
655
|
+
conditionA &&
|
|
656
|
+
conditionB &&
|
|
657
|
+
conditionC
|
|
658
|
+
) {}
|
|
659
|
+
|
|
660
|
+
// Bad
|
|
661
|
+
if (conditionA &&
|
|
662
|
+
conditionB && conditionC) {}
|
|
663
|
+
```
|
|
664
|
+
|
|
665
|
+
---
|
|
666
|
+
|
|
667
|
+
### `no-empty-lines-in-switch-cases`
|
|
668
|
+
|
|
669
|
+
Switch case blocks should not have empty lines at the beginning of the case logic or between consecutive cases.
|
|
670
|
+
|
|
671
|
+
```javascript
|
|
672
|
+
// Good
|
|
673
|
+
switch (value) {
|
|
674
|
+
case 1:
|
|
675
|
+
return "one";
|
|
676
|
+
case 2:
|
|
677
|
+
return "two";
|
|
678
|
+
}
|
|
679
|
+
|
|
680
|
+
// Bad
|
|
681
|
+
switch (value) {
|
|
682
|
+
case 1:
|
|
683
|
+
|
|
684
|
+
return "one";
|
|
685
|
+
|
|
686
|
+
case 2:
|
|
687
|
+
return "two";
|
|
688
|
+
}
|
|
689
|
+
```
|
|
294
690
|
|
|
295
691
|
<br />
|
|
296
692
|
|
|
297
|
-
##
|
|
693
|
+
## 📥 Import/Export Rules
|
|
298
694
|
|
|
299
|
-
###
|
|
695
|
+
### `absolute-imports-only`
|
|
696
|
+
|
|
697
|
+
Enforce absolute imports from index files only for local paths. Local paths (starting with @/) should only import from folder-level index files.
|
|
300
698
|
|
|
301
699
|
```javascript
|
|
302
|
-
//
|
|
303
|
-
import {
|
|
700
|
+
// Good
|
|
701
|
+
import { Button } from "@/components";
|
|
702
|
+
import { useAuth } from "@/hooks";
|
|
703
|
+
|
|
704
|
+
// Bad
|
|
705
|
+
import { Button } from "@/components/buttons/primary-button";
|
|
706
|
+
import { useAuth } from "@/hooks/auth/useAuth";
|
|
707
|
+
```
|
|
708
|
+
|
|
709
|
+
**Default Allowed Folders:**
|
|
710
|
+
`actions`, `apis`, `assets`, `atoms`, `components`, `constants`, `contexts`, `data`, `hooks`, `layouts`, `middlewares`, `providers`, `reducers`, `redux`, `requests`, `routes`, `schemas`, `services`, `store`, `styles`, `theme`, `thunks`, `types`, `utils`, `views`
|
|
711
|
+
|
|
712
|
+
**Customization Options:**
|
|
713
|
+
|
|
714
|
+
| Option | Type | Description |
|
|
715
|
+
|--------|------|-------------|
|
|
716
|
+
| `extraAllowedFolders` | `string[]` | Add extra folders to the default list |
|
|
717
|
+
| `extraReduxSubfolders` | `string[]` | Add extra redux subfolders (default: `actions`, `reducers`, `store`, `thunks`, `types`) |
|
|
718
|
+
| `extraDeepImportFolders` | `string[]` | Add extra folders that allow deep imports (default: `assets`) |
|
|
719
|
+
| `aliasPrefix` | `string` | Change the import alias prefix (default: `@/`) |
|
|
720
|
+
| `allowedFolders` | `string[]` | Replace default folders entirely |
|
|
721
|
+
| `reduxSubfolders` | `string[]` | Replace default redux subfolders entirely |
|
|
722
|
+
| `deepImportFolders` | `string[]` | Replace default deep import folders entirely |
|
|
304
723
|
|
|
305
|
-
|
|
724
|
+
```javascript
|
|
725
|
+
// Example: Add custom folders to the defaults
|
|
726
|
+
"code-style/absolute-imports-only": ["error", {
|
|
727
|
+
extraAllowedFolders: ["features", "modules", "lib"],
|
|
728
|
+
extraDeepImportFolders: ["images", "fonts"]
|
|
729
|
+
}]
|
|
730
|
+
```
|
|
731
|
+
|
|
732
|
+
---
|
|
733
|
+
|
|
734
|
+
### `export-format`
|
|
735
|
+
|
|
736
|
+
Export statements should have consistent formatting with proper spacing. Collapse 1-3 specifiers on one line, use multiline for 4+ specifiers.
|
|
737
|
+
|
|
738
|
+
```javascript
|
|
739
|
+
// Good
|
|
740
|
+
export { a, b, c };
|
|
741
|
+
export {
|
|
742
|
+
a,
|
|
743
|
+
b,
|
|
744
|
+
c,
|
|
745
|
+
d,
|
|
746
|
+
};
|
|
747
|
+
|
|
748
|
+
// Bad
|
|
749
|
+
export {a,b,c};
|
|
750
|
+
export { a, b, c, d, e };
|
|
751
|
+
```
|
|
752
|
+
|
|
753
|
+
---
|
|
754
|
+
|
|
755
|
+
### `import-format`
|
|
756
|
+
|
|
757
|
+
Import statements should have consistent formatting with proper spacing. Collapse 1-3 specifiers on one line, use multiline for 4+ specifiers.
|
|
758
|
+
|
|
759
|
+
```javascript
|
|
760
|
+
// Good
|
|
761
|
+
import { a, b, c } from "module";
|
|
306
762
|
import {
|
|
307
|
-
|
|
763
|
+
a,
|
|
764
|
+
b,
|
|
765
|
+
c,
|
|
766
|
+
d,
|
|
767
|
+
} from "module";
|
|
768
|
+
|
|
769
|
+
// Bad
|
|
770
|
+
import {a,b,c} from "module";
|
|
771
|
+
import { a, b, c, d, e } from "module";
|
|
772
|
+
```
|
|
773
|
+
|
|
774
|
+
---
|
|
775
|
+
|
|
776
|
+
### `import-source-spacing`
|
|
777
|
+
|
|
778
|
+
No spaces inside import path quotes. The module path should not have leading or trailing whitespace.
|
|
779
|
+
|
|
780
|
+
```javascript
|
|
781
|
+
// Good
|
|
782
|
+
import { Button } from "@mui/material";
|
|
783
|
+
|
|
784
|
+
// Bad
|
|
785
|
+
import { Button } from " @mui/material ";
|
|
786
|
+
```
|
|
787
|
+
|
|
788
|
+
---
|
|
789
|
+
|
|
790
|
+
### `index-export-style`
|
|
791
|
+
|
|
792
|
+
Enforce consistent export style in index files. Choose between shorthand re-exports or import-then-export pattern.
|
|
793
|
+
|
|
794
|
+
**Style: "shorthand" (default)**
|
|
795
|
+
```javascript
|
|
796
|
+
// Good - shorthand re-exports
|
|
797
|
+
export { Button } from "./button";
|
|
798
|
+
export { Input, Select } from "./form";
|
|
799
|
+
export { StyledCard, StyledCardWithActions } from "./card";
|
|
800
|
+
```
|
|
801
|
+
|
|
802
|
+
**Style: "import-export"**
|
|
803
|
+
```javascript
|
|
804
|
+
// Good - import then export
|
|
805
|
+
import { Button } from "./button";
|
|
806
|
+
import { Input, Select } from "./form";
|
|
807
|
+
import { StyledCard, StyledCardWithActions } from "./card";
|
|
808
|
+
|
|
809
|
+
export {
|
|
308
810
|
Button,
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
811
|
+
Input,
|
|
812
|
+
Select,
|
|
813
|
+
StyledCard,
|
|
814
|
+
StyledCardWithActions,
|
|
815
|
+
};
|
|
816
|
+
```
|
|
312
817
|
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
818
|
+
**Bad - mixing styles**
|
|
819
|
+
```javascript
|
|
820
|
+
// Bad - don't mix shorthand with import-then-export
|
|
821
|
+
export { Button } from "./button";
|
|
822
|
+
import { Input } from "./input";
|
|
823
|
+
export { Input };
|
|
316
824
|
```
|
|
317
825
|
|
|
318
|
-
|
|
826
|
+
**Customization Options:**
|
|
319
827
|
|
|
320
|
-
|
|
828
|
+
| Option | Type | Default | Description |
|
|
829
|
+
|--------|------|---------|-------------|
|
|
830
|
+
| `style` | `"shorthand"` \| `"import-export"` | `"shorthand"` | The export style to enforce |
|
|
321
831
|
|
|
322
832
|
```javascript
|
|
323
|
-
//
|
|
324
|
-
|
|
833
|
+
// Example: Use shorthand style (default)
|
|
834
|
+
"code-style/index-export-style": "error"
|
|
325
835
|
|
|
326
|
-
//
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
836
|
+
// Example: Use import-then-export style
|
|
837
|
+
"code-style/index-export-style": ["error", { style: "import-export" }]
|
|
838
|
+
```
|
|
839
|
+
|
|
840
|
+
---
|
|
841
|
+
|
|
842
|
+
### `module-index-exports`
|
|
843
|
+
|
|
844
|
+
Ensure module folders have index files that export all contents. Each module folder must have an index file that exports all subfolders and files in the module.
|
|
845
|
+
|
|
846
|
+
```javascript
|
|
847
|
+
// Good
|
|
848
|
+
// index.js
|
|
849
|
+
export { Button } from "./Button";
|
|
850
|
+
export { Input } from "./Input";
|
|
851
|
+
|
|
852
|
+
// Bad
|
|
853
|
+
// Missing exports in index.js
|
|
854
|
+
```
|
|
855
|
+
|
|
856
|
+
**Default Module Folders:**
|
|
857
|
+
`apis`, `assets`, `atoms`, `components`, `constants`, `contexts`, `data`, `hooks`, `layouts`, `middlewares`, `providers`, `redux`, `requests`, `routes`, `schemas`, `services`, `styles`, `theme`, `utils`, `views`
|
|
332
858
|
|
|
333
|
-
|
|
334
|
-
|
|
859
|
+
**Customization Options:**
|
|
860
|
+
|
|
861
|
+
| Option | Type | Description |
|
|
862
|
+
|--------|------|-------------|
|
|
863
|
+
| `extraModuleFolders` | `string[]` | Add extra module folders to the default list |
|
|
864
|
+
| `extraLazyLoadFolders` | `string[]` | Add extra lazy load folders (default: `views`) |
|
|
865
|
+
| `extraIgnorePatterns` | `string[]` | Add extra ignore patterns (supports wildcards like `*.stories.js`) |
|
|
866
|
+
| `moduleFolders` | `string[]` | Replace default module folders entirely |
|
|
867
|
+
| `lazyLoadFolders` | `string[]` | Replace default lazy load folders entirely |
|
|
868
|
+
| `ignorePatterns` | `string[]` | Replace default ignore patterns entirely |
|
|
869
|
+
|
|
870
|
+
**Default Ignore Patterns:**
|
|
871
|
+
`index.js`, `index.jsx`, `index.ts`, `index.tsx`, `.DS_Store`, `__tests__`, `__mocks__`, `*.test.js`, `*.test.jsx`, `*.spec.js`, `*.spec.jsx`
|
|
872
|
+
|
|
873
|
+
```javascript
|
|
874
|
+
// Example: Add custom folders and patterns to the defaults
|
|
875
|
+
"code-style/module-index-exports": ["error", {
|
|
876
|
+
extraModuleFolders: ["features", "modules", "lib"],
|
|
877
|
+
extraLazyLoadFolders: ["pages"],
|
|
878
|
+
extraIgnorePatterns: ["*.stories.js", "*.mock.js"]
|
|
879
|
+
}]
|
|
335
880
|
```
|
|
336
881
|
|
|
337
882
|
<br />
|
|
338
883
|
|
|
339
|
-
|
|
884
|
+
## ⚛️ JSX Rules
|
|
885
|
+
|
|
886
|
+
### `jsx-children-on-new-line`
|
|
887
|
+
|
|
888
|
+
When a JSX element has multiple children, each child should be on its own line with proper indentation.
|
|
340
889
|
|
|
341
890
|
```javascript
|
|
342
|
-
//
|
|
343
|
-
|
|
891
|
+
// Good
|
|
892
|
+
<Container>
|
|
893
|
+
<Header />
|
|
894
|
+
<Content />
|
|
895
|
+
<Footer />
|
|
896
|
+
</Container>
|
|
897
|
+
|
|
898
|
+
// Bad
|
|
899
|
+
<Container><Header /><Content />
|
|
900
|
+
<Footer /></Container>
|
|
901
|
+
```
|
|
902
|
+
|
|
903
|
+
---
|
|
904
|
+
|
|
905
|
+
### `jsx-closing-bracket-spacing`
|
|
906
|
+
|
|
907
|
+
No space before > or /> in JSX tags. The closing bracket should be directly after the last attribute or tag name.
|
|
344
908
|
|
|
345
|
-
|
|
346
|
-
|
|
909
|
+
```javascript
|
|
910
|
+
// Good
|
|
911
|
+
<Button />
|
|
912
|
+
<Button className="primary">
|
|
913
|
+
|
|
914
|
+
// Bad
|
|
915
|
+
<Button / >
|
|
916
|
+
<Button className="primary" >
|
|
917
|
+
```
|
|
918
|
+
|
|
919
|
+
---
|
|
920
|
+
|
|
921
|
+
### `jsx-element-child-new-line`
|
|
922
|
+
|
|
923
|
+
JSX element children (nested JSX elements) must be on their own line, not on the same line as the opening tag.
|
|
924
|
+
|
|
925
|
+
```javascript
|
|
926
|
+
// Good
|
|
927
|
+
<Button>
|
|
928
|
+
<Icon />
|
|
929
|
+
</Button>
|
|
930
|
+
|
|
931
|
+
// Bad
|
|
932
|
+
<Button><Icon /></Button>
|
|
933
|
+
```
|
|
934
|
+
|
|
935
|
+
---
|
|
936
|
+
|
|
937
|
+
### `jsx-logical-expression-simplify`
|
|
938
|
+
|
|
939
|
+
Simplify JSX logical expressions by removing unnecessary parentheses around conditions and JSX elements.
|
|
940
|
+
|
|
941
|
+
```javascript
|
|
942
|
+
// Good
|
|
943
|
+
{condition && <Component />}
|
|
944
|
+
{isVisible && <Modal />}
|
|
945
|
+
|
|
946
|
+
// Bad
|
|
947
|
+
{(condition) && (<Component />)}
|
|
948
|
+
{(isVisible) && (<Modal />)}
|
|
949
|
+
```
|
|
950
|
+
|
|
951
|
+
---
|
|
952
|
+
|
|
953
|
+
### `jsx-parentheses-position`
|
|
954
|
+
|
|
955
|
+
JSX return parentheses should be on the same line as the arrow or return keyword, not on a new line.
|
|
956
|
+
|
|
957
|
+
```javascript
|
|
958
|
+
// Good
|
|
959
|
+
const Component = () => (
|
|
960
|
+
<div>content</div>
|
|
961
|
+
);
|
|
962
|
+
return (
|
|
963
|
+
<div>content</div>
|
|
964
|
+
);
|
|
965
|
+
|
|
966
|
+
// Bad
|
|
967
|
+
const Component = () =>
|
|
968
|
+
(
|
|
969
|
+
<div>content</div>
|
|
970
|
+
);
|
|
971
|
+
return
|
|
972
|
+
(
|
|
973
|
+
<div>content</div>
|
|
974
|
+
);
|
|
975
|
+
```
|
|
976
|
+
|
|
977
|
+
---
|
|
978
|
+
|
|
979
|
+
### `jsx-prop-naming-convention`
|
|
980
|
+
|
|
981
|
+
Enforce camelCase naming for JSX props. Allows PascalCase for component reference props, and kebab-case for data-* and aria-*.
|
|
982
|
+
|
|
983
|
+
```javascript
|
|
984
|
+
// Good
|
|
985
|
+
<Button onClick={handler} />
|
|
986
|
+
<Input data-testid="input" />
|
|
987
|
+
<Modal ContentComponent={Panel} />
|
|
988
|
+
|
|
989
|
+
// Bad
|
|
990
|
+
<Button on_click={handler} />
|
|
991
|
+
<Input test_id="input" />
|
|
992
|
+
```
|
|
993
|
+
|
|
994
|
+
---
|
|
995
|
+
|
|
996
|
+
### `jsx-simple-element-one-line`
|
|
997
|
+
|
|
998
|
+
Simple JSX elements with only a single text or expression child should be collapsed onto a single line.
|
|
999
|
+
|
|
1000
|
+
```javascript
|
|
1001
|
+
// Good
|
|
1002
|
+
<Button>{buttonLinkText}</Button>
|
|
1003
|
+
<Title>Hello</Title>
|
|
1004
|
+
|
|
1005
|
+
// Bad
|
|
1006
|
+
<Button>
|
|
1007
|
+
{buttonLinkText}
|
|
1008
|
+
</Button>
|
|
1009
|
+
```
|
|
1010
|
+
|
|
1011
|
+
---
|
|
1012
|
+
|
|
1013
|
+
### `jsx-string-value-trim`
|
|
1014
|
+
|
|
1015
|
+
JSX string attribute values should not have leading or trailing whitespace inside the quotes.
|
|
1016
|
+
|
|
1017
|
+
```javascript
|
|
1018
|
+
// Good
|
|
1019
|
+
className="button"
|
|
1020
|
+
title="Hello World"
|
|
1021
|
+
|
|
1022
|
+
// Bad
|
|
1023
|
+
className=" button "
|
|
1024
|
+
title=" Hello World "
|
|
1025
|
+
```
|
|
1026
|
+
|
|
1027
|
+
---
|
|
1028
|
+
|
|
1029
|
+
### `jsx-ternary-format`
|
|
1030
|
+
|
|
1031
|
+
Format ternary expressions in JSX with proper structure. Simple branches stay on one line, complex branches get parentheses with proper indentation.
|
|
1032
|
+
|
|
1033
|
+
```javascript
|
|
1034
|
+
// Good
|
|
1035
|
+
{condition ? <Simple /> : <Other />}
|
|
1036
|
+
{condition ? <Simple /> : (
|
|
347
1037
|
<Complex>
|
|
348
|
-
<
|
|
1038
|
+
<Child />
|
|
349
1039
|
</Complex>
|
|
350
|
-
) : (
|
|
351
|
-
<Alternative>
|
|
352
|
-
<Content />
|
|
353
|
-
</Alternative>
|
|
354
1040
|
)}
|
|
355
1041
|
|
|
356
|
-
//
|
|
357
|
-
{condition
|
|
1042
|
+
// Bad
|
|
1043
|
+
{condition
|
|
1044
|
+
? <Simple />
|
|
1045
|
+
: <Other />}
|
|
1046
|
+
```
|
|
358
1047
|
|
|
359
|
-
|
|
1048
|
+
---
|
|
360
1049
|
|
|
361
|
-
|
|
1050
|
+
### `no-empty-lines-in-jsx`
|
|
362
1051
|
|
|
363
|
-
|
|
1052
|
+
JSX elements should not contain empty lines between children or after opening/before closing tags.
|
|
364
1053
|
|
|
365
|
-
|
|
1054
|
+
```javascript
|
|
1055
|
+
// Good
|
|
1056
|
+
<div>
|
|
1057
|
+
<span>text</span>
|
|
1058
|
+
<span>more</span>
|
|
1059
|
+
</div>
|
|
1060
|
+
|
|
1061
|
+
// Bad
|
|
1062
|
+
<div>
|
|
1063
|
+
|
|
1064
|
+
<span>text</span>
|
|
1065
|
+
|
|
1066
|
+
<span>more</span>
|
|
1067
|
+
|
|
1068
|
+
</div>
|
|
366
1069
|
```
|
|
367
1070
|
|
|
368
1071
|
<br />
|
|
369
1072
|
|
|
370
|
-
|
|
1073
|
+
## 📞 Call Expression Rules
|
|
1074
|
+
|
|
1075
|
+
### `multiline-argument-newline`
|
|
1076
|
+
|
|
1077
|
+
When function arguments span multiple lines, each argument should start on its own line with consistent indentation.
|
|
371
1078
|
|
|
372
1079
|
```javascript
|
|
373
|
-
//
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
1080
|
+
// Good
|
|
1081
|
+
fn(
|
|
1082
|
+
arg1,
|
|
1083
|
+
arg2,
|
|
1084
|
+
)
|
|
1085
|
+
|
|
1086
|
+
// Bad
|
|
1087
|
+
fn(arg1,
|
|
1088
|
+
arg2)
|
|
1089
|
+
```
|
|
1090
|
+
|
|
1091
|
+
---
|
|
1092
|
+
|
|
1093
|
+
### `multiple-arguments-per-line`
|
|
1094
|
+
|
|
1095
|
+
When a function call has 2+ arguments, each argument should be on its own line with proper indentation.
|
|
1096
|
+
|
|
1097
|
+
```javascript
|
|
1098
|
+
// Good
|
|
1099
|
+
setValue(
|
|
1100
|
+
"numberOfCopies",
|
|
1101
|
+
null,
|
|
1102
|
+
)
|
|
1103
|
+
|
|
1104
|
+
// Bad
|
|
1105
|
+
setValue("numberOfCopies", null)
|
|
1106
|
+
```
|
|
1107
|
+
|
|
1108
|
+
---
|
|
1109
|
+
|
|
1110
|
+
### `nested-call-closing-brackets`
|
|
1111
|
+
|
|
1112
|
+
Nested function calls (like styled-components) should have closing brackets on the same line: }));
|
|
1113
|
+
|
|
1114
|
+
```javascript
|
|
1115
|
+
// Good
|
|
1116
|
+
styled(Card)(({ theme }) => ({
|
|
1117
|
+
color: theme.color,
|
|
1118
|
+
}));
|
|
1119
|
+
|
|
1120
|
+
// Bad
|
|
1121
|
+
styled(Card)(({ theme }) => ({
|
|
1122
|
+
color: theme.color,
|
|
1123
|
+
})
|
|
379
1124
|
);
|
|
1125
|
+
```
|
|
380
1126
|
|
|
381
|
-
|
|
382
|
-
useEffect(() => doSomething(), []);
|
|
1127
|
+
---
|
|
383
1128
|
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
1129
|
+
### `no-empty-lines-in-function-calls`
|
|
1130
|
+
|
|
1131
|
+
Function call arguments should not have empty lines between them or after opening/before closing parentheses.
|
|
1132
|
+
|
|
1133
|
+
```javascript
|
|
1134
|
+
// Good
|
|
1135
|
+
fn(
|
|
1136
|
+
arg1,
|
|
1137
|
+
arg2,
|
|
1138
|
+
)
|
|
1139
|
+
|
|
1140
|
+
// Bad
|
|
1141
|
+
fn(
|
|
1142
|
+
arg1,
|
|
1143
|
+
|
|
1144
|
+
arg2,
|
|
1145
|
+
)
|
|
1146
|
+
```
|
|
1147
|
+
|
|
1148
|
+
---
|
|
1149
|
+
|
|
1150
|
+
### `opening-brackets-same-line`
|
|
1151
|
+
|
|
1152
|
+
Opening brackets should be on the same line as function/method calls. This applies to objects, arrays, and arrow function parameters.
|
|
1153
|
+
|
|
1154
|
+
```javascript
|
|
1155
|
+
// Good
|
|
1156
|
+
fn({ prop: value })
|
|
1157
|
+
.map(({ x }) => x)
|
|
1158
|
+
fn([1, 2, 3])
|
|
1159
|
+
|
|
1160
|
+
// Bad
|
|
1161
|
+
fn(
|
|
1162
|
+
{ prop: value }
|
|
1163
|
+
)
|
|
1164
|
+
.map(
|
|
1165
|
+
({ x }) => x
|
|
1166
|
+
)
|
|
1167
|
+
```
|
|
1168
|
+
|
|
1169
|
+
---
|
|
1170
|
+
|
|
1171
|
+
### `simple-call-single-line`
|
|
1172
|
+
|
|
1173
|
+
Simple function calls with an arrow function containing a simple call expression should be on a single line.
|
|
1174
|
+
|
|
1175
|
+
```javascript
|
|
1176
|
+
// Good
|
|
1177
|
+
fn(() => call(arg))
|
|
1178
|
+
lazy(() => import("./module"))
|
|
1179
|
+
|
|
1180
|
+
// Bad
|
|
1181
|
+
fn(
|
|
1182
|
+
() => call(arg),
|
|
1183
|
+
)
|
|
1184
|
+
```
|
|
1185
|
+
|
|
1186
|
+
---
|
|
1187
|
+
|
|
1188
|
+
### `single-argument-on-one-line`
|
|
1189
|
+
|
|
1190
|
+
Function calls with a single simple argument (literal, identifier, member expression) should be on one line.
|
|
1191
|
+
|
|
1192
|
+
```javascript
|
|
1193
|
+
// Good
|
|
1194
|
+
fn(arg)
|
|
1195
|
+
getValue("key")
|
|
1196
|
+
obj.method(value)
|
|
1197
|
+
|
|
1198
|
+
// Bad
|
|
1199
|
+
fn(
|
|
1200
|
+
arg,
|
|
1201
|
+
)
|
|
388
1202
|
```
|
|
389
1203
|
|
|
390
1204
|
<br />
|
|
391
1205
|
|
|
392
|
-
|
|
1206
|
+
## 📦 Object Rules
|
|
1207
|
+
|
|
1208
|
+
### `no-empty-lines-in-objects`
|
|
1209
|
+
|
|
1210
|
+
Object literals should not contain empty lines between properties or after opening/before closing braces.
|
|
393
1211
|
|
|
394
1212
|
```javascript
|
|
395
|
-
//
|
|
396
|
-
|
|
1213
|
+
// Good
|
|
1214
|
+
{
|
|
1215
|
+
a: 1,
|
|
1216
|
+
b: 2,
|
|
1217
|
+
}
|
|
397
1218
|
|
|
398
|
-
//
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
1219
|
+
// Bad
|
|
1220
|
+
{
|
|
1221
|
+
a: 1,
|
|
1222
|
+
|
|
1223
|
+
b: 2,
|
|
1224
|
+
}
|
|
1225
|
+
```
|
|
1226
|
+
|
|
1227
|
+
---
|
|
1228
|
+
|
|
1229
|
+
### `object-property-per-line`
|
|
1230
|
+
|
|
1231
|
+
When an object has 2 or more properties and spans multiple lines, each property should be on its own line.
|
|
405
1232
|
|
|
406
|
-
|
|
407
|
-
|
|
1233
|
+
```javascript
|
|
1234
|
+
// Good
|
|
1235
|
+
{
|
|
1236
|
+
name: "John",
|
|
1237
|
+
age: 30,
|
|
1238
|
+
}
|
|
1239
|
+
|
|
1240
|
+
// Bad
|
|
1241
|
+
{ name: "John",
|
|
1242
|
+
age: 30 }
|
|
1243
|
+
```
|
|
1244
|
+
|
|
1245
|
+
---
|
|
1246
|
+
|
|
1247
|
+
### `object-property-value-brace`
|
|
1248
|
+
|
|
1249
|
+
Opening brace of an object value should be on the same line as the colon, not on a new line.
|
|
1250
|
+
|
|
1251
|
+
```javascript
|
|
1252
|
+
// Good
|
|
1253
|
+
"& a": { color: "red" }
|
|
1254
|
+
|
|
1255
|
+
// Bad
|
|
1256
|
+
"& a":
|
|
1257
|
+
{ color: "red" }
|
|
1258
|
+
```
|
|
1259
|
+
|
|
1260
|
+
---
|
|
1261
|
+
|
|
1262
|
+
### `object-property-value-format`
|
|
1263
|
+
|
|
1264
|
+
Object property values should be on the same line as the colon with proper spacing for simple values.
|
|
1265
|
+
|
|
1266
|
+
```javascript
|
|
1267
|
+
// Good
|
|
1268
|
+
{
|
|
1269
|
+
name: "John",
|
|
1270
|
+
age: 30,
|
|
1271
|
+
}
|
|
1272
|
+
|
|
1273
|
+
// Bad
|
|
1274
|
+
{
|
|
1275
|
+
name:
|
|
1276
|
+
"John",
|
|
1277
|
+
age:
|
|
1278
|
+
30,
|
|
1279
|
+
}
|
|
1280
|
+
```
|
|
1281
|
+
|
|
1282
|
+
---
|
|
1283
|
+
|
|
1284
|
+
### `string-property-spacing`
|
|
1285
|
+
|
|
1286
|
+
String property keys should not have extra leading or trailing spaces inside the quotes.
|
|
1287
|
+
|
|
1288
|
+
```javascript
|
|
1289
|
+
// Good
|
|
1290
|
+
{ "& a": value }
|
|
1291
|
+
{ "selector": value }
|
|
1292
|
+
|
|
1293
|
+
// Bad
|
|
1294
|
+
{ " & a ": value }
|
|
1295
|
+
{ " selector ": value }
|
|
408
1296
|
```
|
|
409
1297
|
|
|
410
1298
|
<br />
|
|
411
1299
|
|
|
1300
|
+
---
|
|
1301
|
+
|
|
412
1302
|
## 🔧 Auto-fixing
|
|
413
1303
|
|
|
414
1304
|
All rules support auto-fixing. Run ESLint with the `--fix` flag:
|