eslint-plugin-nextfriday 1.0.2 → 1.1.1

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,17 @@
1
1
  # eslint-plugin-nextfriday
2
2
 
3
+ ## 1.1.1
4
+
5
+ ### Patch Changes
6
+
7
+ - [#14](https://github.com/next-friday/eslint-plugin-nextfriday/pull/14) [`de54aaa`](https://github.com/next-friday/eslint-plugin-nextfriday/commit/de54aaa42833ada9d847fe3885ab98b82e0590e9) Thanks [@nextfridaydeveloper](https://github.com/nextfridaydeveloper)! - Improved type checking logic across ESLint rules to enhance accuracy and reliability. This refactor focuses on better type inference, more precise type guards, and improved handling of edge cases in rule implementations.
8
+
9
+ ## 1.1.0
10
+
11
+ ### Minor Changes
12
+
13
+ - [#12](https://github.com/next-friday/eslint-plugin-nextfriday/pull/12) [`30dc89f`](https://github.com/next-friday/eslint-plugin-nextfriday/commit/30dc89f3c4d11c9cb320b8c3dfa370b7caff9ddc) Thanks [@nextfridaydeveloper](https://github.com/nextfridaydeveloper)! - Added two new ESLint rules to improve React development practices and code quality. The `prefer-react-import-types` rule enforces direct import of React types, while `prefer-interface-over-inline-types` promotes better type organization. Also improved the React component detection logic in the existing `react-props-destructure` rule.
14
+
3
15
  ## 1.0.2
4
16
 
5
17
  ### Patch Changes
package/README.md CHANGED
@@ -59,23 +59,24 @@ export default [
59
59
  nextfriday,
60
60
  },
61
61
  rules: {
62
- // Base rules (suitable for all projects)
63
62
  "nextfriday/no-emoji": "error",
64
63
  "nextfriday/file-kebab-case": "error",
65
64
  "nextfriday/md-filename-case-restriction": "error",
66
65
  "nextfriday/prefer-destructuring-params": "error",
67
66
  "nextfriday/no-explicit-return-type": "error",
68
67
  "nextfriday/prefer-import-type": "error",
69
- // JSX rule (only for React/Next.js projects)
68
+ "nextfriday/prefer-react-import-types": "error",
70
69
  "nextfriday/jsx-pascal-case": "error",
70
+ "nextfriday/prefer-interface-over-inline-types": "error",
71
+ "nextfriday/react-props-destructure": "error",
71
72
  },
72
73
  },
73
74
  ];
74
75
  ```
75
76
 
76
- ### Legacy Config
77
+ ### Legacy Config (ESLint 8 and below)
77
78
 
78
- #### Base Configuration
79
+ #### Base Legacy Configuration
79
80
 
80
81
  ```js
81
82
  module.exports = {
@@ -84,7 +85,7 @@ module.exports = {
84
85
  };
85
86
  ```
86
87
 
87
- #### React Configuration
88
+ #### React Legacy Configuration
88
89
 
89
90
  ```js
90
91
  module.exports = {
@@ -93,7 +94,7 @@ module.exports = {
93
94
  };
94
95
  ```
95
96
 
96
- #### Next.js Configuration
97
+ #### Next.js Legacy Configuration
97
98
 
98
99
  ```js
99
100
  module.exports = {
@@ -104,15 +105,18 @@ module.exports = {
104
105
 
105
106
  ## Rules
106
107
 
107
- | Rule | Description | Fixable |
108
- | -------------------------------------------------------------------------- | ------------------------------------------------------------ | ------- |
109
- | [no-emoji](docs/rules/NO_EMOJI.md) | Disallow emojis in code | ❌ |
110
- | [file-kebab-case](docs/rules/FILE_KEBAB_CASE.md) | Enforce kebab-case filenames for .ts and .js files | ❌ |
111
- | [jsx-pascal-case](docs/rules/JSX_PASCAL_CASE.md) | Enforce PascalCase filenames for .jsx and .tsx files | ❌ |
112
- | [md-filename-case-restriction](docs/rules/MD_FILENAME_CASE_RESTRICTION.md) | Enforce SNAKE_CASE filenames for .md files | ❌ |
113
- | [prefer-destructuring-params](docs/rules/PREFER_DESTRUCTURING_PARAMS.md) | Enforce destructuring for functions with multiple parameters | ❌ |
114
- | [no-explicit-return-type](docs/rules/NO_EXPLICIT_RETURN_TYPE.md) | Disallow explicit return types on functions | ✅ |
115
- | [prefer-import-type](docs/rules/PREFER_IMPORT_TYPE.md) | Enforce using 'import type' for type-only imports | ✅ |
108
+ | Rule | Description | Fixable |
109
+ | -------------------------------------------------------------------------------------- | ---------------------------------------------------------------- | ------- |
110
+ | [no-emoji](docs/rules/NO_EMOJI.md) | Disallow emojis in code | ❌ |
111
+ | [file-kebab-case](docs/rules/FILE_KEBAB_CASE.md) | Enforce kebab-case filenames for .ts and .js files | ❌ |
112
+ | [jsx-pascal-case](docs/rules/JSX_PASCAL_CASE.md) | Enforce PascalCase filenames for .jsx and .tsx files | ❌ |
113
+ | [md-filename-case-restriction](docs/rules/MD_FILENAME_CASE_RESTRICTION.md) | Enforce SNAKE_CASE filenames for .md files | ❌ |
114
+ | [prefer-destructuring-params](docs/rules/PREFER_DESTRUCTURING_PARAMS.md) | Enforce destructuring for functions with multiple parameters | ❌ |
115
+ | [no-explicit-return-type](docs/rules/NO_EXPLICIT_RETURN_TYPE.md) | Disallow explicit return types on functions | ✅ |
116
+ | [prefer-import-type](docs/rules/PREFER_IMPORT_TYPE.md) | Enforce using 'import type' for type-only imports | ✅ |
117
+ | [prefer-interface-over-inline-types](docs/rules/PREFER_INTERFACE_OVER_INLINE_TYPES.md) | Enforce interface declarations over inline types for React props | ❌ |
118
+ | [prefer-react-import-types](docs/rules/PREFER_REACT_IMPORT_TYPES.md) | Enforce direct imports from 'react' instead of React.X | ✅ |
119
+ | [react-props-destructure](docs/rules/REACT_PROPS_DESTRUCTURE.md) | Enforce destructuring props inside React component body | ❌ |
116
120
 
117
121
  ## Configurations
118
122
 
@@ -128,6 +132,7 @@ Basic configuration without JSX-specific rules:
128
132
  - `nextfriday/prefer-destructuring-params`: `"error"`
129
133
  - `nextfriday/no-explicit-return-type`: `"error"`
130
134
  - `nextfriday/prefer-import-type`: `"error"`
135
+ - `nextfriday/prefer-react-import-types`: `"error"`
131
136
 
132
137
  #### `base/recommended`
133
138
 
@@ -141,6 +146,8 @@ Includes all base rules plus React-specific rules:
141
146
 
142
147
  - All base rules above
143
148
  - `nextfriday/jsx-pascal-case`: `"error"`
149
+ - `nextfriday/prefer-interface-over-inline-types`: `"error"`
150
+ - `nextfriday/react-props-destructure`: `"error"`
144
151
 
145
152
  #### `react/recommended`
146
153
 
@@ -154,6 +161,8 @@ Includes all rules suitable for Next.js projects:
154
161
 
155
162
  - All base rules
156
163
  - `nextfriday/jsx-pascal-case`: `"error"`
164
+ - `nextfriday/prefer-interface-over-inline-types`: `"error"`
165
+ - `nextfriday/react-props-destructure`: `"error"`
157
166
 
158
167
  #### `nextjs/recommended`
159
168
 
@@ -0,0 +1,211 @@
1
+ # prefer-interface-over-inline-types
2
+
3
+ Enforce interface declarations over inline type annotations for React component props.
4
+
5
+ ## Rule Details
6
+
7
+ This rule enforces the use of interface declarations instead of inline type annotations for React component props when the type is complex. This promotes better code organization, reusability, and readability.
8
+
9
+ Examples of **incorrect** code for this rule:
10
+
11
+ ```tsx
12
+ // More than 2 properties - should use interface
13
+ const Component = (props: { children: ReactNode; title: string; onClick: () => void }) => (
14
+ <div onClick={props.onClick}>
15
+ <h1>{props.title}</h1>
16
+ {props.children}
17
+ </div>
18
+ );
19
+
20
+ // Nested object types - should use interface
21
+ const Component = (props: { user: { name: string; age: number }; isActive: boolean }) => <div>{props.user.name}</div>;
22
+
23
+ // Array types - should use interface
24
+ const Component = (props: { items: string[]; title: string }) => (
25
+ <div>
26
+ <h1>{props.title}</h1>
27
+ {props.items.map((item) => (
28
+ <span key={item}>{item}</span>
29
+ ))}
30
+ </div>
31
+ );
32
+
33
+ // Union types - should use interface
34
+ const Component = (props: { status: "loading" | "success" | "error"; message: string }) => (
35
+ <div className={props.status}>{props.message}</div>
36
+ );
37
+
38
+ // Function declarations
39
+ function Component(props: { data: { id: number; name: string }; isVisible: boolean }) {
40
+ return <div>{props.data.name}</div>;
41
+ }
42
+
43
+ // Function expressions
44
+ const Component = function (props: { config: { theme: string; lang: string }; children: ReactNode }) {
45
+ return <div className={props.config.theme}>{props.children}</div>;
46
+ };
47
+ ```
48
+
49
+ Examples of **correct** code for this rule:
50
+
51
+ ```tsx
52
+ // Using interface for complex props
53
+ interface ComponentProps {
54
+ children: ReactNode;
55
+ title: string;
56
+ onClick: () => void;
57
+ }
58
+
59
+ const Component = (props: ComponentProps) => (
60
+ <div onClick={props.onClick}>
61
+ <h1>{props.title}</h1>
62
+ {props.children}
63
+ </div>
64
+ );
65
+
66
+ // Using interface for nested objects
67
+ interface UserComponentProps {
68
+ user: {
69
+ name: string;
70
+ age: number;
71
+ };
72
+ isActive: boolean;
73
+ }
74
+
75
+ const Component = (props: UserComponentProps) => <div>{props.user.name}</div>;
76
+
77
+ // Using type alias is also acceptable
78
+ type ListComponentProps = {
79
+ items: string[];
80
+ title: string;
81
+ };
82
+
83
+ const Component = (props: ListComponentProps) => (
84
+ <div>
85
+ <h1>{props.title}</h1>
86
+ {props.items.map((item) => (
87
+ <span key={item}>{item}</span>
88
+ ))}
89
+ </div>
90
+ );
91
+
92
+ // Simple inline types are allowed (2 or fewer properties, no complex types)
93
+ const Component = (props: { children: ReactNode }) => <div>{props.children}</div>;
94
+
95
+ const Component = (props: { title: string; onClick: () => void }) => <div onClick={props.onClick}>{props.title}</div>;
96
+
97
+ // Non-React functions are ignored
98
+ const helper = (props: { value: number; name: string; data: object }) => {
99
+ return props.value + props.name.length;
100
+ };
101
+
102
+ // Functions with no parameters
103
+ const Component = () => <div>Hello</div>;
104
+
105
+ // Functions with multiple parameters
106
+ const Component = (props: { title: string }, ref: any) => <div>{props.title}</div>;
107
+ ```
108
+
109
+ ## Why?
110
+
111
+ ### Benefits of interface declarations:
112
+
113
+ 1. **Reusability**: Interfaces can be reused across multiple components
114
+ 2. **Better organization**: Separates type definitions from component logic
115
+ 3. **Improved readability**: Makes component signatures cleaner and easier to understand
116
+ 4. **Better IDE support**: Enhanced autocomplete, refactoring, and navigation
117
+ 5. **Documentation**: Interfaces serve as clear documentation of component APIs
118
+ 6. **Extensibility**: Interfaces can be extended and composed more easily
119
+
120
+ ## Rule Scope
121
+
122
+ This rule applies to:
123
+
124
+ - React functional components (arrow functions, function expressions, function declarations)
125
+ - Functions that return JSX elements or fragments
126
+ - Props with inline type annotations that meet complexity criteria
127
+
128
+ **Complexity criteria:**
129
+
130
+ - More than 2 properties in the type literal
131
+ - Contains nested object types (`{ user: { name: string } }`)
132
+ - Contains array types (`string[]`, `Array<T>`)
133
+ - Contains union types (`'a' | 'b' | 'c'`)
134
+
135
+ The rule ignores:
136
+
137
+ - Non-React functions (functions that don't return JSX)
138
+ - Functions with multiple parameters
139
+ - Functions with no parameters
140
+ - Simple inline types (2 or fewer properties with primitive types)
141
+ - Components already using named types or interfaces
142
+
143
+ ## When Not To Use It
144
+
145
+ This rule should not be used if you:
146
+
147
+ - Prefer inline types for consistency across your codebase
148
+ - Are working with very simple components that don't benefit from interface extraction
149
+ - Have specific naming conventions that conflict with interface declarations
150
+ - Are maintaining legacy code with established patterns
151
+
152
+ ## Configuration
153
+
154
+ This rule is included in the following configurations:
155
+
156
+ - `nextfriday/react`
157
+ - `nextfriday/react/recommended`
158
+ - `nextfriday/nextjs`
159
+ - `nextfriday/nextjs/recommended`
160
+
161
+ To enable this rule manually:
162
+
163
+ ```json
164
+ {
165
+ "rules": {
166
+ "nextfriday/prefer-interface-over-inline-types": "error"
167
+ }
168
+ }
169
+ ```
170
+
171
+ ## Examples of Complexity Detection
172
+
173
+ ### Simple types (allowed as inline)
174
+
175
+ ```tsx
176
+ // ✅ Simple - only 1 property
177
+ const Component = (props: { children: ReactNode }) => <div>{props.children}</div>;
178
+
179
+ // ✅ Simple - only 2 properties with primitive types
180
+ const Component = (props: { title: string; count: number }) => (
181
+ <div>
182
+ {props.title}: {props.count}
183
+ </div>
184
+ );
185
+ ```
186
+
187
+ ### Complex types (should use interface)
188
+
189
+ ```tsx
190
+ // ❌ Complex - more than 2 properties
191
+ const Component = (props: { title: string; count: number; isActive: boolean }) => <div>...</div>;
192
+
193
+ // ❌ Complex - nested object
194
+ const Component = (props: { user: { name: string }; isActive: boolean }) => <div>...</div>;
195
+
196
+ // ❌ Complex - array type
197
+ const Component = (props: { items: string[]; title: string }) => <div>...</div>;
198
+
199
+ // ❌ Complex - union type
200
+ const Component = (props: { status: "loading" | "success"; message: string }) => <div>...</div>;
201
+ ```
202
+
203
+ ## Compatibility
204
+
205
+ - React 16.8+ (functional components)
206
+ - TypeScript 3.0+ (interface declarations)
207
+ - ESLint 9+ with flat config
208
+
209
+ ## Version
210
+
211
+ This rule was introduced in eslint-plugin-nextfriday v1.2.0.
@@ -0,0 +1,175 @@
1
+ # prefer-react-import-types
2
+
3
+ Enforce importing React types and utilities from 'react' instead of using React.X notation.
4
+
5
+ ## Rule Details
6
+
7
+ This rule enforces direct imports of React types and utilities instead of using the React namespace notation (`React.ReactNode`, `React.useState`, etc.). This promotes cleaner imports and better tree-shaking in modern bundlers.
8
+
9
+ Examples of **incorrect** code for this rule:
10
+
11
+ ```tsx
12
+ // Types with React namespace
13
+ const Component = (props: { children: React.ReactNode }) => <div>{props.children}</div>;
14
+
15
+ interface Props {
16
+ title: React.ReactElement;
17
+ onClick: React.MouseEventHandler;
18
+ }
19
+
20
+ const MyComponent: React.FC<Props> = ({ title, onClick }) => <div onClick={onClick}>{title}</div>;
21
+
22
+ // Hooks with React namespace
23
+ const Component = () => {
24
+ const [state, setState] = React.useState(0);
25
+ const value = React.useMemo(() => state * 2, [state]);
26
+ const ref = React.useRef<HTMLDivElement>(null);
27
+
28
+ React.useEffect(() => {
29
+ console.log("mounted");
30
+ }, []);
31
+
32
+ return <div ref={ref}>{value}</div>;
33
+ };
34
+
35
+ // Utilities with React namespace
36
+ const element = React.createElement("div", null, "Hello");
37
+ const MemoizedComponent = React.memo(() => <div>Hello</div>);
38
+ const LazyComponent = React.lazy(() => import("./Component"));
39
+
40
+ const MyFragment = () => (
41
+ <React.Fragment>
42
+ <div>Item 1</div>
43
+ <div>Item 2</div>
44
+ </React.Fragment>
45
+ );
46
+ ```
47
+
48
+ Examples of **correct** code for this rule:
49
+
50
+ ```tsx
51
+ // Direct type imports
52
+ import type { ReactNode, ReactElement, MouseEventHandler, FC } from "react";
53
+
54
+ const Component = (props: { children: ReactNode }) => <div>{props.children}</div>;
55
+
56
+ interface Props {
57
+ title: ReactElement;
58
+ onClick: MouseEventHandler;
59
+ }
60
+
61
+ const MyComponent: FC<Props> = ({ title, onClick }) => <div onClick={onClick}>{title}</div>;
62
+
63
+ // Direct hook imports
64
+ import { useState, useMemo, useRef, useEffect } from "react";
65
+
66
+ const Component = () => {
67
+ const [state, setState] = useState(0);
68
+ const value = useMemo(() => state * 2, [state]);
69
+ const ref = useRef<HTMLDivElement>(null);
70
+
71
+ useEffect(() => {
72
+ console.log("mounted");
73
+ }, []);
74
+
75
+ return <div ref={ref}>{value}</div>;
76
+ };
77
+
78
+ // Direct utility imports
79
+ import { createElement, memo, lazy, Fragment } from "react";
80
+
81
+ const element = createElement("div", null, "Hello");
82
+ const MemoizedComponent = memo(() => <div>Hello</div>);
83
+ const LazyComponent = lazy(() => import("./Component"));
84
+
85
+ const MyFragment = () => (
86
+ <Fragment>
87
+ <div>Item 1</div>
88
+ <div>Item 2</div>
89
+ </Fragment>
90
+ );
91
+ ```
92
+
93
+ ## Why?
94
+
95
+ ### Benefits of direct imports
96
+
97
+ 1. **Better tree-shaking**: Bundlers can more easily eliminate unused code when imports are explicit
98
+ 2. **Cleaner code**: Reduces namespace pollution and makes dependencies more explicit
99
+ 3. **Improved IDE support**: Better autocomplete and refactoring capabilities
100
+ 4. **Smaller bundle sizes**: Only import what you actually use
101
+ 5. **TypeScript optimization**: Better type checking and inference with explicit imports
102
+ 6. **Modern practices**: Aligns with current React ecosystem conventions
103
+
104
+ ## Automatic Fixing
105
+
106
+ This rule provides automatic fixing that replaces `React.X` with the direct import name. However, you will need to manually add the appropriate import statements:
107
+
108
+ - **Types**: Use `import type { TypeName } from "react"`
109
+ - **Runtime code**: Use `import { functionName } from "react"`
110
+
111
+ ## Supported React Exports
112
+
113
+ ### Types (use `import type`)
114
+
115
+ - `ReactNode`, `ReactElement`, `ReactChildren`, `ReactChild`
116
+ - `ComponentType`, `FC`, `FunctionComponent`, `Component`, `PureComponent`
117
+ - Event handlers: `ReactEventHandler`, `MouseEventHandler`, `ChangeEventHandler`, etc.
118
+ - Refs: `RefObject`, `MutableRefObject`, `Ref`, `ForwardedRef`
119
+ - Props: `HTMLProps`, `ComponentProps`
120
+ - `JSXElementConstructor`
121
+
122
+ ### Runtime Exports (use `import`)
123
+
124
+ #### Hooks
125
+
126
+ - `useState`, `useEffect`, `useContext`, `useReducer`
127
+ - `useCallback`, `useMemo`, `useRef`, `useImperativeHandle`
128
+ - `useLayoutEffect`, `useDebugValue`, `useDeferredValue`
129
+ - `useTransition`, `useId`, `useSyncExternalStore`, `useInsertionEffect`
130
+
131
+ #### Utilities
132
+
133
+ - `createElement`, `createContext`, `forwardRef`, `memo`, `lazy`
134
+ - `Suspense`, `Fragment`, `StrictMode`, `createRef`
135
+ - `isValidElement`, `cloneElement`, `Children`
136
+
137
+ ## When Not To Use It
138
+
139
+ This rule should not be used if you:
140
+
141
+ - Prefer the React namespace for consistency across a large codebase
142
+ - Are working with legacy code that heavily uses React namespace
143
+ - Need to maintain compatibility with older bundlers that don't support tree-shaking
144
+
145
+ ## Configuration
146
+
147
+ This rule is included in the following configurations:
148
+
149
+ - `nextfriday/base`
150
+ - `nextfriday/base/recommended`
151
+ - `nextfriday/react`
152
+ - `nextfriday/react/recommended`
153
+ - `nextfriday/nextjs`
154
+ - `nextfriday/nextjs/recommended`
155
+
156
+ To enable this rule manually:
157
+
158
+ ```json
159
+ {
160
+ "rules": {
161
+ "nextfriday/prefer-react-import-types": "error"
162
+ }
163
+ }
164
+ ```
165
+
166
+ ## Compatibility
167
+
168
+ - React 16.8+ (hooks support)
169
+ - TypeScript 3.8+ (type-only imports)
170
+ - Modern bundlers with tree-shaking support
171
+ - ESLint 9+ with flat config
172
+
173
+ ## Version
174
+
175
+ This rule was introduced in eslint-plugin-nextfriday v1.1.0.
@@ -0,0 +1,158 @@
1
+ # react-props-destructure
2
+
3
+ Enforce destructuring props inside React component body instead of parameters.
4
+
5
+ ## Rule Details
6
+
7
+ This rule enforces a consistent pattern for handling props in React components by requiring destructuring to be done inside the component body rather than in the parameter list. This promotes better code readability and makes prop usage more explicit.
8
+
9
+ Examples of **incorrect** code for this rule:
10
+
11
+ ```jsx
12
+ const Component = ({ children }) => <div>{children}</div>;
13
+
14
+ const Component = ({ title, children, onClick }) => (
15
+ <div onClick={onClick}>
16
+ <h1>{title}</h1>
17
+ {children}
18
+ </div>
19
+ );
20
+
21
+ function Component({ children }) {
22
+ return <div>{children}</div>;
23
+ }
24
+
25
+ const Component = function ({ children }) {
26
+ return <div>{children}</div>;
27
+ };
28
+
29
+ // Also applies to conditional returns
30
+ const Component = ({ show, children }) => {
31
+ return show ? <div>{children}</div> : null;
32
+ };
33
+
34
+ // And logical operators
35
+ const Component = ({ show, children }) => {
36
+ return show && <div>{children}</div>;
37
+ };
38
+ ```
39
+
40
+ Examples of **correct** code for this rule:
41
+
42
+ ```jsx
43
+ const Component = (props) => {
44
+ const { children } = props;
45
+ return <div>{children}</div>;
46
+ };
47
+
48
+ const Component = (props) => {
49
+ const { title, children, onClick } = props;
50
+
51
+ return (
52
+ <div onClick={onClick}>
53
+ <h1>{title}</h1>
54
+ {children}
55
+ </div>
56
+ );
57
+ };
58
+
59
+ function Component(props) {
60
+ const { children } = props;
61
+ return <div>{children}</div>;
62
+ }
63
+
64
+ const Component = function (props) {
65
+ const { children } = props;
66
+ return <div>{children}</div>;
67
+ };
68
+
69
+ // Multiple parameters are allowed
70
+ const Component = (props, ref) => {
71
+ return <div>{props.children}</div>;
72
+ };
73
+
74
+ // No parameters is allowed
75
+ const Component = () => {
76
+ return <div>Hello</div>;
77
+ };
78
+
79
+ // Already using props parameter (no destructuring) is allowed
80
+ const Component = (props) => {
81
+ return <div>{props.children}</div>;
82
+ };
83
+
84
+ // Non-React functions are ignored
85
+ const helper = ({ value }) => {
86
+ return value * 2;
87
+ };
88
+
89
+ const regularFunction = ({ data }) => {
90
+ return data.map((item) => item.id);
91
+ };
92
+ ```
93
+
94
+ ## Why?
95
+
96
+ ### Benefits of destructuring inside component body
97
+
98
+ 1. **Explicit prop usage**: Makes it clear which props are being used within the component
99
+ 2. **Better readability**: Separates prop extraction from component signature
100
+ 3. **Easier refactoring**: Props can be easily modified without changing the function signature
101
+ 4. **Consistent patterns**: Promotes a uniform approach across the codebase
102
+ 5. **Better TypeScript integration**: Works better with prop type definitions
103
+
104
+ ## When Not To Use It
105
+
106
+ This rule should not be used if you:
107
+
108
+ - Prefer parameter destructuring for brevity
109
+ - Are working on a codebase that already consistently uses parameter destructuring
110
+ - Need to maintain compatibility with existing patterns
111
+
112
+ ## Rule Scope
113
+
114
+ This rule only applies to:
115
+
116
+ - Functions that return JSX elements or fragments
117
+ - Functions with exactly one parameter that is object destructuring
118
+ - Arrow functions, function expressions, and function declarations
119
+
120
+ The rule ignores:
121
+
122
+ - Non-React functions (functions that don't return JSX)
123
+ - Functions with multiple parameters
124
+ - Functions with no parameters
125
+ - Functions already using a `props` parameter without destructuring
126
+
127
+ ## Configuration
128
+
129
+ This rule is included in the following configurations:
130
+
131
+ - `nextfriday/react`
132
+ - `nextfriday/react/recommended`
133
+ - `nextfriday/nextjs`
134
+ - `nextfriday/nextjs/recommended`
135
+
136
+ To enable this rule manually:
137
+
138
+ ```json
139
+ {
140
+ "rules": {
141
+ "nextfriday/react-props-destructure": "error"
142
+ }
143
+ }
144
+ ```
145
+
146
+ ## Compatibility
147
+
148
+ - React functional components
149
+ - Arrow functions with JSX
150
+ - Function declarations with JSX
151
+ - Function expressions with JSX
152
+ - Conditional JSX returns
153
+ - Logical operator JSX returns
154
+ - JSX fragments
155
+
156
+ ## Version
157
+
158
+ This rule was introduced in eslint-plugin-nextfriday v1.0.0.