eslint-plugin-nextfriday 1.5.3 → 1.6.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 +9 -0
- package/README.md +4 -0
- package/docs/rules/ENFORCE_SORTED_DESTRUCTURING.md +122 -0
- package/docs/rules/JSX_NO_NON_COMPONENT_FUNCTION.md +114 -0
- package/docs/rules/JSX_NO_VARIABLE_IN_CALLBACK.md +144 -0
- package/docs/rules/PREFER_JSX_TEMPLATE_LITERALS.md +78 -0
- package/lib/index.cjs +577 -127
- package/lib/index.cjs.map +1 -1
- package/lib/index.d.cts +56 -0
- package/lib/index.d.ts +56 -0
- package/lib/index.js +577 -127
- package/lib/index.js.map +1 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,14 @@
|
|
|
1
1
|
# eslint-plugin-nextfriday
|
|
2
2
|
|
|
3
|
+
## 1.6.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- [#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:
|
|
8
|
+
- `jsx-no-non-component-function`: Prevent non-component functions at top level in .tsx/.jsx files
|
|
9
|
+
- `enforce-sorted-destructuring`: Enforce alphabetical sorting of destructured properties with defaults first
|
|
10
|
+
- `jsx-no-variable-in-callback`: Prevent variable declarations inside JSX callbacks for cleaner code
|
|
11
|
+
|
|
3
12
|
## 1.5.3
|
|
4
13
|
|
|
5
14
|
### Patch Changes
|
package/README.md
CHANGED
|
@@ -118,12 +118,16 @@ module.exports = {
|
|
|
118
118
|
| [md-filename-case-restriction](docs/rules/MD_FILENAME_CASE_RESTRICTION.md) | Enforce SNAKE_CASE filenames for .md files | ❌ |
|
|
119
119
|
| [prefer-destructuring-params](docs/rules/PREFER_DESTRUCTURING_PARAMS.md) | Enforce destructuring for functions with multiple parameters | ❌ |
|
|
120
120
|
| [no-explicit-return-type](docs/rules/NO_EXPLICIT_RETURN_TYPE.md) | Disallow explicit return types on functions | ✅ |
|
|
121
|
+
| [jsx-no-non-component-function](docs/rules/JSX_NO_NON_COMPONENT_FUNCTION.md) | Disallow non-component functions at top level in .tsx and .jsx files | ❌ |
|
|
122
|
+
| [jsx-no-variable-in-callback](docs/rules/JSX_NO_VARIABLE_IN_CALLBACK.md) | Disallow variable declarations inside callback functions within JSX | ❌ |
|
|
121
123
|
| [prefer-import-type](docs/rules/PREFER_IMPORT_TYPE.md) | Enforce using 'import type' for type-only imports | ✅ |
|
|
122
124
|
| [prefer-named-param-types](docs/rules/PREFER_NAMED_PARAM_TYPES.md) | Enforce named types for function parameters with object types | ❌ |
|
|
123
125
|
| [prefer-interface-over-inline-types](docs/rules/PREFER_INTERFACE_OVER_INLINE_TYPES.md) | Enforce interface declarations over inline types for React props | ❌ |
|
|
126
|
+
| [prefer-jsx-template-literals](docs/rules/PREFER_JSX_TEMPLATE_LITERALS.md) | Enforce using template literals instead of mixing text and JSX expressions | ✅ |
|
|
124
127
|
| [prefer-react-import-types](docs/rules/PREFER_REACT_IMPORT_TYPES.md) | Enforce direct imports from 'react' instead of React.X | ✅ |
|
|
125
128
|
| [react-props-destructure](docs/rules/REACT_PROPS_DESTRUCTURE.md) | Enforce destructuring props inside React component body | ❌ |
|
|
126
129
|
| [enforce-readonly-component-props](docs/rules/ENFORCE_READONLY_COMPONENT_PROPS.md) | Enforce Readonly wrapper for React component props | ✅ |
|
|
130
|
+
| [enforce-sorted-destructuring](docs/rules/ENFORCE_SORTED_DESTRUCTURING.md) | Enforce alphabetical sorting of destructured properties with defaults first | ❌ |
|
|
127
131
|
| [no-complex-inline-return](docs/rules/NO_COMPLEX_INLINE_RETURN.md) | Disallow complex inline expressions in return statements - prefer const first | ❌ |
|
|
128
132
|
| [no-logic-in-params](docs/rules/NO_LOGIC_IN_PARAMS.md) | Disallow logic or conditions in function parameters - extract to const first | ❌ |
|
|
129
133
|
| [no-env-fallback](docs/rules/NO_ENV_FALLBACK.md) | Disallow fallback values for environment variables as they can be dangerous | ❌ |
|
|
@@ -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)
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
# jsx-no-variable-in-callback
|
|
2
|
+
|
|
3
|
+
Disallow variable declarations inside callback functions within JSX.
|
|
4
|
+
|
|
5
|
+
## Rule Details
|
|
6
|
+
|
|
7
|
+
This rule prevents variable declarations inside callback functions that are directly used within JSX expressions. This enforces cleaner, more maintainable code by extracting complex logic to separate functions.
|
|
8
|
+
|
|
9
|
+
### Why?
|
|
10
|
+
|
|
11
|
+
1. **Readability**: Keeps JSX clean and focused on rendering, not logic
|
|
12
|
+
2. **Maintainability**: Extracted functions are easier to test and modify
|
|
13
|
+
3. **Separation of Concerns**: Logic belongs in functions, not inline in JSX
|
|
14
|
+
4. **Consistency**: Enforces a uniform pattern across the codebase
|
|
15
|
+
|
|
16
|
+
## Examples
|
|
17
|
+
|
|
18
|
+
### ❌ Incorrect
|
|
19
|
+
|
|
20
|
+
```tsx
|
|
21
|
+
// Bad: Variable declared inside map callback in JSX
|
|
22
|
+
const UserList = ({ users }) => {
|
|
23
|
+
return (
|
|
24
|
+
<div>
|
|
25
|
+
{users.map((user) => {
|
|
26
|
+
const displayName = user.firstName + " " + user.lastName;
|
|
27
|
+
return <div key={user.id}>{displayName}</div>;
|
|
28
|
+
})}
|
|
29
|
+
</div>
|
|
30
|
+
);
|
|
31
|
+
};
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
```tsx
|
|
35
|
+
// Bad: Variable in filter callback
|
|
36
|
+
const ProductList = ({ products }) => {
|
|
37
|
+
return (
|
|
38
|
+
<ul>
|
|
39
|
+
{products.filter((product) => {
|
|
40
|
+
const isAvailable = product.stock > 0 && product.active;
|
|
41
|
+
return isAvailable;
|
|
42
|
+
})}
|
|
43
|
+
</ul>
|
|
44
|
+
);
|
|
45
|
+
};
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
```tsx
|
|
49
|
+
// Bad: Multiple variables in callback
|
|
50
|
+
const OrderSummary = ({ orders }) => {
|
|
51
|
+
return (
|
|
52
|
+
<div>
|
|
53
|
+
{orders.map((order) => {
|
|
54
|
+
const total = order.price * order.quantity;
|
|
55
|
+
const discount = total * 0.1;
|
|
56
|
+
const final = total - discount;
|
|
57
|
+
return <div key={order.id}>{final}</div>;
|
|
58
|
+
})}
|
|
59
|
+
</div>
|
|
60
|
+
);
|
|
61
|
+
};
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
### ✅ Correct
|
|
65
|
+
|
|
66
|
+
```tsx
|
|
67
|
+
// Good: Extract logic to a separate function
|
|
68
|
+
const UserList = ({ users }) => {
|
|
69
|
+
const renderUsers = () =>
|
|
70
|
+
users.map((user) => {
|
|
71
|
+
const displayName = user.firstName + " " + user.lastName;
|
|
72
|
+
return <div key={user.id}>{displayName}</div>;
|
|
73
|
+
});
|
|
74
|
+
|
|
75
|
+
return <div>{renderUsers()}</div>;
|
|
76
|
+
};
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
```tsx
|
|
80
|
+
// Good: Use helper function outside JSX
|
|
81
|
+
const ProductList = ({ products }) => {
|
|
82
|
+
const isProductAvailable = (product) => {
|
|
83
|
+
const isAvailable = product.stock > 0 && product.active;
|
|
84
|
+
return isAvailable;
|
|
85
|
+
};
|
|
86
|
+
|
|
87
|
+
return <ul>{products.filter(isProductAvailable)}</ul>;
|
|
88
|
+
};
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
```tsx
|
|
92
|
+
// Good: No variable declaration in callback
|
|
93
|
+
const UserList = ({ users }) => {
|
|
94
|
+
return (
|
|
95
|
+
<div>
|
|
96
|
+
{users.map((user) => (
|
|
97
|
+
<div key={user.id}>
|
|
98
|
+
{user.firstName} {user.lastName}
|
|
99
|
+
</div>
|
|
100
|
+
))}
|
|
101
|
+
</div>
|
|
102
|
+
);
|
|
103
|
+
};
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
```tsx
|
|
107
|
+
// Good: Variable declared outside JSX
|
|
108
|
+
const OrderSummary = ({ orders }) => {
|
|
109
|
+
const discount = 0.1;
|
|
110
|
+
|
|
111
|
+
return (
|
|
112
|
+
<div>
|
|
113
|
+
{orders.map((order) => {
|
|
114
|
+
const total = order.price * order.quantity;
|
|
115
|
+
return <div key={order.id}>{total - total * discount}</div>;
|
|
116
|
+
})}
|
|
117
|
+
</div>
|
|
118
|
+
);
|
|
119
|
+
};
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
```tsx
|
|
123
|
+
// Good: Extract rendering to a function
|
|
124
|
+
const OrderSummary = ({ orders }) => {
|
|
125
|
+
const calculateFinalPrice = (order) => {
|
|
126
|
+
const total = order.price * order.quantity;
|
|
127
|
+
const discount = total * 0.1;
|
|
128
|
+
return total - discount;
|
|
129
|
+
};
|
|
130
|
+
|
|
131
|
+
const renderOrders = () => orders.map((order) => <div key={order.id}>{calculateFinalPrice(order)}</div>);
|
|
132
|
+
|
|
133
|
+
return <div>{renderOrders()}</div>;
|
|
134
|
+
};
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
## When Not To Use It
|
|
138
|
+
|
|
139
|
+
If you prefer keeping all logic inline within JSX callbacks and don't mind the reduced readability, you can disable this rule. However, this is generally not recommended as it leads to harder-to-maintain code.
|
|
140
|
+
|
|
141
|
+
## Further Reading
|
|
142
|
+
|
|
143
|
+
- [React Component Best Practices](https://react.dev/learn/keeping-components-pure)
|
|
144
|
+
- [Clean Code Principles](https://clean-code-developer.com/)
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
# prefer-jsx-template-literals
|
|
2
|
+
|
|
3
|
+
Enforce using template literals instead of mixing text and JSX expressions.
|
|
4
|
+
|
|
5
|
+
## Rule Details
|
|
6
|
+
|
|
7
|
+
This rule prevents mixing plain text with JSX expressions in JSX elements, which can lead to incorrect spacing and readability issues. Instead, it enforces using template literals to combine text and expressions.
|
|
8
|
+
|
|
9
|
+
### Why?
|
|
10
|
+
|
|
11
|
+
Mixing text and JSX expressions without proper spacing can cause:
|
|
12
|
+
|
|
13
|
+
1. **Spacing issues**: `<div>+ {value}</div>` renders as "+ value" with unexpected spacing
|
|
14
|
+
2. **Inconsistent formatting**: Hard to maintain consistent spacing across the codebase
|
|
15
|
+
3. **Readability problems**: Mixed syntax makes code harder to read and understand
|
|
16
|
+
|
|
17
|
+
Using template literals ensures:
|
|
18
|
+
|
|
19
|
+
- Explicit control over spacing
|
|
20
|
+
- Consistent formatting
|
|
21
|
+
- Better readability
|
|
22
|
+
- Easier to maintain
|
|
23
|
+
|
|
24
|
+
## Examples
|
|
25
|
+
|
|
26
|
+
### ❌ Incorrect
|
|
27
|
+
|
|
28
|
+
```tsx
|
|
29
|
+
// Bad: Text followed by expression
|
|
30
|
+
<div>+ {fooVariable}</div>
|
|
31
|
+
<div>+{fooVariable}</div>
|
|
32
|
+
<div>Price: {price}</div>
|
|
33
|
+
<div>$ {amount}</div>
|
|
34
|
+
<span>Total: {total}</span>
|
|
35
|
+
<p>Hello {name}</p>
|
|
36
|
+
|
|
37
|
+
// Bad: Expression followed by text
|
|
38
|
+
<div>{count} items</div>
|
|
39
|
+
<div>{price}$</div>
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
### ✅ Correct
|
|
43
|
+
|
|
44
|
+
```tsx
|
|
45
|
+
// Good: Using template literals
|
|
46
|
+
<div>{`+${fooVariable}`}</div>
|
|
47
|
+
<div>{`+ ${fooVariable}`}</div>
|
|
48
|
+
<div>{`Price: ${price}`}</div>
|
|
49
|
+
<div>{`$ ${amount}`}</div>
|
|
50
|
+
<span>{`Total: ${total}`}</span>
|
|
51
|
+
<p>{`Hello ${name}`}</p>
|
|
52
|
+
|
|
53
|
+
// Good: Using template literals for expression + text
|
|
54
|
+
<div>{`${count}items`}</div>
|
|
55
|
+
<div>{`${price}$`}</div>
|
|
56
|
+
|
|
57
|
+
// Good: Expression only
|
|
58
|
+
<div>{fooVariable}</div>
|
|
59
|
+
<div>{price}</div>
|
|
60
|
+
|
|
61
|
+
// Good: Text only
|
|
62
|
+
<div>Some static text</div>
|
|
63
|
+
|
|
64
|
+
// Good: Expression with whitespace only around it
|
|
65
|
+
<div> {fooVariable} </div>
|
|
66
|
+
<div>
|
|
67
|
+
{fooVariable}
|
|
68
|
+
</div>
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
## When Not To Use It
|
|
72
|
+
|
|
73
|
+
If you prefer mixing text and JSX expressions, you can disable this rule. However, this may lead to inconsistent spacing and formatting issues.
|
|
74
|
+
|
|
75
|
+
## Further Reading
|
|
76
|
+
|
|
77
|
+
- [Template Literals (MDN)](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Template_literals)
|
|
78
|
+
- [JSX in React](https://react.dev/learn/writing-markup-with-jsx)
|