eslint-plugin-nextfriday 1.5.3 → 1.7.0

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/CHANGELOG.md CHANGED
@@ -1,5 +1,20 @@
1
1
  # eslint-plugin-nextfriday
2
2
 
3
+ ## 1.7.0
4
+
5
+ ### Minor Changes
6
+
7
+ - [#41](https://github.com/next-friday/eslint-plugin-nextfriday/pull/41) [`10b67d9`](https://github.com/next-friday/eslint-plugin-nextfriday/commit/10b67d941c47fef5b72408bfff2b56e98a46c26c) Thanks [@nextfridaydeveloper](https://github.com/nextfridaydeveloper)! - Add no-direct-date rule to disallow direct usage of Date constructor and methods (new Date(), Date.now(), Date.parse()) to enforce centralized date utilities like dayjs
8
+
9
+ ## 1.6.0
10
+
11
+ ### Minor Changes
12
+
13
+ - [#36](https://github.com/next-friday/eslint-plugin-nextfriday/pull/36) [`f819ffa`](https://github.com/next-friday/eslint-plugin-nextfriday/commit/f819ffa8eed179e38eed4ec51a05dec53dd979d0) Thanks [@joetakara](https://github.com/joetakara)! - Add three new ESLint rules:
14
+ - `jsx-no-non-component-function`: Prevent non-component functions at top level in .tsx/.jsx files
15
+ - `enforce-sorted-destructuring`: Enforce alphabetical sorting of destructured properties with defaults first
16
+ - `jsx-no-variable-in-callback`: Prevent variable declarations inside JSX callbacks for cleaner code
17
+
3
18
  ## 1.5.3
4
19
 
5
20
  ### Patch Changes
package/README.md CHANGED
@@ -22,7 +22,7 @@ pnpm add -D eslint-plugin-nextfriday
22
22
  import nextfriday from "eslint-plugin-nextfriday";
23
23
 
24
24
  export default [nextfriday.configs.base];
25
- // or use the recommended preset
25
+ // or use the recommended preset (stricter)
26
26
  export default [nextfriday.configs["base/recommended"]];
27
27
  ```
28
28
 
@@ -59,19 +59,37 @@ export default [
59
59
  nextfriday,
60
60
  },
61
61
  rules: {
62
- "nextfriday/no-emoji": "error",
62
+ // Variable Naming
63
+ "nextfriday/no-single-char-variables": "error",
64
+ "nextfriday/boolean-naming-prefix": "error",
65
+
66
+ // File Naming
63
67
  "nextfriday/file-kebab-case": "error",
68
+ "nextfriday/jsx-pascal-case": "error",
64
69
  "nextfriday/md-filename-case-restriction": "error",
70
+
71
+ // Code Style
72
+ "nextfriday/no-emoji": "error",
65
73
  "nextfriday/prefer-destructuring-params": "error",
66
- "nextfriday/no-explicit-return-type": "error",
67
- "nextfriday/prefer-import-type": "error",
68
- "nextfriday/prefer-named-param-types": "error",
69
- "nextfriday/prefer-react-import-types": "error",
74
+ "nextfriday/prefer-function-declaration": "error",
75
+ "nextfriday/require-explicit-return-type": "error",
70
76
  "nextfriday/no-complex-inline-return": "error",
71
77
  "nextfriday/no-logic-in-params": "error",
78
+ "nextfriday/enforce-sorted-destructuring": "error",
72
79
  "nextfriday/no-env-fallback": "error",
73
- "nextfriday/jsx-pascal-case": "error",
80
+
81
+ // Import Optimization
82
+ "nextfriday/prefer-import-type": "error",
83
+ "nextfriday/prefer-react-import-types": "error",
84
+
85
+ // Type Patterns
86
+ "nextfriday/prefer-named-param-types": "error",
74
87
  "nextfriday/prefer-interface-over-inline-types": "error",
88
+
89
+ // React/JSX
90
+ "nextfriday/jsx-no-non-component-function": "error",
91
+ "nextfriday/jsx-no-variable-in-callback": "error",
92
+ "nextfriday/prefer-jsx-template-literals": "error",
75
93
  "nextfriday/react-props-destructure": "error",
76
94
  "nextfriday/enforce-readonly-component-props": "error",
77
95
  },
@@ -110,87 +128,119 @@ module.exports = {
110
128
 
111
129
  ## Rules
112
130
 
113
- | Rule | Description | Fixable |
114
- | -------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------- | ------- |
115
- | [no-emoji](docs/rules/NO_EMOJI.md) | Disallow emojis in code | ❌ |
116
- | [file-kebab-case](docs/rules/FILE_KEBAB_CASE.md) | Enforce kebab-case filenames for .ts and .js files | ❌ |
117
- | [jsx-pascal-case](docs/rules/JSX_PASCAL_CASE.md) | Enforce PascalCase filenames for .jsx and .tsx files | ❌ |
118
- | [md-filename-case-restriction](docs/rules/MD_FILENAME_CASE_RESTRICTION.md) | Enforce SNAKE_CASE filenames for .md files | ❌ |
119
- | [prefer-destructuring-params](docs/rules/PREFER_DESTRUCTURING_PARAMS.md) | Enforce destructuring for functions with multiple parameters | ❌ |
120
- | [no-explicit-return-type](docs/rules/NO_EXPLICIT_RETURN_TYPE.md) | Disallow explicit return types on functions | ✅ |
121
- | [prefer-import-type](docs/rules/PREFER_IMPORT_TYPE.md) | Enforce using 'import type' for type-only imports | ✅ |
122
- | [prefer-named-param-types](docs/rules/PREFER_NAMED_PARAM_TYPES.md) | Enforce named types for function parameters with object types | ❌ |
123
- | [prefer-interface-over-inline-types](docs/rules/PREFER_INTERFACE_OVER_INLINE_TYPES.md) | Enforce interface declarations over inline types for React props | ❌ |
124
- | [prefer-react-import-types](docs/rules/PREFER_REACT_IMPORT_TYPES.md) | Enforce direct imports from 'react' instead of React.X | ✅ |
125
- | [react-props-destructure](docs/rules/REACT_PROPS_DESTRUCTURE.md) | Enforce destructuring props inside React component body | ❌ |
126
- | [enforce-readonly-component-props](docs/rules/ENFORCE_READONLY_COMPONENT_PROPS.md) | Enforce Readonly wrapper for React component props | ✅ |
127
- | [no-complex-inline-return](docs/rules/NO_COMPLEX_INLINE_RETURN.md) | Disallow complex inline expressions in return statements - prefer const first | ❌ |
128
- | [no-logic-in-params](docs/rules/NO_LOGIC_IN_PARAMS.md) | Disallow logic or conditions in function parameters - extract to const first | ❌ |
129
- | [no-env-fallback](docs/rules/NO_ENV_FALLBACK.md) | Disallow fallback values for environment variables as they can be dangerous | ❌ |
130
-
131
- ## Configurations
132
-
133
- ### Base Configurations (for pure JS/TS projects)
134
-
135
- #### `base`
136
-
137
- Basic configuration without JSX-specific rules:
131
+ ### Variable Naming Rules
138
132
 
139
- - `nextfriday/no-emoji`: `"error"`
140
- - `nextfriday/file-kebab-case`: `"error"`
141
- - `nextfriday/md-filename-case-restriction`: `"error"`
142
- - `nextfriday/prefer-destructuring-params`: `"error"`
143
- - `nextfriday/no-explicit-return-type`: `"error"`
144
- - `nextfriday/prefer-import-type`: `"error"`
145
- - `nextfriday/prefer-named-param-types`: `"error"`
146
- - `nextfriday/prefer-react-import-types`: `"error"`
147
- - `nextfriday/no-complex-inline-return`: `"error"`
148
- - `nextfriday/no-logic-in-params`: `"error"`
149
- - `nextfriday/no-env-fallback`: `"error"`
133
+ | Rule | Description | Fixable |
134
+ | ------------------------------------------------------------------ | --------------------------------------------------------------------- | ------- |
135
+ | [no-single-char-variables](docs/rules/NO_SINGLE_CHAR_VARIABLES.md) | Disallow single character variable names (e.g., `d`, `u`, `l`) | ❌ |
136
+ | [boolean-naming-prefix](docs/rules/BOOLEAN_NAMING_PREFIX.md) | Enforce boolean variables to have prefix (is, has, should, can, etc.) | ❌ |
150
137
 
151
- #### `base/recommended`
138
+ ### File Naming Rules
152
139
 
153
- Same as `base` configuration (recommended preset for pure JS/TS projects).
140
+ | Rule | Description | Fixable |
141
+ | -------------------------------------------------------------------------- | ---------------------------------------------------- | ------- |
142
+ | [file-kebab-case](docs/rules/FILE_KEBAB_CASE.md) | Enforce kebab-case filenames for .ts and .js files | ❌ |
143
+ | [jsx-pascal-case](docs/rules/JSX_PASCAL_CASE.md) | Enforce PascalCase filenames for .jsx and .tsx files | ❌ |
144
+ | [md-filename-case-restriction](docs/rules/MD_FILENAME_CASE_RESTRICTION.md) | Enforce SNAKE_CASE filenames for .md files | ❌ |
154
145
 
155
- ### React Configurations
146
+ ### Code Style Rules
156
147
 
157
- #### `react`
148
+ | Rule | Description | Fixable |
149
+ | -------------------------------------------------------------------------- | ---------------------------------------------------------------------- | ------- |
150
+ | [no-emoji](docs/rules/NO_EMOJI.md) | Disallow emoji characters in source code | ❌ |
151
+ | [prefer-destructuring-params](docs/rules/PREFER_DESTRUCTURING_PARAMS.md) | Enforce destructuring for functions with multiple parameters | ❌ |
152
+ | [prefer-function-declaration](docs/rules/PREFER_FUNCTION_DECLARATION.md) | Enforce function declarations over arrow functions in .ts files | ❌ |
153
+ | [require-explicit-return-type](docs/rules/REQUIRE_EXPLICIT_RETURN_TYPE.md) | Require explicit return types on functions for better documentation | ❌ |
154
+ | [no-complex-inline-return](docs/rules/NO_COMPLEX_INLINE_RETURN.md) | Disallow complex inline expressions in return - extract to const first | ❌ |
155
+ | [no-logic-in-params](docs/rules/NO_LOGIC_IN_PARAMS.md) | Disallow logic/conditions in function parameters - extract to const | ❌ |
156
+ | [enforce-sorted-destructuring](docs/rules/ENFORCE_SORTED_DESTRUCTURING.md) | Enforce alphabetical sorting of destructured properties | ❌ |
157
+ | [no-env-fallback](docs/rules/NO_ENV_FALLBACK.md) | Disallow fallback values for environment variables | ❌ |
158
+ | [no-direct-date](docs/rules/NO_DIRECT_DATE.md) | Disallow direct usage of Date constructor and methods | ❌ |
158
159
 
159
- Includes all base rules plus React-specific rules:
160
+ ### Import Optimization Rules
160
161
 
161
- - All base rules above
162
- - `nextfriday/jsx-pascal-case`: `"error"`
163
- - `nextfriday/prefer-interface-over-inline-types`: `"error"`
164
- - `nextfriday/react-props-destructure`: `"error"`
165
- - `nextfriday/enforce-readonly-component-props`: `"error"`
162
+ | Rule | Description | Fixable |
163
+ | -------------------------------------------------------------------- | ------------------------------------------------------ | ------- |
164
+ | [prefer-import-type](docs/rules/PREFER_IMPORT_TYPE.md) | Enforce using 'import type' for type-only imports | ✅ |
165
+ | [prefer-react-import-types](docs/rules/PREFER_REACT_IMPORT_TYPES.md) | Enforce direct imports from 'react' instead of React.X | ✅ |
166
166
 
167
- #### `react/recommended`
167
+ ### Type Pattern Rules
168
168
 
169
- Same as `react` configuration (recommended preset for React projects).
169
+ | Rule | Description | Fixable |
170
+ | -------------------------------------------------------------------------------------- | ---------------------------------------------------------------- | ------- |
171
+ | [prefer-named-param-types](docs/rules/PREFER_NAMED_PARAM_TYPES.md) | Enforce named types for function parameters with object types | ❌ |
172
+ | [prefer-interface-over-inline-types](docs/rules/PREFER_INTERFACE_OVER_INLINE_TYPES.md) | Enforce interface declarations over inline types for React props | ❌ |
170
173
 
171
- ### Next.js Configurations
174
+ ### React/JSX Rules
172
175
 
173
- #### `nextjs`
176
+ | Rule | Description | Fixable |
177
+ | ---------------------------------------------------------------------------------- | -------------------------------------------------------------------- | ------- |
178
+ | [jsx-no-non-component-function](docs/rules/JSX_NO_NON_COMPONENT_FUNCTION.md) | Disallow non-component functions at top level in .tsx/.jsx files | ❌ |
179
+ | [jsx-no-variable-in-callback](docs/rules/JSX_NO_VARIABLE_IN_CALLBACK.md) | Disallow variable declarations inside callback functions in JSX | ❌ |
180
+ | [prefer-jsx-template-literals](docs/rules/PREFER_JSX_TEMPLATE_LITERALS.md) | Enforce template literals instead of mixing text and JSX expressions | ✅ |
181
+ | [react-props-destructure](docs/rules/REACT_PROPS_DESTRUCTURE.md) | Enforce destructuring props inside React component body | ❌ |
182
+ | [enforce-readonly-component-props](docs/rules/ENFORCE_READONLY_COMPONENT_PROPS.md) | Enforce Readonly wrapper for React component props | ✅ |
174
183
 
175
- Includes all rules suitable for Next.js projects:
176
-
177
- - All base rules
178
- - `nextfriday/jsx-pascal-case`: `"error"`
179
- - `nextfriday/prefer-interface-over-inline-types`: `"error"`
180
- - `nextfriday/react-props-destructure`: `"error"`
181
- - `nextfriday/enforce-readonly-component-props`: `"error"`
182
-
183
- #### `nextjs/recommended`
184
+ ## Configurations
184
185
 
185
- Same as `nextjs` configuration (recommended preset for Next.js projects).
186
+ ### Configuration Presets Overview
187
+
188
+ | Preset | Severity | Base Rules | JSX Rules | Total Rules |
189
+ | -------------------- | -------- | ---------- | --------- | ----------- |
190
+ | `base` | warn | 16 | 0 | 16 |
191
+ | `base/recommended` | error | 16 | 0 | 16 |
192
+ | `react` | warn | 16 | 7 | 23 |
193
+ | `react/recommended` | error | 16 | 7 | 23 |
194
+ | `nextjs` | warn | 16 | 7 | 23 |
195
+ | `nextjs/recommended` | error | 16 | 7 | 23 |
196
+
197
+ ### Base Configuration Rules (16 rules)
198
+
199
+ Included in `base`, `base/recommended`, and all other presets:
200
+
201
+ - `nextfriday/boolean-naming-prefix`
202
+ - `nextfriday/enforce-sorted-destructuring`
203
+ - `nextfriday/file-kebab-case`
204
+ - `nextfriday/md-filename-case-restriction`
205
+ - `nextfriday/no-complex-inline-return`
206
+ - `nextfriday/no-direct-date`
207
+ - `nextfriday/no-emoji`
208
+ - `nextfriday/no-env-fallback`
209
+ - `nextfriday/require-explicit-return-type`
210
+ - `nextfriday/no-logic-in-params`
211
+ - `nextfriday/no-single-char-variables`
212
+ - `nextfriday/prefer-destructuring-params`
213
+ - `nextfriday/prefer-function-declaration`
214
+ - `nextfriday/prefer-import-type`
215
+ - `nextfriday/prefer-named-param-types`
216
+ - `nextfriday/prefer-react-import-types`
217
+
218
+ ### JSX Rules (7 rules)
219
+
220
+ Additionally included in `react`, `react/recommended`, `nextjs`, `nextjs/recommended`:
221
+
222
+ - `nextfriday/enforce-readonly-component-props`
223
+ - `nextfriday/jsx-no-non-component-function`
224
+ - `nextfriday/jsx-no-variable-in-callback`
225
+ - `nextfriday/jsx-pascal-case`
226
+ - `nextfriday/prefer-interface-over-inline-types`
227
+ - `nextfriday/prefer-jsx-template-literals`
228
+ - `nextfriday/react-props-destructure`
229
+
230
+ ### Severity Levels
231
+
232
+ - **`base` / `react` / `nextjs`**: All rules set to `"warn"`
233
+ - **`base/recommended` / `react/recommended` / `nextjs/recommended`**: All rules set to `"error"`
186
234
 
187
235
  ## Features
188
236
 
189
- - **File naming enforcement**: Ensure consistent file naming conventions across your project
237
+ - **Variable naming enforcement**: Prevent cryptic single-character names and enforce boolean prefixes
238
+ - **File naming enforcement**: Ensure consistent file naming conventions (kebab-case, PascalCase, SNAKE_CASE)
239
+ - **Function style**: Enforce function declarations over arrow functions in utility files
190
240
  - **Import optimization**: Automatically suggests better import patterns for TypeScript
191
241
  - **Code cleanup**: Helps remove unnecessary explicit type annotations
192
- - **React component conventions**: Enforces naming standards for JSX/TSX files
193
- - **Clean code practices**: Prevents emoji usage and enforces parameter destructuring
242
+ - **React component conventions**: Enforces naming standards and patterns for JSX/TSX files
243
+ - **Clean code practices**: Prevents emoji usage, enforces parameter destructuring, and more
194
244
 
195
245
  ## Need Help?
196
246
 
@@ -0,0 +1,102 @@
1
+ # boolean-naming-prefix
2
+
3
+ Enforce boolean variables and parameters to have a prefix like is, has, should, can, did, will for better readability.
4
+
5
+ ## Rule Details
6
+
7
+ This rule enforces that boolean variables and parameters use a descriptive prefix that makes them read like English sentences. Variables like `open`, `valid`, `user` are ambiguous - it's unclear whether they represent a value or a state. Boolean prefixes make the intent clear.
8
+
9
+ **Recommended prefixes:** `is`, `has`, `should`, `can`, `did`, `will`, `was`, `are`, `does`, `had`
10
+
11
+ **Incorrect** code for this rule:
12
+
13
+ ```typescript
14
+ const valid = true;
15
+ const user = false;
16
+ const open = true;
17
+ const closed = false;
18
+ const active: boolean = true;
19
+ const enabled: boolean = checkEnabled();
20
+
21
+ const equal = a === b;
22
+ const different = a !== b;
23
+ const bigger = a > b;
24
+ const negated = !value;
25
+ const combined = a && b;
26
+ const either = a || b;
27
+
28
+ function process(active: boolean) {}
29
+ const fn = (enabled: boolean) => {};
30
+ function toggle(active = true) {}
31
+ ```
32
+
33
+ **Correct** code for this rule:
34
+
35
+ ```typescript
36
+ const isValid = true;
37
+ const hasUser = false;
38
+ const isOpen = true;
39
+ const isClosed = false;
40
+ const isActive: boolean = true;
41
+ const isEnabled: boolean = checkEnabled();
42
+
43
+ const isEqual = a === b;
44
+ const isDifferent = a !== b;
45
+ const isBigger = a > b;
46
+ const isNegated = !value;
47
+ const areCombined = a && b;
48
+ const hasEither = a || b;
49
+
50
+ function process(isActive: boolean) {}
51
+ const fn = (hasAccess: boolean) => {};
52
+ function toggle(isActive = true) {}
53
+ ```
54
+
55
+ ## What This Rule Detects
56
+
57
+ The rule identifies boolean variables and parameters by:
58
+
59
+ 1. **Boolean type annotations**: Variables explicitly typed as `boolean`
60
+ 2. **Boolean literals**: Variables initialized with `true` or `false`
61
+ 3. **Comparison expressions**: `===`, `!==`, `==`, `!=`, `<`, `>`, `<=`, `>=`, `in`, `instanceof`
62
+ 4. **Logical expressions**: `&&`, `||`
63
+ 5. **Negation**: `!value`
64
+ 6. **Function parameters**: With boolean type annotation or default boolean value
65
+
66
+ ## Allowed Prefixes
67
+
68
+ | Prefix | Usage | Example |
69
+ | -------- | ----------------------------- | --------------------------------------------- |
70
+ | `is` | State or condition | `isActive`, `isValid`, `isLoading` |
71
+ | `has` | Possession or existence | `hasUser`, `hasPermission`, `hasError` |
72
+ | `can` | Ability or permission | `canSubmit`, `canEdit`, `canDelete` |
73
+ | `should` | Recommendation or expectation | `shouldRender`, `shouldUpdate`, `shouldFetch` |
74
+ | `will` | Future action | `willUpdate`, `willRedirect`, `willExpire` |
75
+ | `did` | Past action | `didLoad`, `didSubmit`, `didFail` |
76
+ | `was` | Past state | `wasActive`, `wasVisible`, `wasProcessed` |
77
+ | `are` | Plural state | `areEqual`, `areValid`, `areLoaded` |
78
+ | `does` | Action capability | `doesExist`, `doesMatch`, `doesContain` |
79
+ | `had` | Past possession | `hadError`, `hadAccess`, `hadPrevious` |
80
+
81
+ ## Benefits
82
+
83
+ - **Self-documenting code**: Boolean intent is immediately clear
84
+ - **Reads like English**: `if (isActive)` reads as "if is active"
85
+ - **Reduced ambiguity**: `user = false` vs `hasUser = false` - the latter is clear
86
+ - **Consistent codebase**: Enforces uniform boolean naming across the project
87
+ - **Better code review**: Reviewers can quickly understand boolean logic
88
+
89
+ ## When Not To Use
90
+
91
+ - When working with external APIs that return boolean fields with different naming conventions
92
+ - In mathematical or scientific code where single-letter variables are conventional
93
+ - When interfacing with legacy code that would require extensive refactoring
94
+
95
+ ## Configuration
96
+
97
+ This rule has no configuration options.
98
+
99
+ ## Related Rules
100
+
101
+ - [no-single-char-variables](./NO_SINGLE_CHAR_VARIABLES.md) - Disallows single character variable names
102
+ - [@typescript-eslint/naming-convention](https://typescript-eslint.io/rules/naming-convention/) - More comprehensive naming convention rule
@@ -0,0 +1,122 @@
1
+ # enforce-sorted-destructuring
2
+
3
+ Enforce alphabetical sorting of destructured properties with defaults first.
4
+
5
+ ## Rule Details
6
+
7
+ This rule enforces that object destructuring properties are sorted alphabetically, with properties that have default values coming first. Default values are further sorted by type (string, number, boolean, object) and then alphabetically within each type.
8
+
9
+ ### Why?
10
+
11
+ 1. **Consistency**: Alphabetical ordering makes code more predictable and easier to scan
12
+ 2. **Readability**: Sorted properties are easier to find in large destructuring statements
13
+ 3. **Organization**: Grouping defaults first keeps the destructuring organized by intent
14
+ 4. **Maintainability**: Clear structure makes it easier to add or remove properties
15
+
16
+ ### Sorting Order
17
+
18
+ Properties are sorted in this order:
19
+
20
+ 1. **Properties with defaults** (sorted by type, then alphabetically):
21
+ - String defaults (alphabetically)
22
+ - Number defaults (alphabetically)
23
+ - Boolean defaults (alphabetically)
24
+ - Object/Array defaults (alphabetically)
25
+ - Other defaults (alphabetically)
26
+
27
+ 2. **Properties without defaults** (alphabetically)
28
+
29
+ ## Examples
30
+
31
+ ### ❌ Incorrect
32
+
33
+ ```js
34
+ // Bad: Not sorted alphabetically
35
+ const { d, b, a, c } = foo;
36
+ ```
37
+
38
+ ```js
39
+ // Bad: Completely unsorted
40
+ const { z, a, m } = foo;
41
+ ```
42
+
43
+ ```js
44
+ // Bad: Default in the middle (should be first)
45
+ const { a, b, d = "string", c } = foo;
46
+ ```
47
+
48
+ ```js
49
+ // Bad: Non-default before defaults
50
+ const { a, d = "string", e = 0 } = foo;
51
+ ```
52
+
53
+ ```js
54
+ // Bad: Defaults not sorted by type (number before string)
55
+ const { e = 0, d = "string", a, b } = foo;
56
+ ```
57
+
58
+ ```js
59
+ // Bad: String defaults not sorted alphabetically
60
+ const { b = "beta", a = "alpha", c } = foo;
61
+ ```
62
+
63
+ ```js
64
+ // Bad: Properties reversed
65
+ const { b, a } = foo;
66
+ ```
67
+
68
+ ### ✅ Correct
69
+
70
+ ```js
71
+ // Good: Alphabetically sorted without defaults
72
+ const { a, b, c, d } = foo;
73
+ ```
74
+
75
+ ```js
76
+ // Good: Defaults first, sorted by type (string, number, boolean), then non-defaults
77
+ const { d = "string", e = 0, f = true, a, b, c } = foo;
78
+ ```
79
+
80
+ ```js
81
+ // Good: String defaults first (sorted alphabetically), then non-defaults
82
+ const { a = "alpha", b = "beta", c, d } = foo;
83
+ ```
84
+
85
+ ```js
86
+ // Good: Number defaults first (sorted alphabetically), then non-defaults
87
+ const { a = 1, b = 2, c, d } = foo;
88
+ ```
89
+
90
+ ```js
91
+ // Good: Boolean defaults first (sorted alphabetically), then non-defaults
92
+ const { a = true, b = false, c, d } = foo;
93
+ ```
94
+
95
+ ```js
96
+ // Good: Object defaults first (sorted alphabetically), then non-defaults
97
+ const { a = {}, b = [], c, d } = foo;
98
+ ```
99
+
100
+ ```js
101
+ // Good: Mixed default types sorted by type order, then non-defaults
102
+ const { name = "default", age = 0, active = true, data = {}, x, y, z } = foo;
103
+ ```
104
+
105
+ ```js
106
+ // Good: All defaults sorted by type and alphabetically
107
+ const { a = "test", b = "value", c = 1, d = 2 } = foo;
108
+ ```
109
+
110
+ ```js
111
+ // Good: With rest element at end
112
+ const { a, b, ...rest } = foo;
113
+ ```
114
+
115
+ ## When Not To Use It
116
+
117
+ If you prefer a different sorting strategy for destructured properties or don't want to enforce any particular order, you can disable this rule.
118
+
119
+ ## Further Reading
120
+
121
+ - [Destructuring Assignment (MDN)](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment)
122
+ - [Default Parameters (MDN)](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Default_parameters)
@@ -0,0 +1,114 @@
1
+ # jsx-no-non-component-function
2
+
3
+ Disallow non-component functions defined at top level in .tsx and .jsx files.
4
+
5
+ ## Rule Details
6
+
7
+ This rule prevents non-component functions from being defined at the top level in `.tsx` and `.jsx` files. These functions should either be:
8
+
9
+ 1. Extracted to separate files and imported
10
+ 2. Defined inside the component function if they are component-specific
11
+
12
+ ### Why?
13
+
14
+ 1. **Better Organization**: Top-level functions in component files can accumulate and make files messy and hard to maintain
15
+ 2. **Proper Separation of Concerns**: Utility/helper functions belong in separate files, not in component files
16
+ 3. **Improved Reusability**: Extracting functions to separate files makes them easier to reuse across components
17
+ 4. **Cleaner Component Files**: Component files should focus on component logic only
18
+
19
+ ## Examples
20
+
21
+ ### ❌ Incorrect
22
+
23
+ ```tsx
24
+ // Bad: Non-component function defined at top level in .tsx file
25
+ const helper = (name: string) => {
26
+ const words = name.trim().split(/\s+/);
27
+ if (words.length === 1) {
28
+ return words[0].charAt(0).toUpperCase();
29
+ }
30
+ return words
31
+ .slice(0, 2)
32
+ .map((word) => word.charAt(0).toUpperCase())
33
+ .join("");
34
+ };
35
+
36
+ const Component = () => {
37
+ return <div>{helper("test")}</div>;
38
+ };
39
+ ```
40
+
41
+ ```tsx
42
+ // Bad: Function declaration at top level
43
+ function formatName(name: string) {
44
+ return name.toUpperCase();
45
+ }
46
+
47
+ const Component = () => {
48
+ return <div>{formatName("test")}</div>;
49
+ };
50
+ ```
51
+
52
+ ```tsx
53
+ // Bad: Non-component function before exported component
54
+ const calculateTotal = (items: number[]) => {
55
+ return items.reduce((sum, item) => sum + item, 0);
56
+ };
57
+
58
+ export const OrderSummary = () => {
59
+ return <div>Total</div>;
60
+ };
61
+ ```
62
+
63
+ ### ✅ Correct
64
+
65
+ ```tsx
66
+ // Good: Function imported from separate file
67
+ import { helper } from "./helper";
68
+
69
+ const Component = () => {
70
+ return <div>{helper("test")}</div>;
71
+ };
72
+ ```
73
+
74
+ ```tsx
75
+ // Good: Function defined inside component
76
+ const Component = () => {
77
+ const helper = (name: string) => {
78
+ return name.toUpperCase();
79
+ };
80
+
81
+ return <div>{helper("test")}</div>;
82
+ };
83
+ ```
84
+
85
+ ```tsx
86
+ // Good: Component only
87
+ const Component = () => {
88
+ return <div>Hello</div>;
89
+ };
90
+ ```
91
+
92
+ ```tsx
93
+ // Good: Functions in .ts or .js files are allowed
94
+ // utils.ts
95
+ export const helper = (name: string) => {
96
+ return name.toUpperCase();
97
+ };
98
+ ```
99
+
100
+ ```tsx
101
+ // Good: Exported component functions are allowed
102
+ export const Component = () => {
103
+ return <div>Hello</div>;
104
+ };
105
+ ```
106
+
107
+ ## When Not To Use It
108
+
109
+ If you prefer to keep utility/helper functions in the same file as your components, you can disable this rule. However, this may lead to less organized code and reduced reusability.
110
+
111
+ ## Further Reading
112
+
113
+ - [React Component File Structure Best Practices](https://react.dev/learn/thinking-in-react)
114
+ - [Separation of Concerns](https://en.wikipedia.org/wiki/Separation_of_concerns)