eslint-plugin-code-style 1.1.2 → 1.1.10

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.
Files changed (4) hide show
  1. package/README.md +853 -655
  2. package/index.d.ts +8 -0
  3. package/index.js +478 -33
  4. package/package.json +1 -1
package/README.md CHANGED
@@ -18,7 +18,7 @@
18
18
 
19
19
  **A powerful ESLint plugin for enforcing consistent code formatting and style rules in React/JSX projects.**
20
20
 
21
- *47 auto-fixable rules to keep your codebase clean and consistent*
21
+ *51 auto-fixable rules to keep your codebase clean and consistent*
22
22
 
23
23
  </div>
24
24
 
@@ -26,7 +26,7 @@
26
26
 
27
27
  ## 🎯 Why This Plugin?
28
28
 
29
- This plugin provides **47 custom auto-fixable rules** for code formatting. Built for **ESLint v9 flat configs**.
29
+ This plugin provides **51 custom auto-fixable rules** for code formatting. Built for **ESLint v9 flat configs**.
30
30
 
31
31
  > **Note:** ESLint [deprecated 79 formatting rules](https://eslint.org/blog/2023/10/deprecating-formatting-rules/) in v8.53.0. Our recommended configs use `@stylistic/eslint-plugin` as the replacement for these deprecated rules.
32
32
 
@@ -59,7 +59,7 @@ We provide **ready-to-use ESLint flat configuration files** that combine `eslint
59
59
 
60
60
  ### 💡 Why Use These Configs?
61
61
 
62
- - **Complete Coverage** — Combines ESLint built-in rules, third-party plugins, and all 47 code-style rules
62
+ - **Complete Coverage** — Combines ESLint built-in rules, third-party plugins, and all 51 code-style rules
63
63
  - **Ready-to-Use** — Copy the config file and start linting immediately
64
64
  - **Battle-Tested** — These configurations have been refined through real-world usage
65
65
  - **Fully Documented** — Each config includes detailed instructions and explanations
@@ -94,7 +94,7 @@ We provide **ready-to-use ESLint flat configuration files** that combine `eslint
94
94
  <td width="50%">
95
95
 
96
96
  ### 🔧 Auto-Fixable Rules
97
- All **47 rules** support automatic fixing with `eslint --fix`. No manual code changes needed.
97
+ All **51 rules** support automatic fixing with `eslint --fix`. No manual code changes needed.
98
98
 
99
99
  </td>
100
100
  <td width="50%">
@@ -225,6 +225,10 @@ rules: {
225
225
  "code-style/single-argument-on-one-line": "error",
226
226
  "code-style/string-property-spacing": "error",
227
227
  "code-style/variable-naming-convention": "error",
228
+ "code-style/enum-format": "error",
229
+ "code-style/interface-format": "error",
230
+ "code-style/type-format": "error",
231
+ "code-style/typescript-definition-location": "error",
228
232
  }
229
233
  ```
230
234
 
@@ -234,34 +238,50 @@ rules: {
234
238
 
235
239
  ## 📖 Rules Summary
236
240
 
237
- > All **47 rules** are auto-fixable. See detailed examples for each rule in the [Rules Reference](#-rules-reference) section below.
241
+ > All **51 rules** are auto-fixable. See detailed examples for each rule in the [Rules Reference](#-rules-reference) section below.
238
242
  >
239
243
  > Rules marked with ⚙️ support customization options (e.g., extending default folder lists).
240
244
 
241
245
  | Rule | Description |
242
246
  |------|-------------|
247
+ | **Array Rules** | |
243
248
  | `array-items-per-line` | Collapse arrays ≤ threshold to one line; expand larger arrays with each item on own line (default: ≤3) ⚙️ |
244
249
  | `array-objects-on-new-lines` | Each object in an array starts on its own line for better visual scanning |
250
+ | **Arrow Function Rules** | |
245
251
  | `arrow-function-block-body` | Wrap multiline arrow function expressions in parentheses for clear boundaries |
246
252
  | `arrow-function-simple-jsx` | Collapse arrow functions returning simple single-element JSX to one line, remove unnecessary parens |
247
253
  | `arrow-function-simplify` | Convert block body with single return to implicit return: `() => { return x; }` → `() => x` |
248
254
  | `curried-arrow-same-line` | Curried arrow functions start on same line as `=>`, not on new line |
249
- | `assignment-value-same-line` | Assignment values start on same line as `=`, not on new line |
250
- | `block-statement-newlines` | Newline after `{` and before `}` in if/for/while/function blocks |
255
+ | **Call Expression Rules** | |
256
+ | `function-arguments-format` | Args threshold or multiline: first arg on new line, each on own line, closing `)` on new line (default: ≥2) ⚙️ |
257
+ | `nested-call-closing-brackets` | Chain closing brackets on same line: `}));` not scattered across lines |
258
+ | `no-empty-lines-in-function-calls` | No empty lines between arguments or after `(`/before `)` |
259
+ | `opening-brackets-same-line` | Opening `{`, `[`, or `(` on same line as function call, not on new line |
260
+ | `simple-call-single-line` | Collapse simple `fn(() => call())` patterns to single line |
261
+ | `single-argument-on-one-line` | Single simple argument stays on one line: `fn(x)` not expanded |
262
+ | **Comment Rules** | |
251
263
  | `comment-format` | Space after `//`, space inside `/* */`, convert single-line blocks to `//`, no blank lines between file-top comments |
264
+ | **Control Flow Rules** | |
265
+ | `block-statement-newlines` | Newline after `{` and before `}` in if/for/while/function blocks |
266
+ | `if-statement-format` | `{` on same line as `if`/`else if`, `else` on same line as `}`, proper spacing |
267
+ | `multiline-if-conditions` | Conditions exceeding threshold get one operand per line with proper indentation (default: >3) ⚙️ |
268
+ | `no-empty-lines-in-switch-cases` | No empty line after `case X:` before code, no empty lines between cases |
269
+ | **Function Rules** | |
252
270
  | `function-call-spacing` | No space between function name and `(`: `fn()` not `fn ()` |
253
271
  | `function-naming-convention` | Functions use camelCase, start with verb (get/set/handle/is/has), handlers end with Handler |
254
272
  | `function-params-per-line` | When multiline, each param on own line with consistent indentation |
273
+ | `no-empty-lines-in-function-params` | No empty lines between parameters or after `(`/before `)` |
274
+ | **Hook Rules** | |
255
275
  | `hook-callback-format` | React hooks: callback on new line, deps array on separate line, proper indentation |
256
276
  | `hook-deps-per-line` | Collapse deps ≤ threshold to one line; expand larger arrays with each dep on own line (default: >2) ⚙️ |
257
- | `if-statement-format` | `{` on same line as `if`/`else if`, `else` on same line as `}`, proper spacing |
258
- | `multiline-if-conditions` | Conditions exceeding threshold get one operand per line with proper indentation (default: >3) ⚙️ |
277
+ | **Import/Export Rules** | |
259
278
  | `absolute-imports-only` | Use alias imports from index files only (not deep paths), no relative imports (default: `@/`) ⚙️ |
260
279
  | `export-format` | `export {` on same line; collapse ≤ threshold to one line; expand larger with each specifier on own line (default: ≤3) ⚙️ |
261
280
  | `import-format` | `import {` and `} from` on same line; collapse ≤ threshold; expand larger with each specifier on own line (default: ≤3) ⚙️ |
262
281
  | `import-source-spacing` | No leading/trailing spaces inside import path quotes |
263
282
  | `index-export-style` | Index files: no blank lines, enforce shorthand or import-export style; Regular files: require blank lines between exports (default: shorthand) ⚙️ |
264
283
  | `module-index-exports` | Index files must export all folder contents (files and subfolders) ⚙️ |
284
+ | **JSX Rules** | |
265
285
  | `jsx-children-on-new-line` | Multiple JSX children: each on own line with proper indentation |
266
286
  | `jsx-closing-bracket-spacing` | No space before `>` or `/>` in JSX tags |
267
287
  | `jsx-element-child-new-line` | Nested JSX elements on new lines; text/expression children can stay inline |
@@ -271,21 +291,22 @@ rules: {
271
291
  | `jsx-simple-element-one-line` | Collapse simple JSX with single text/expression child to one line |
272
292
  | `jsx-string-value-trim` | No leading/trailing whitespace inside JSX string attribute values |
273
293
  | `jsx-ternary-format` | Simple ternaries on one line; complex branches get parens with proper indentation |
274
- | `member-expression-bracket-spacing` | No spaces inside brackets in computed member expressions: `arr[0]` not `arr[ 0 ]` |
275
- | `function-arguments-format` | Args ≥ threshold or multiline: first arg on new line, each on own line, closing `)` on new line (default: ≥2) ⚙️ |
276
- | `nested-call-closing-brackets` | Chain closing brackets on same line: `}));` not scattered across lines |
277
- | `no-empty-lines-in-function-calls` | No empty lines between arguments or after `(`/before `)` |
278
- | `no-empty-lines-in-function-params` | No empty lines between parameters or after `(`/before `)` |
279
294
  | `no-empty-lines-in-jsx` | No empty lines between children or after opening/before closing tags |
295
+ | **Object Rules** | |
280
296
  | `no-empty-lines-in-objects` | No empty lines between properties or after `{`/before `}` |
281
- | `no-empty-lines-in-switch-cases` | No empty line after `case X:` before code, no empty lines between cases |
282
297
  | `object-property-per-line` | Collapse ≤ threshold to one line; expand larger with `{`/`}` on own lines and each property on own line (default: ≥2) ⚙️ |
283
298
  | `object-property-value-brace` | Opening `{` of object value on same line as `:`, not on new line |
284
299
  | `object-property-value-format` | Simple property values on same line as `:`, not on new line |
285
- | `opening-brackets-same-line` | Opening `{`, `[`, or `(` on same line as function call, not on new line |
286
- | `simple-call-single-line` | Collapse simple `fn(() => call())` patterns to single line |
287
- | `single-argument-on-one-line` | Single simple argument stays on one line: `fn(x)` not expanded |
288
300
  | `string-property-spacing` | No leading/trailing spaces inside string property keys |
301
+ | **Spacing Rules** | |
302
+ | `assignment-value-same-line` | Assignment values start on same line as `=`, not on new line |
303
+ | `member-expression-bracket-spacing` | No spaces inside brackets in computed member expressions: `arr[0]` not `arr[ 0 ]` |
304
+ | **TypeScript Rules** | |
305
+ | `enum-format` | Enforce enum naming (PascalCase + Enum suffix), UPPER_CASE members, no empty lines, and trailing commas |
306
+ | `interface-format` | Enforce interface naming (PascalCase + Interface suffix), camelCase properties, no empty lines, and trailing commas |
307
+ | `type-format` | Enforce type naming (PascalCase + Type suffix), camelCase properties, no empty lines, and trailing commas |
308
+ | `typescript-definition-location` | Enforce TypeScript definitions (interfaces, types, enums) to be in designated folders ⚙️ |
309
+ | **Variable Rules** | |
289
310
  | `variable-naming-convention` | camelCase for variables, UPPER_CASE for constants, PascalCase for components, `use` prefix for hooks |
290
311
 
291
312
  <br />
@@ -484,196 +505,528 @@ const mapDispatch = () =>
484
505
 
485
506
  <br />
486
507
 
487
- ## 📐 Spacing & Formatting Rules
508
+ ## 📞 Call Expression Rules
488
509
 
489
- ### `assignment-value-same-line`
510
+ ### `function-arguments-format`
490
511
 
491
- **What it does:** Ensures the assigned value starts on the same line as the `=` sign, not on a new line.
512
+ **What it does:** Enforces consistent formatting for function call arguments:
513
+ - Single simple argument stays on one line
514
+ - 2+ arguments get one per line
515
+ - Multiline arguments trigger full expansion
516
+ - React hooks are skipped by default (they have their own rule)
492
517
 
493
- **Why use it:** Breaking after `=` creates awkward formatting and wastes vertical space. Keeping values on the same line as `=` is more readable.
518
+ **Why use it:** Consistent argument formatting makes function calls scannable and diffs clean when adding/removing arguments.
494
519
 
495
520
  ```javascript
496
- // ✅ Good — value starts on same line as =
497
- const name = "John";
498
- const config = {
499
- host: "localhost",
500
- port: 3000,
501
- };
502
- const items = [
503
- "first",
504
- "second",
505
- ];
506
-
507
- // ❌ Bad — value on new line after =
508
- const name =
509
- "John";
510
- const config =
511
- {
512
- host: "localhost",
513
- port: 3000,
514
- };
515
- const items =
516
- [
517
- "first",
518
- "second",
519
- ];
520
- ```
521
-
522
- ---
523
-
524
- ### `block-statement-newlines`
525
-
526
- **What it does:** Enforces newlines after the opening brace `{` and before the closing brace `}` in block statements (if, for, while, etc.).
527
-
528
- **Why use it:** Consistent block formatting improves readability. Single-line blocks are harder to scan and edit.
521
+ // ✅ Good — single argument stays compact
522
+ fetchUser(userId);
523
+ console.log(message);
524
+ dispatch(action);
529
525
 
530
- ```javascript
531
- // ✅ Good — proper block formatting
532
- if (condition) {
533
- doSomething();
534
- }
526
+ // ✅ Good — 2+ arguments get one per line
527
+ setValue(
528
+ "email",
529
+ "user@example.com",
530
+ );
535
531
 
536
- for (const item of items) {
537
- process(item);
538
- }
532
+ createUser(
533
+ name,
534
+ email,
535
+ password,
536
+ );
539
537
 
540
- while (running) {
541
- tick();
542
- }
538
+ // Good — multiline argument triggers expansion
539
+ processData(
540
+ {
541
+ id: 1,
542
+ name: "test",
543
+ },
544
+ );
543
545
 
544
- // Badeverything on one line
545
- if (condition) { doSomething(); }
546
+ // Goodcallback with body triggers expansion
547
+ items.forEach(
548
+ (item) => {
549
+ process(item);
550
+ save(item);
551
+ },
552
+ );
546
553
 
547
- // ❌ Bad — no space after brace
548
- if (condition) {doSomething();}
554
+ // ❌ Bad — multiple arguments on same line
555
+ setValue("email", "user@example.com");
556
+ createUser(name, email, password);
549
557
 
550
558
  // ❌ Bad — inconsistent formatting
551
- for (const item of items) { process(item);
552
- }
559
+ fn(arg1,
560
+ arg2, arg3);
553
561
  ```
554
562
 
555
- ---
556
-
557
- ### `comment-format`
558
-
559
- **What it does:** Enforces proper comment formatting:
560
- - Space after `//` in line comments
561
- - Space after `/*` and before `*/` in block comments
562
- - Single-line block comments converted to line comments
563
- - No blank lines between consecutive comments at file top
563
+ **Options:**
564
564
 
565
- **Why use it:** Consistent comment formatting improves readability and maintains a clean, professional codebase.
565
+ | Option | Type | Default | Description |
566
+ |--------|------|---------|-------------|
567
+ | `minArgs` | `integer` | `2` | Minimum arguments to enforce multiline |
568
+ | `skipHooks` | `boolean` | `true` | Skip React hooks (useEffect, etc.) |
569
+ | `skipSingleArg` | `boolean` | `true` | Skip calls with single complex argument |
566
570
 
567
571
  ```javascript
568
- // Good proper spacing
569
- // This is a comment
570
- /* This is a block comment */
571
-
572
- /*
573
- * This is a multi-line
574
- * block comment
575
- */
576
-
577
- // ✅ Good — file-top comments without gaps
578
- // File: utils.js
579
- // Author: John Doe
580
- // License: MIT
581
-
582
- // ❌ Bad — missing space after //
583
- //This is a comment
584
-
585
- // ❌ Bad — no space in block comment
586
- /*No space*/
572
+ // Example: Require multiline for 3+ arguments
573
+ "code-style/function-arguments-format": ["error", { minArgs: 3 }]
587
574
 
588
- // Bad single-line block should be line comment
589
- /* This should use // syntax */
575
+ // Example: Don't skip React hooks
576
+ "code-style/function-arguments-format": ["error", { skipHooks: false }]
590
577
  ```
591
578
 
592
579
  ---
593
580
 
594
- ### `member-expression-bracket-spacing`
581
+ ### `nested-call-closing-brackets`
595
582
 
596
- **What it does:** Removes spaces inside brackets in computed member expressions (array access, dynamic property access).
583
+ **What it does:** Ensures nested function calls (common in styled-components, HOCs) have closing brackets on the same line: `}));`
597
584
 
598
- **Why use it:** Consistent with JavaScript conventions. Spaces inside brackets look inconsistent with array literals and other bracket usage.
585
+ **Why use it:** Scattered closing brackets (`}\n);\n` ) waste vertical space and make it harder to see where expressions end.
599
586
 
600
587
  ```javascript
601
- // ✅ Good — no spaces inside brackets
602
- const value = arr[0];
603
- const name = obj[key];
604
- const item = data[index];
605
- const nested = matrix[row][col];
588
+ // ✅ Good — closing brackets together
589
+ const StyledCard = styled(Card)(({ theme }) => ({
590
+ color: theme.palette.text.primary,
591
+ padding: theme.spacing(2),
592
+ }));
606
593
 
607
- // Bad spaces inside brackets
608
- const value = arr[ 0 ];
609
- const name = obj[ key ];
610
- const item = data[ index ];
594
+ const StyledButton = styled("button")(({ theme }) => ({
595
+ backgroundColor: theme.colors.primary,
596
+ }));
597
+
598
+ // ✅ Good — multiple levels
599
+ const Component = connect(
600
+ mapStateToProps,
601
+ mapDispatchToProps,
602
+ )(withRouter(MyComponent));
603
+
604
+ // ❌ Bad — closing brackets scattered
605
+ const StyledCard = styled(Card)(({ theme }) => ({
606
+ color: theme.palette.text.primary,
607
+ })
608
+ );
609
+
610
+ // ❌ Bad — each bracket on its own line
611
+ const StyledCard = styled(Card)(({ theme }) => ({
612
+ color: theme.colors.primary,
613
+ })
614
+ )
615
+ ;
611
616
  ```
612
617
 
613
618
  ---
614
619
 
615
- ### `no-empty-lines-in-function-params`
620
+ ### `no-empty-lines-in-function-calls`
616
621
 
617
- **What it does:** Removes empty lines within function parameter lists — between parameters and after opening/before closing parentheses.
622
+ **What it does:** Removes empty lines within function call argument lists — between arguments and after opening/before closing parentheses.
618
623
 
619
- **Why use it:** Empty lines in parameter lists waste space and make parameters harder to scan as a group.
624
+ **Why use it:** Empty lines between arguments break visual grouping. Arguments should flow as a cohesive list.
620
625
 
621
626
  ```javascript
622
627
  // ✅ Good — no empty lines
623
- function createUser(
628
+ createUser(
624
629
  name,
625
630
  email,
631
+ password,
626
632
  role,
627
- ) {}
633
+ );
628
634
 
629
- const handler = (
630
- event,
631
- context,
632
- ) => {};
635
+ fetchData(
636
+ url,
637
+ {
638
+ method: "POST",
639
+ body: data,
640
+ },
641
+ );
633
642
 
634
- // ❌ Bad — empty line between params
635
- function createUser(
643
+ // ❌ Bad — empty line between arguments
644
+ createUser(
636
645
  name,
637
646
 
638
647
  email,
639
648
 
640
- role,
641
- ) {}
649
+ password,
650
+ );
642
651
 
643
652
  // ❌ Bad — empty line after opening paren
644
- const handler = (
653
+ fetchData(
645
654
 
646
- event,
647
- context,
648
- ) => {};
655
+ url,
656
+ options,
657
+ );
658
+
659
+ // ❌ Bad — empty line before closing paren
660
+ fetchData(
661
+ url,
662
+ options,
663
+
664
+ );
649
665
  ```
650
666
 
651
667
  ---
652
668
 
653
- ### `variable-naming-convention`
669
+ ### `opening-brackets-same-line`
654
670
 
655
- **What it does:** Enforces naming conventions for variables:
656
- - **camelCase** for regular variables and functions
657
- - **UPPER_CASE** for constants (primitive values)
658
- - **PascalCase** for React components and classes
659
- - **camelCase with `use` prefix** for hooks
671
+ **What it does:** Ensures opening brackets (`{`, `[`, `(`) in function arguments stay on the same line as the function call.
660
672
 
661
- **Why use it:** Consistent naming makes code predictable. You can tell what something is by how it's named.
673
+ **Why use it:** Opening brackets on new lines create unnecessary indentation and vertical space.
674
+
675
+ ```javascript
676
+ // ✅ Good — brackets on same line as call
677
+ fn({ key: value });
678
+ process([1, 2, 3]);
679
+ items.map(({ id }) => id);
680
+ configure({ debug: true });
681
+
682
+ // ✅ Good — multiline content is fine
683
+ fn({
684
+ key: value,
685
+ other: data,
686
+ });
687
+
688
+ items.map(({ id, name }) => (
689
+ <Item key={id} name={name} />
690
+ ));
691
+
692
+ // ❌ Bad — opening bracket on new line
693
+ fn(
694
+ { key: value }
695
+ );
696
+
697
+ process(
698
+ [1, 2, 3]
699
+ );
700
+
701
+ items.map(
702
+ ({ id }) => id
703
+ );
704
+ ```
705
+
706
+ ---
707
+
708
+ ### `simple-call-single-line`
709
+
710
+ **What it does:** Collapses simple function calls with an arrow function containing a single call expression onto one line.
711
+
712
+ **Why use it:** Common patterns like `lazy(() => import(...))` don't need multiline formatting. Single line is cleaner.
713
+
714
+ ```javascript
715
+ // ✅ Good — simple patterns on one line
716
+ const Page = lazy(() => import("./Page"));
717
+ const Modal = lazy(() => import("./Modal"));
718
+ setTimeout(() => callback(), 100);
719
+ requestAnimationFrame(() => render());
720
+ items.filter(() => isValid(item));
721
+
722
+ // ✅ Good — complex callbacks stay multiline
723
+ const Page = lazy(() => {
724
+ console.log("Loading page");
725
+ return import("./Page");
726
+ });
727
+
728
+ // ❌ Bad — unnecessary multiline for simple pattern
729
+ const Page = lazy(
730
+ () => import("./Page"),
731
+ );
732
+
733
+ setTimeout(
734
+ () => callback(),
735
+ 100,
736
+ );
737
+ ```
738
+
739
+ ---
740
+
741
+ ### `single-argument-on-one-line`
742
+
743
+ **What it does:** Ensures function calls with a single simple argument (literal, identifier, member expression) stay on one line.
744
+
745
+ **Why use it:** Single-argument calls don't need multiline formatting. Expanding them wastes vertical space.
746
+
747
+ ```javascript
748
+ // ✅ Good — single argument on one line
749
+ fetchUser(userId);
750
+ console.log(message);
751
+ process(data.items);
752
+ dispatch(action);
753
+ setValue("key");
754
+ getElement(document.body);
755
+
756
+ // ✅ Good — complex single argument can be multiline
757
+ processConfig({
758
+ key: value,
759
+ other: data,
760
+ });
761
+
762
+ // ❌ Bad — simple argument expanded unnecessarily
763
+ fetchUser(
764
+ userId,
765
+ );
766
+
767
+ console.log(
768
+ message,
769
+ );
770
+
771
+ dispatch(
772
+ action,
773
+ );
774
+ ```
775
+
776
+ <br />
777
+
778
+ ## 💬 Comment Rules
779
+
780
+ ### `comment-format`
781
+
782
+ **What it does:** Enforces proper comment formatting:
783
+ - Space after `//` in line comments
784
+ - Space after `/*` and before `*/` in block comments
785
+ - Single-line block comments converted to line comments
786
+ - No blank lines between consecutive comments at file top
787
+
788
+ **Why use it:** Consistent comment formatting improves readability and maintains a clean, professional codebase.
789
+
790
+ ```javascript
791
+ // ✅ Good — proper spacing
792
+ // This is a comment
793
+ /* This is a block comment */
794
+
795
+ /*
796
+ * This is a multi-line
797
+ * block comment
798
+ */
799
+
800
+ // ✅ Good — file-top comments without gaps
801
+ // File: utils.js
802
+ // Author: John Doe
803
+ // License: MIT
804
+
805
+ // ❌ Bad — missing space after //
806
+ //This is a comment
807
+
808
+ // ❌ Bad — no space in block comment
809
+ /*No space*/
810
+
811
+ // ❌ Bad — single-line block should be line comment
812
+ /* This should use // syntax */
813
+ ```
814
+
815
+ <br />
816
+
817
+ ## 🔀 Control Flow Rules
818
+
819
+ ### `block-statement-newlines`
820
+
821
+ **What it does:** Enforces newlines after the opening brace `{` and before the closing brace `}` in block statements (if, for, while, etc.).
822
+
823
+ **Why use it:** Consistent block formatting improves readability. Single-line blocks are harder to scan and edit.
824
+
825
+ ```javascript
826
+ // ✅ Good — proper block formatting
827
+ if (condition) {
828
+ doSomething();
829
+ }
830
+
831
+ for (const item of items) {
832
+ process(item);
833
+ }
834
+
835
+ while (running) {
836
+ tick();
837
+ }
838
+
839
+ // ❌ Bad — everything on one line
840
+ if (condition) { doSomething(); }
841
+
842
+ // ❌ Bad — no space after brace
843
+ if (condition) {doSomething();}
844
+
845
+ // ❌ Bad — inconsistent formatting
846
+ for (const item of items) { process(item);
847
+ }
848
+ ```
849
+
850
+ ---
851
+
852
+ ### `if-statement-format`
853
+
854
+ **What it does:** Enforces consistent if/else formatting:
855
+ - Opening `{` on the same line as `if`/`else if`/`else`
856
+ - `else` on the same line as the closing `}`
857
+ - Proper spacing around keywords
858
+
859
+ **Why use it:** Consistent brace placement reduces visual noise and follows the most common JavaScript style (K&R / "one true brace style").
860
+
861
+ ```javascript
862
+ // ✅ Good — consistent formatting
863
+ if (condition) {
864
+ doSomething();
865
+
866
+ doMore();
867
+ }
868
+
869
+ if (condition) {
870
+ doSomething();
871
+
872
+ doMore();
873
+ } else {
874
+ doOther();
875
+
876
+ doAnother();
877
+ }
878
+
879
+ if (conditionA) {
880
+ handleA();
881
+
882
+ processA();
883
+ } else if (conditionB) {
884
+ handleB();
885
+
886
+ processB();
887
+ } else {
888
+ handleDefault();
889
+
890
+ processDefault();
891
+ }
892
+
893
+ // ❌ Bad — brace on new line
894
+ if (condition)
895
+ {
896
+ doSomething();
897
+
898
+ doMore();
899
+ }
900
+
901
+ // ❌ Bad — else on new line
902
+ if (condition) {
903
+ doSomething();
904
+
905
+ doMore();
906
+ }
907
+ else {
908
+ doOther();
909
+
910
+ doAnother();
911
+ }
912
+
913
+ // ❌ Bad — inconsistent formatting
914
+ if (condition)
915
+ {
916
+ doSomething();
917
+
918
+ doMore();
919
+ }
920
+ else
921
+ {
922
+ doOther();
923
+
924
+ doAnother();
925
+ }
926
+ ```
927
+
928
+ ---
929
+
930
+ ### `multiline-if-conditions`
931
+
932
+ **What it does:** When an if statement has more conditions than the threshold (default: 3), each condition goes on its own line with proper indentation.
933
+
934
+ **Why use it:** Long conditions are hard to read on one line. One per line makes each condition clear and easy to modify.
935
+
936
+ ```javascript
937
+ // ✅ Good — 3 or fewer conditions stay inline
938
+ if (isValid && isActive) {}
939
+ if (a && b && c) {}
940
+
941
+ // ✅ Good — 4+ conditions get one per line
942
+ if (
943
+ isAuthenticated &&
944
+ hasPermission &&
945
+ !isExpired &&
946
+ isEnabled
947
+ ) {
948
+ allowAccess();
949
+ }
950
+
951
+ if (
952
+ user.isAdmin ||
953
+ user.isModerator ||
954
+ user.hasSpecialAccess ||
955
+ isPublicResource
956
+ ) {
957
+ showContent();
958
+ }
959
+
960
+ // ❌ Bad — too many conditions on one line
961
+ if (isAuthenticated && hasPermission && !isExpired && isEnabled) {}
962
+
963
+ // ❌ Bad — inconsistent formatting
964
+ if (isAuthenticated &&
965
+ hasPermission && !isExpired &&
966
+ isEnabled) {}
967
+ ```
968
+
969
+ **Options:**
970
+
971
+ | Option | Type | Default | Description |
972
+ |--------|------|---------|-------------|
973
+ | `maxOperands` | `integer` | `3` | Maximum operands to keep on single line |
974
+
975
+ ```javascript
976
+ // Example: Allow up to 4 operands on single line
977
+ "code-style/multiline-if-conditions": ["error", { maxOperands: 4 }]
978
+ ```
979
+
980
+ ---
981
+
982
+ ### `no-empty-lines-in-switch-cases`
983
+
984
+ **What it does:** Removes empty lines at the start of case blocks and between consecutive case statements.
985
+
986
+ **Why use it:** Empty lines inside switch cases create unnecessary gaps. Cases should flow together as a cohesive block.
987
+
988
+ ```javascript
989
+ // ✅ Good — no empty lines
990
+ switch (status) {
991
+ case "pending":
992
+ return "Waiting...";
993
+ case "success":
994
+ return "Done!";
995
+ case "error":
996
+ return "Failed";
997
+ default:
998
+ return "Unknown";
999
+ }
1000
+
1001
+ // ✅ Good — fall-through cases grouped
1002
+ switch (day) {
1003
+ case "Saturday":
1004
+ case "Sunday":
1005
+ return "Weekend";
1006
+ default:
1007
+ return "Weekday";
1008
+ }
662
1009
 
663
- ```javascript
664
- // Good — correct conventions
665
- const userName = "John"; // camelCase for variables
666
- const itemCount = 42; // camelCase for variables
667
- const MAX_RETRIES = 3; // UPPER_CASE for constants
668
- const API_BASE_URL = "/api"; // UPPER_CASE for constants
669
- const UserProfile = () => <div />; // PascalCase for components
670
- const useAuth = () => {}; // camelCase with use prefix for hooks
1010
+ // ❌ Bad — empty line after case label
1011
+ switch (status) {
1012
+ case "pending":
671
1013
 
672
- // ❌ Bad — wrong conventions
673
- const user_name = "John"; // snake_case
674
- const maxretries = 3; // should be UPPER_CASE
675
- const userProfile = () => <div />; // should be PascalCase
676
- const UseAuth = () => {}; // hooks should be camelCase
1014
+ return "Waiting...";
1015
+ case "success":
1016
+ return "Done!";
1017
+ }
1018
+
1019
+ // ❌ Bad — empty lines between cases
1020
+ switch (status) {
1021
+ case "pending":
1022
+ return "Waiting...";
1023
+
1024
+ case "success":
1025
+ return "Done!";
1026
+
1027
+ default:
1028
+ return "Unknown";
1029
+ }
677
1030
  ```
678
1031
 
679
1032
  <br />
@@ -772,9 +1125,47 @@ const handler = (event, context,
772
1125
  callback) => {};
773
1126
  ```
774
1127
 
1128
+ ---
1129
+
1130
+ ### `no-empty-lines-in-function-params`
1131
+
1132
+ **What it does:** Removes empty lines within function parameter lists — between parameters and after opening/before closing parentheses.
1133
+
1134
+ **Why use it:** Empty lines in parameter lists waste space and make parameters harder to scan as a group.
1135
+
1136
+ ```javascript
1137
+ // ✅ Good — no empty lines
1138
+ function createUser(
1139
+ name,
1140
+ email,
1141
+ role,
1142
+ ) {}
1143
+
1144
+ const handler = (
1145
+ event,
1146
+ context,
1147
+ ) => {};
1148
+
1149
+ // ❌ Bad — empty line between params
1150
+ function createUser(
1151
+ name,
1152
+
1153
+ email,
1154
+
1155
+ role,
1156
+ ) {}
1157
+
1158
+ // ❌ Bad — empty line after opening paren
1159
+ const handler = (
1160
+
1161
+ event,
1162
+ context,
1163
+ ) => {};
1164
+ ```
1165
+
775
1166
  <br />
776
1167
 
777
- ## 🪝 React Hooks Rules
1168
+ ## 🪝 Hook Rules
778
1169
 
779
1170
  ### `hook-callback-format`
780
1171
 
@@ -875,190 +1266,6 @@ useEffect(() => {}, [
875
1266
 
876
1267
  <br />
877
1268
 
878
- ## 🔀 Control Flow Rules
879
-
880
- ### `if-statement-format`
881
-
882
- **What it does:** Enforces consistent if/else formatting:
883
- - Opening `{` on the same line as `if`/`else if`/`else`
884
- - `else` on the same line as the closing `}`
885
- - Proper spacing around keywords
886
-
887
- **Why use it:** Consistent brace placement reduces visual noise and follows the most common JavaScript style (K&R / "one true brace style").
888
-
889
- ```javascript
890
- // ✅ Good — consistent formatting
891
- if (condition) {
892
- doSomething();
893
-
894
- doMore();
895
- }
896
-
897
- if (condition) {
898
- doSomething();
899
-
900
- doMore();
901
- } else {
902
- doOther();
903
-
904
- doAnother();
905
- }
906
-
907
- if (conditionA) {
908
- handleA();
909
-
910
- processA();
911
- } else if (conditionB) {
912
- handleB();
913
-
914
- processB();
915
- } else {
916
- handleDefault();
917
-
918
- processDefault();
919
- }
920
-
921
- // ❌ Bad — brace on new line
922
- if (condition)
923
- {
924
- doSomething();
925
-
926
- doMore();
927
- }
928
-
929
- // ❌ Bad — else on new line
930
- if (condition) {
931
- doSomething();
932
-
933
- doMore();
934
- }
935
- else {
936
- doOther();
937
-
938
- doAnother();
939
- }
940
-
941
- // ❌ Bad — inconsistent formatting
942
- if (condition)
943
- {
944
- doSomething();
945
-
946
- doMore();
947
- }
948
- else
949
- {
950
- doOther();
951
-
952
- doAnother();
953
- }
954
- ```
955
-
956
- ---
957
-
958
- ### `multiline-if-conditions`
959
-
960
- **What it does:** When an if statement has more conditions than the threshold (default: 3), each condition goes on its own line with proper indentation.
961
-
962
- **Why use it:** Long conditions are hard to read on one line. One per line makes each condition clear and easy to modify.
963
-
964
- ```javascript
965
- // ✅ Good — 3 or fewer conditions stay inline
966
- if (isValid && isActive) {}
967
- if (a && b && c) {}
968
-
969
- // ✅ Good — 4+ conditions get one per line
970
- if (
971
- isAuthenticated &&
972
- hasPermission &&
973
- !isExpired &&
974
- isEnabled
975
- ) {
976
- allowAccess();
977
- }
978
-
979
- if (
980
- user.isAdmin ||
981
- user.isModerator ||
982
- user.hasSpecialAccess ||
983
- isPublicResource
984
- ) {
985
- showContent();
986
- }
987
-
988
- // ❌ Bad — too many conditions on one line
989
- if (isAuthenticated && hasPermission && !isExpired && isEnabled) {}
990
-
991
- // ❌ Bad — inconsistent formatting
992
- if (isAuthenticated &&
993
- hasPermission && !isExpired &&
994
- isEnabled) {}
995
- ```
996
-
997
- **Options:**
998
-
999
- | Option | Type | Default | Description |
1000
- |--------|------|---------|-------------|
1001
- | `maxOperands` | `integer` | `3` | Maximum operands to keep on single line |
1002
-
1003
- ```javascript
1004
- // Example: Allow up to 4 operands on single line
1005
- "code-style/multiline-if-conditions": ["error", { maxOperands: 4 }]
1006
- ```
1007
-
1008
- ---
1009
-
1010
- ### `no-empty-lines-in-switch-cases`
1011
-
1012
- **What it does:** Removes empty lines at the start of case blocks and between consecutive case statements.
1013
-
1014
- **Why use it:** Empty lines inside switch cases create unnecessary gaps. Cases should flow together as a cohesive block.
1015
-
1016
- ```javascript
1017
- // ✅ Good — no empty lines
1018
- switch (status) {
1019
- case "pending":
1020
- return "Waiting...";
1021
- case "success":
1022
- return "Done!";
1023
- case "error":
1024
- return "Failed";
1025
- default:
1026
- return "Unknown";
1027
- }
1028
-
1029
- // ✅ Good — fall-through cases grouped
1030
- switch (day) {
1031
- case "Saturday":
1032
- case "Sunday":
1033
- return "Weekend";
1034
- default:
1035
- return "Weekday";
1036
- }
1037
-
1038
- // ❌ Bad — empty line after case label
1039
- switch (status) {
1040
- case "pending":
1041
-
1042
- return "Waiting...";
1043
- case "success":
1044
- return "Done!";
1045
- }
1046
-
1047
- // ❌ Bad — empty lines between cases
1048
- switch (status) {
1049
- case "pending":
1050
- return "Waiting...";
1051
-
1052
- case "success":
1053
- return "Done!";
1054
-
1055
- default:
1056
- return "Unknown";
1057
- }
1058
- ```
1059
-
1060
- <br />
1061
-
1062
1269
  ## 📥 Import/Export Rules
1063
1270
 
1064
1271
  ### `absolute-imports-only`
@@ -1092,7 +1299,7 @@ import { fetchUsers } from "@/apis/users/fetchUsers";
1092
1299
  ```
1093
1300
 
1094
1301
  **Default Allowed Folders:**
1095
- `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`
1302
+ `actions`, `apis`, `assets`, `atoms`, `components`, `constants`, `contexts`, `data`, `enums`, `hooks`, `interfaces`, `layouts`, `middlewares`, `providers`, `reducers`, `redux`, `requests`, `routes`, `schemas`, `services`, `store`, `styles`, `theme`, `thunks`, `types`, `utils`, `views`
1096
1303
 
1097
1304
  **Customization Options:**
1098
1305
 
@@ -1336,7 +1543,7 @@ import { Button } from "@/components/Button/Button"; // Avoid this!
1336
1543
  ```
1337
1544
 
1338
1545
  **Default Module Folders:**
1339
- `apis`, `assets`, `atoms`, `components`, `constants`, `contexts`, `data`, `hooks`, `layouts`, `middlewares`, `providers`, `redux`, `requests`, `routes`, `schemas`, `services`, `styles`, `theme`, `utils`, `views`
1546
+ `actions`, `apis`, `assets`, `atoms`, `components`, `constants`, `contexts`, `data`, `enums`, `hooks`, `interfaces`, `layouts`, `middlewares`, `providers`, `reducers`, `redux`, `requests`, `routes`, `schemas`, `services`, `store`, `styles`, `theme`, `thunks`, `types`, `utils`, `views`
1340
1547
 
1341
1548
  **Default Ignore Patterns:**
1342
1549
  `index.js`, `index.jsx`, `index.ts`, `index.tsx`, `.DS_Store`, `__tests__`, `__mocks__`, `*.test.js`, `*.test.jsx`, `*.test.ts`, `*.test.tsx`, `*.spec.js`, `*.spec.jsx`, `*.spec.ts`, `*.spec.tsx`
@@ -1642,339 +1849,69 @@ function Card() {
1642
1849
  </Content>
1643
1850
  )}
1644
1851
 
1645
- // ✅ Good — one simple, one complex
1646
- {isLoading ? <Spinner /> : (
1647
- <Content>
1648
- <Header />
1649
- <Body />
1650
- </Content>
1651
- )}
1652
-
1653
- // ❌ Bad — awkward line breaks
1654
- {isLoading
1655
- ? <Spinner />
1656
- : <Content />}
1657
-
1658
- // ❌ Bad — missing parentheses for complex branch
1659
- {isLoading ? <Spinner /> : <Content>
1660
- <Header />
1661
- <Body />
1662
- </Content>}
1663
- ```
1664
-
1665
- ---
1666
-
1667
- ### `no-empty-lines-in-jsx`
1668
-
1669
- **What it does:** Removes empty lines inside JSX elements — between children and after opening/before closing tags.
1670
-
1671
- **Why use it:** Empty lines inside JSX create visual gaps that break the component's visual structure.
1672
-
1673
- ```javascript
1674
- // ✅ Good — no empty lines inside
1675
- <div>
1676
- <Header />
1677
- <Content />
1678
- <Footer />
1679
- </div>
1680
-
1681
- <Form>
1682
- <Input name="email" />
1683
- <Input name="password" />
1684
- <Button>Submit</Button>
1685
- </Form>
1686
-
1687
- // ❌ Bad — empty line after opening tag
1688
- <div>
1689
-
1690
- <Header />
1691
- <Content />
1692
- </div>
1693
-
1694
- // ❌ Bad — empty lines between children
1695
- <Form>
1696
- <Input name="email" />
1697
-
1698
- <Input name="password" />
1699
-
1700
- <Button>Submit</Button>
1701
- </Form>
1702
-
1703
- // ❌ Bad — empty line before closing tag
1704
- <div>
1705
- <Content />
1706
-
1707
- </div>
1708
- ```
1709
-
1710
- <br />
1711
-
1712
- ## 📞 Call Expression Rules
1713
-
1714
- ### `function-arguments-format`
1715
-
1716
- **What it does:** Enforces consistent formatting for function call arguments:
1717
- - Single simple argument stays on one line
1718
- - 2+ arguments get one per line
1719
- - Multiline arguments trigger full expansion
1720
- - React hooks are skipped by default (they have their own rule)
1721
-
1722
- **Why use it:** Consistent argument formatting makes function calls scannable and diffs clean when adding/removing arguments.
1723
-
1724
- ```javascript
1725
- // ✅ Good — single argument stays compact
1726
- fetchUser(userId);
1727
- console.log(message);
1728
- dispatch(action);
1729
-
1730
- // ✅ Good — 2+ arguments get one per line
1731
- setValue(
1732
- "email",
1733
- "user@example.com",
1734
- );
1735
-
1736
- createUser(
1737
- name,
1738
- email,
1739
- password,
1740
- );
1741
-
1742
- // ✅ Good — multiline argument triggers expansion
1743
- processData(
1744
- {
1745
- id: 1,
1746
- name: "test",
1747
- },
1748
- );
1749
-
1750
- // ✅ Good — callback with body triggers expansion
1751
- items.forEach(
1752
- (item) => {
1753
- process(item);
1754
- save(item);
1755
- },
1756
- );
1757
-
1758
- // ❌ Bad — multiple arguments on same line
1759
- setValue("email", "user@example.com");
1760
- createUser(name, email, password);
1761
-
1762
- // ❌ Bad — inconsistent formatting
1763
- fn(arg1,
1764
- arg2, arg3);
1765
- ```
1766
-
1767
- **Options:**
1768
-
1769
- | Option | Type | Default | Description |
1770
- |--------|------|---------|-------------|
1771
- | `minArgs` | `integer` | `2` | Minimum arguments to enforce multiline |
1772
- | `skipHooks` | `boolean` | `true` | Skip React hooks (useEffect, etc.) |
1773
- | `skipSingleArg` | `boolean` | `true` | Skip calls with single complex argument |
1774
-
1775
- ```javascript
1776
- // Example: Require multiline for 3+ arguments
1777
- "code-style/function-arguments-format": ["error", { minArgs: 3 }]
1778
-
1779
- // Example: Don't skip React hooks
1780
- "code-style/function-arguments-format": ["error", { skipHooks: false }]
1781
- ```
1782
-
1783
- ---
1784
-
1785
- ### `nested-call-closing-brackets`
1786
-
1787
- **What it does:** Ensures nested function calls (common in styled-components, HOCs) have closing brackets on the same line: `}));`
1788
-
1789
- **Why use it:** Scattered closing brackets (`}\n);\n` ) waste vertical space and make it harder to see where expressions end.
1790
-
1791
- ```javascript
1792
- // ✅ Good — closing brackets together
1793
- const StyledCard = styled(Card)(({ theme }) => ({
1794
- color: theme.palette.text.primary,
1795
- padding: theme.spacing(2),
1796
- }));
1797
-
1798
- const StyledButton = styled("button")(({ theme }) => ({
1799
- backgroundColor: theme.colors.primary,
1800
- }));
1801
-
1802
- // ✅ Good — multiple levels
1803
- const Component = connect(
1804
- mapStateToProps,
1805
- mapDispatchToProps,
1806
- )(withRouter(MyComponent));
1807
-
1808
- // ❌ Bad — closing brackets scattered
1809
- const StyledCard = styled(Card)(({ theme }) => ({
1810
- color: theme.palette.text.primary,
1811
- })
1812
- );
1813
-
1814
- // ❌ Bad — each bracket on its own line
1815
- const StyledCard = styled(Card)(({ theme }) => ({
1816
- color: theme.colors.primary,
1817
- })
1818
- )
1819
- ;
1820
- ```
1821
-
1822
- ---
1823
-
1824
- ### `no-empty-lines-in-function-calls`
1825
-
1826
- **What it does:** Removes empty lines within function call argument lists — between arguments and after opening/before closing parentheses.
1827
-
1828
- **Why use it:** Empty lines between arguments break visual grouping. Arguments should flow as a cohesive list.
1829
-
1830
- ```javascript
1831
- // ✅ Good — no empty lines
1832
- createUser(
1833
- name,
1834
- email,
1835
- password,
1836
- role,
1837
- );
1838
-
1839
- fetchData(
1840
- url,
1841
- {
1842
- method: "POST",
1843
- body: data,
1844
- },
1845
- );
1846
-
1847
- // ❌ Bad — empty line between arguments
1848
- createUser(
1849
- name,
1850
-
1851
- email,
1852
-
1853
- password,
1854
- );
1855
-
1856
- // ❌ Bad — empty line after opening paren
1857
- fetchData(
1858
-
1859
- url,
1860
- options,
1861
- );
1862
-
1863
- // ❌ Bad — empty line before closing paren
1864
- fetchData(
1865
- url,
1866
- options,
1867
-
1868
- );
1869
- ```
1870
-
1871
- ---
1872
-
1873
- ### `opening-brackets-same-line`
1874
-
1875
- **What it does:** Ensures opening brackets (`{`, `[`, `(`) in function arguments stay on the same line as the function call.
1876
-
1877
- **Why use it:** Opening brackets on new lines create unnecessary indentation and vertical space.
1878
-
1879
- ```javascript
1880
- // ✅ Good — brackets on same line as call
1881
- fn({ key: value });
1882
- process([1, 2, 3]);
1883
- items.map(({ id }) => id);
1884
- configure({ debug: true });
1885
-
1886
- // ✅ Good — multiline content is fine
1887
- fn({
1888
- key: value,
1889
- other: data,
1890
- });
1891
-
1892
- items.map(({ id, name }) => (
1893
- <Item key={id} name={name} />
1894
- ));
1895
-
1896
- // ❌ Bad — opening bracket on new line
1897
- fn(
1898
- { key: value }
1899
- );
1900
-
1901
- process(
1902
- [1, 2, 3]
1903
- );
1852
+ // ✅ Good — one simple, one complex
1853
+ {isLoading ? <Spinner /> : (
1854
+ <Content>
1855
+ <Header />
1856
+ <Body />
1857
+ </Content>
1858
+ )}
1904
1859
 
1905
- items.map(
1906
- ({ id }) => id
1907
- );
1860
+ // ❌ Bad — awkward line breaks
1861
+ {isLoading
1862
+ ? <Spinner />
1863
+ : <Content />}
1864
+
1865
+ // ❌ Bad — missing parentheses for complex branch
1866
+ {isLoading ? <Spinner /> : <Content>
1867
+ <Header />
1868
+ <Body />
1869
+ </Content>}
1908
1870
  ```
1909
1871
 
1910
1872
  ---
1911
1873
 
1912
- ### `simple-call-single-line`
1874
+ ### `no-empty-lines-in-jsx`
1913
1875
 
1914
- **What it does:** Collapses simple function calls with an arrow function containing a single call expression onto one line.
1876
+ **What it does:** Removes empty lines inside JSX elements between children and after opening/before closing tags.
1915
1877
 
1916
- **Why use it:** Common patterns like `lazy(() => import(...))` don't need multiline formatting. Single line is cleaner.
1878
+ **Why use it:** Empty lines inside JSX create visual gaps that break the component's visual structure.
1917
1879
 
1918
1880
  ```javascript
1919
- // ✅ Good — simple patterns on one line
1920
- const Page = lazy(() => import("./Page"));
1921
- const Modal = lazy(() => import("./Modal"));
1922
- setTimeout(() => callback(), 100);
1923
- requestAnimationFrame(() => render());
1924
- items.filter(() => isValid(item));
1925
-
1926
- // ✅ Good — complex callbacks stay multiline
1927
- const Page = lazy(() => {
1928
- console.log("Loading page");
1929
- return import("./Page");
1930
- });
1931
-
1932
- // ❌ Bad — unnecessary multiline for simple pattern
1933
- const Page = lazy(
1934
- () => import("./Page"),
1935
- );
1936
-
1937
- setTimeout(
1938
- () => callback(),
1939
- 100,
1940
- );
1941
- ```
1942
-
1943
- ---
1881
+ // ✅ Good — no empty lines inside
1882
+ <div>
1883
+ <Header />
1884
+ <Content />
1885
+ <Footer />
1886
+ </div>
1944
1887
 
1945
- ### `single-argument-on-one-line`
1888
+ <Form>
1889
+ <Input name="email" />
1890
+ <Input name="password" />
1891
+ <Button>Submit</Button>
1892
+ </Form>
1946
1893
 
1947
- **What it does:** Ensures function calls with a single simple argument (literal, identifier, member expression) stay on one line.
1894
+ // Bad empty line after opening tag
1895
+ <div>
1948
1896
 
1949
- **Why use it:** Single-argument calls don't need multiline formatting. Expanding them wastes vertical space.
1897
+ <Header />
1898
+ <Content />
1899
+ </div>
1950
1900
 
1951
- ```javascript
1952
- // ✅ Good — single argument on one line
1953
- fetchUser(userId);
1954
- console.log(message);
1955
- process(data.items);
1956
- dispatch(action);
1957
- setValue("key");
1958
- getElement(document.body);
1901
+ // ❌ Bad — empty lines between children
1902
+ <Form>
1903
+ <Input name="email" />
1959
1904
 
1960
- // Good — complex single argument can be multiline
1961
- processConfig({
1962
- key: value,
1963
- other: data,
1964
- });
1905
+ <Input name="password" />
1965
1906
 
1966
- // ❌ Bad — simple argument expanded unnecessarily
1967
- fetchUser(
1968
- userId,
1969
- );
1907
+ <Button>Submit</Button>
1908
+ </Form>
1970
1909
 
1971
- console.log(
1972
- message,
1973
- );
1910
+ // ❌ Bad — empty line before closing tag
1911
+ <div>
1912
+ <Content />
1974
1913
 
1975
- dispatch(
1976
- action,
1977
- );
1914
+ </div>
1978
1915
  ```
1979
1916
 
1980
1917
  <br />
@@ -2200,6 +2137,267 @@ const styles = {
2200
2137
 
2201
2138
  <br />
2202
2139
 
2140
+ ## 📐 Spacing Rules
2141
+
2142
+ ### `assignment-value-same-line`
2143
+
2144
+ **What it does:** Ensures the assigned value starts on the same line as the `=` sign, not on a new line.
2145
+
2146
+ **Why use it:** Breaking after `=` creates awkward formatting and wastes vertical space. Keeping values on the same line as `=` is more readable.
2147
+
2148
+ ```javascript
2149
+ // ✅ Good — value starts on same line as =
2150
+ const name = "John";
2151
+ const config = {
2152
+ host: "localhost",
2153
+ port: 3000,
2154
+ };
2155
+ const items = [
2156
+ "first",
2157
+ "second",
2158
+ ];
2159
+
2160
+ // ❌ Bad — value on new line after =
2161
+ const name =
2162
+ "John";
2163
+ const config =
2164
+ {
2165
+ host: "localhost",
2166
+ port: 3000,
2167
+ };
2168
+ const items =
2169
+ [
2170
+ "first",
2171
+ "second",
2172
+ ];
2173
+ ```
2174
+
2175
+ ---
2176
+
2177
+ ### `member-expression-bracket-spacing`
2178
+
2179
+ **What it does:** Removes spaces inside brackets in computed member expressions (array access, dynamic property access).
2180
+
2181
+ **Why use it:** Consistent with JavaScript conventions. Spaces inside brackets look inconsistent with array literals and other bracket usage.
2182
+
2183
+ ```javascript
2184
+ // ✅ Good — no spaces inside brackets
2185
+ const value = arr[0];
2186
+ const name = obj[key];
2187
+ const item = data[index];
2188
+ const nested = matrix[row][col];
2189
+
2190
+ // ❌ Bad — spaces inside brackets
2191
+ const value = arr[ 0 ];
2192
+ const name = obj[ key ];
2193
+ const item = data[ index ];
2194
+ ```
2195
+
2196
+ <br />
2197
+
2198
+ ## 🔷 TypeScript Rules
2199
+
2200
+ ### `enum-format`
2201
+
2202
+ **What it does:** Enforces consistent formatting for TypeScript enums:
2203
+ - Enum names must be PascalCase and end with `Enum` suffix
2204
+ - Enum members must be UPPER_CASE (for string enums) or PascalCase (for numeric enums)
2205
+ - No empty lines between enum members
2206
+ - Members must end with commas, not semicolons
2207
+
2208
+ **Why use it:** Consistent enum naming makes enums instantly recognizable. UPPER_CASE members follow common conventions for constants.
2209
+
2210
+ ```typescript
2211
+ // ✅ Good — proper enum format
2212
+ export enum StatusEnum {
2213
+ ACTIVE = "active",
2214
+ INACTIVE = "inactive",
2215
+ PENDING = "pending",
2216
+ }
2217
+
2218
+ export enum HttpMethodEnum {
2219
+ DELETE = "DELETE",
2220
+ GET = "GET",
2221
+ POST = "POST",
2222
+ PUT = "PUT",
2223
+ }
2224
+
2225
+ // ❌ Bad — wrong naming
2226
+ export enum Status { // Missing Enum suffix
2227
+ active = "active", // Should be UPPER_CASE
2228
+ inactive = "inactive"; // Should use comma, not semicolon
2229
+ }
2230
+
2231
+ // ❌ Bad — empty lines between members
2232
+ export enum UserStatusEnum {
2233
+ ACTIVE = "active",
2234
+
2235
+ INACTIVE = "inactive",
2236
+ }
2237
+ ```
2238
+
2239
+ ---
2240
+
2241
+ ### `interface-format`
2242
+
2243
+ **What it does:** Enforces consistent formatting for TypeScript interfaces:
2244
+ - Interface names must be PascalCase and end with `Interface` suffix
2245
+ - Properties must be camelCase
2246
+ - No empty lines between properties
2247
+ - Properties must end with commas, not semicolons
2248
+
2249
+ **Why use it:** Consistent interface naming makes interfaces instantly recognizable. The suffix clearly distinguishes interfaces from types and classes.
2250
+
2251
+ ```typescript
2252
+ // ✅ Good — proper interface format
2253
+ export interface UserInterface {
2254
+ email: string,
2255
+ id: string,
2256
+ isActive: boolean,
2257
+ name: string,
2258
+ }
2259
+
2260
+ export interface ApiResponseInterface<T> {
2261
+ data: T,
2262
+ error: string | null,
2263
+ status: number,
2264
+ success: boolean,
2265
+ }
2266
+
2267
+ // ❌ Bad — wrong naming
2268
+ export interface User { // Missing Interface suffix
2269
+ Email: string; // Should be camelCase
2270
+ ID: string; // Should be camelCase
2271
+ is_active: boolean; // Should be camelCase, use comma
2272
+ }
2273
+
2274
+ // ❌ Bad — semicolons and empty lines
2275
+ export interface UserInterface {
2276
+ email: string; // Should use comma
2277
+
2278
+ name: string; // Empty line not allowed
2279
+ }
2280
+ ```
2281
+
2282
+ ---
2283
+
2284
+ ### `type-format`
2285
+
2286
+ **What it does:** Enforces consistent formatting for TypeScript type aliases:
2287
+ - Type names must be PascalCase and end with `Type` suffix
2288
+ - Properties must be camelCase
2289
+ - No empty lines between properties
2290
+ - Properties must end with commas, not semicolons
2291
+
2292
+ **Why use it:** Consistent type naming makes types instantly recognizable. The suffix clearly distinguishes types from interfaces and classes.
2293
+
2294
+ ```typescript
2295
+ // ✅ Good — proper type format
2296
+ export type UserType = {
2297
+ email: string,
2298
+ id: string,
2299
+ name: string,
2300
+ };
2301
+
2302
+ export type ApiResponseType<T> = {
2303
+ data: T,
2304
+ error: string | null,
2305
+ status: number,
2306
+ };
2307
+
2308
+ // ❌ Bad — wrong naming
2309
+ export type User = { // Missing Type suffix
2310
+ Email: string; // Should be camelCase
2311
+ ID: string; // Should use comma
2312
+ };
2313
+
2314
+ // ❌ Bad — empty lines
2315
+ export type ConfigType = {
2316
+ debug: boolean,
2317
+
2318
+ port: number, // Empty line not allowed
2319
+ };
2320
+ ```
2321
+
2322
+ ---
2323
+
2324
+ ### `typescript-definition-location`
2325
+
2326
+ **What it does:** Enforces that TypeScript definitions are placed in their designated folders:
2327
+ - Interfaces must be in files inside the `interfaces` folder
2328
+ - Types must be in files inside the `types` folder
2329
+ - Enums must be in files inside the `enums` folder
2330
+
2331
+ **Why use it:** Separating type definitions by category makes them easier to find, maintain, and share across the codebase. It promotes a clean and organized project structure.
2332
+
2333
+ ```typescript
2334
+ // ✅ Good — definitions in correct folders
2335
+ // src/interfaces/user.ts
2336
+ export interface UserInterface {
2337
+ id: string,
2338
+ name: string,
2339
+ }
2340
+
2341
+ // src/types/config.ts
2342
+ export type ConfigType = {
2343
+ apiUrl: string,
2344
+ timeout: number,
2345
+ };
2346
+
2347
+ // src/enums/status.ts
2348
+ export enum UserRoleEnum {
2349
+ ADMIN = "admin",
2350
+ USER = "user",
2351
+ }
2352
+
2353
+ // ❌ Bad — definitions in wrong folders
2354
+ // src/components/user-card.tsx
2355
+ interface UserProps { // Should be in interfaces folder
2356
+ name: string,
2357
+ }
2358
+
2359
+ // src/types/user.ts
2360
+ export interface UserInterface { // Should be in interfaces folder, not types
2361
+ id: string,
2362
+ }
2363
+
2364
+ export enum StatusEnum { // Should be in enums folder, not types
2365
+ ACTIVE = "active",
2366
+ }
2367
+ ```
2368
+
2369
+ <br />
2370
+
2371
+ ## 📝 Variable Rules
2372
+
2373
+ ### `variable-naming-convention`
2374
+
2375
+ **What it does:** Enforces naming conventions for variables:
2376
+ - **camelCase** for regular variables and functions
2377
+ - **UPPER_CASE** for constants (primitive values)
2378
+ - **PascalCase** for React components and classes
2379
+ - **camelCase with `use` prefix** for hooks
2380
+
2381
+ **Why use it:** Consistent naming makes code predictable. You can tell what something is by how it's named.
2382
+
2383
+ ```javascript
2384
+ // ✅ Good — correct conventions
2385
+ const userName = "John"; // camelCase for variables
2386
+ const itemCount = 42; // camelCase for variables
2387
+ const MAX_RETRIES = 3; // UPPER_CASE for constants
2388
+ const API_BASE_URL = "/api"; // UPPER_CASE for constants
2389
+ const UserProfile = () => <div />; // PascalCase for components
2390
+ const useAuth = () => {}; // camelCase with use prefix for hooks
2391
+
2392
+ // ❌ Bad — wrong conventions
2393
+ const user_name = "John"; // snake_case
2394
+ const maxretries = 3; // should be UPPER_CASE
2395
+ const userProfile = () => <div />; // should be PascalCase
2396
+ const UseAuth = () => {}; // hooks should be camelCase
2397
+ ```
2398
+
2399
+ <br />
2400
+
2203
2401
  ---
2204
2402
 
2205
2403
  ## 🔧 Auto-fixing