eslint-plugin-code-style 2.0.0 → 2.0.2

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.
@@ -1,224 +0,0 @@
1
- # Object Rules
2
-
3
- ### `no-empty-lines-in-objects`
4
-
5
- **What it does:** Removes empty lines within object literals — between properties and after opening/before closing braces.
6
-
7
- **Why use it:** Empty lines inside objects break the visual grouping of properties. Properties should flow as a cohesive unit.
8
-
9
- ```javascript
10
- // ✅ Good — no empty lines
11
- const user = {
12
- name: "John",
13
- email: "john@example.com",
14
- role: "admin",
15
- };
16
-
17
- const config = {
18
- host: "localhost",
19
- port: 3000,
20
- debug: true,
21
- };
22
-
23
- // ❌ Bad — empty line between properties
24
- const user = {
25
- name: "John",
26
-
27
- email: "john@example.com",
28
-
29
- role: "admin",
30
- };
31
-
32
- // ❌ Bad — empty line after opening brace
33
- const config = {
34
-
35
- host: "localhost",
36
- port: 3000,
37
- };
38
-
39
- // ❌ Bad — empty line before closing brace
40
- const config = {
41
- host: "localhost",
42
- port: 3000,
43
-
44
- };
45
- ```
46
-
47
- ---
48
-
49
- ### `object-property-per-line`
50
-
51
- **What it does:** Controls object formatting based on property count:
52
- - 1 property: stays on single line `{ name: "John" }`
53
- - 2+ properties: expands with `{` and `}` on own lines, each property on its own line
54
-
55
- **Why use it:** Single-property objects are clear on one line. Multiple properties need expansion for readability and clean diffs.
56
-
57
- ```javascript
58
- // ✅ Good — single property stays compact
59
- const point = { x: 10 };
60
- const config = { debug: true };
61
- fn({ callback: handleClick });
62
-
63
- // ✅ Good — 2+ properties get full expansion
64
- const point = {
65
- x: 10,
66
- y: 20,
67
- };
68
-
69
- const user = {
70
- name: "John",
71
- email: "john@example.com",
72
- role: "admin",
73
- };
74
-
75
- // ✅ Good — nested objects follow same rules
76
- const config = {
77
- server: { port: 3000 },
78
- database: {
79
- host: "localhost",
80
- name: "mydb",
81
- },
82
- };
83
-
84
- // ❌ Bad — multiple properties on one line
85
- const point = { x: 10, y: 20 };
86
- const user = { name: "John", email: "john@example.com" };
87
-
88
- // ❌ Bad — inconsistent formatting
89
- const point = { x: 10,
90
- y: 20 };
91
- ```
92
-
93
- **Options:**
94
-
95
- | Option | Type | Default | Description |
96
- |--------|------|---------|-------------|
97
- | `minProperties` | `integer` | `2` | Minimum properties to trigger expansion |
98
-
99
- ```javascript
100
- // Example: Require 3+ properties for expansion
101
- "code-style/object-property-per-line": ["error", { minProperties: 3 }]
102
- ```
103
-
104
- ---
105
-
106
- ### `object-property-value-brace`
107
-
108
- **What it does:** Ensures opening braces of object values start on the same line as the colon, not on a new line.
109
-
110
- **Why use it:** Braces on new lines waste vertical space and disconnect the property key from its value.
111
-
112
- ```javascript
113
- // ✅ Good — brace on same line as colon
114
- const styles = {
115
- "& a": { color: "red" },
116
- "& button": { padding: "10px" },
117
- };
118
-
119
- const config = {
120
- server: {
121
- host: "localhost",
122
- port: 3000,
123
- },
124
- };
125
-
126
- // ❌ Bad — brace on new line
127
- const styles = {
128
- "& a":
129
- { color: "red" },
130
- "& button":
131
- { padding: "10px" },
132
- };
133
-
134
- // ❌ Bad — inconsistent
135
- const config = {
136
- server:
137
- {
138
- host: "localhost",
139
- },
140
- };
141
- ```
142
-
143
- ---
144
-
145
- ### `object-property-value-format`
146
-
147
- **What it does:** Ensures property values start on the same line as the colon for simple values (strings, numbers, identifiers).
148
-
149
- **Why use it:** Values on new lines after the colon waste space and look disconnected from their keys.
150
-
151
- ```javascript
152
- // ✅ Good — values on same line as colon
153
- const user = {
154
- name: "John",
155
- age: 30,
156
- isActive: true,
157
- role: userRole,
158
- };
159
-
160
- // ✅ Good — complex values can span lines
161
- const config = {
162
- handler: (event) => {
163
- process(event);
164
- },
165
- items: [
166
- "first",
167
- "second",
168
- ],
169
- };
170
-
171
- // ❌ Bad — simple values on new line
172
- const user = {
173
- name:
174
- "John",
175
- age:
176
- 30,
177
- isActive:
178
- true,
179
- };
180
- ```
181
-
182
- ---
183
-
184
- ### `string-property-spacing`
185
-
186
- **What it does:** Removes leading and trailing whitespace inside string property keys.
187
-
188
- **Why use it:** Whitespace in property keys is usually unintentional and can cause bugs when accessing properties.
189
-
190
- ```javascript
191
- // ✅ Good — no extra whitespace
192
- const styles = {
193
- "& a": { color: "red" },
194
- "& .button": { padding: "10px" },
195
- "data-testid": "myElement",
196
- };
197
-
198
- const obj = {
199
- "Content-Type": "application/json",
200
- "X-Custom-Header": "value",
201
- };
202
-
203
- // ❌ Bad — leading whitespace
204
- const styles = {
205
- " & a": { color: "red" },
206
- " & .button": { padding: "10px" },
207
- };
208
-
209
- // ❌ Bad — trailing whitespace
210
- const obj = {
211
- "Content-Type ": "application/json",
212
- };
213
-
214
- // ❌ Bad — both
215
- const styles = {
216
- " & a ": { color: "red" },
217
- };
218
- ```
219
-
220
- <br />
221
-
222
- ---
223
-
224
- [← Back to Rules Index](./README.md) | [← Back to Main README](../../README.md)
@@ -1,175 +0,0 @@
1
- # React Rules
2
-
3
- ### `react-code-order`
4
-
5
- **What it does:** Enforces a consistent ordering of code blocks within React components and custom hooks. The order follows a logical dependency chain where declarations appear before their usage.
6
-
7
- **Order (top to bottom):**
8
- 1. Props/params destructure (in function signature: `({ prop1, prop2 })`)
9
- 2. Props/params destructure in body (`const { x } = propValue` where propValue is a prop)
10
- 3. `useRef` declarations
11
- 4. `useState` declarations
12
- 5. `useReducer` declarations
13
- 6. `useSelector` / `useDispatch` (Redux hooks)
14
- 7. Router hooks (`useNavigate`, `useLocation`, `useParams`, `useSearchParams`)
15
- 8. Context hooks (`useContext`, `useToast`, etc.)
16
- 9. Custom hooks (`use*` pattern)
17
- 10. Derived state / variables (computed from hooks above, e.g., `const isSearching = term.length > 0`)
18
- 11. `useMemo` declarations
19
- 12. `useCallback` declarations
20
- 13. Handler functions (`const handleX = () => {}`)
21
- 14. `useEffect` / `useLayoutEffect`
22
- 15. Return statement
23
-
24
- **Why use it:** A consistent code structure makes components and hooks predictable and easier to navigate. Placing hooks before derived values ensures dependencies are defined before use. Effects come last because they typically depend on everything else.
25
-
26
- ```typescript
27
- // Good — Component follows the correct order
28
- const UserDashboard = ({ title }) => {
29
- // 1. useRef
30
- const inputRef = useRef(null);
31
-
32
- // 2. useState
33
- const [count, setCount] = useState(0);
34
- const [isLoading, setIsLoading] = useState(false);
35
-
36
- // 3. Redux hooks
37
- const dispatch = useDispatch();
38
- const user = useSelector((state) => state.user);
39
-
40
- // 4. Router hooks
41
- const navigate = useNavigate();
42
- const { id } = useParams();
43
-
44
- // 5. Custom hooks
45
- const { data, loading } = useFetchData(id);
46
-
47
- // 6. Derived state
48
- const isReady = !loading && data !== null;
49
- const displayName = user?.name ?? "Guest";
50
-
51
- // 7. useMemo
52
- const filteredItems = useMemo(
53
- () => data?.filter((item) => item.active),
54
- [data],
55
- );
56
-
57
- // 8. useCallback
58
- const handleSubmit = useCallback(
59
- () => {
60
- dispatch(submitAction());
61
- },
62
- [dispatch],
63
- );
64
-
65
- // 9. Handler functions
66
- const resetHandler = () => {
67
- setCount(0);
68
- setIsLoading(false);
69
- };
70
-
71
- // 10. useEffect
72
- useEffect(
73
- () => {
74
- inputRef.current?.focus();
75
- },
76
- [],
77
- );
78
-
79
- // 11. Return
80
- return (
81
- <div>
82
- <h1>{title}</h1>
83
- <span>{displayName}</span>
84
- </div>
85
- );
86
- };
87
-
88
- // Good — Custom hook follows the correct order
89
- const useCreateAccount = () => {
90
- // 1. useState
91
- const [loading, setLoading] = useState(false);
92
- const [created, setCreated] = useState(false);
93
-
94
- // 2. Redux hooks
95
- const dispatch = useDispatch();
96
-
97
- // 3. Context hooks
98
- const { toast } = useToast();
99
-
100
- // 4. Handler functions
101
- const createAccountHandler = async (data: AccountData) => {
102
- setLoading(true);
103
- try {
104
- await api.createAccount(data);
105
- setCreated(true);
106
- } catch (error) {
107
- toast({ description: "Failed to create account" });
108
- } finally {
109
- setLoading(false);
110
- }
111
- };
112
-
113
- // 5. useEffect
114
- useEffect(
115
- () => {
116
- if (created) {
117
- setTimeout(() => setCreated(false), 50);
118
- }
119
- },
120
- [created],
121
- );
122
-
123
- // 6. Return
124
- return { createAccountHandler, created, loading };
125
- };
126
-
127
- // Bad — useEffect before useState
128
- const BadComponent = ({ title }) => {
129
- useEffect(() => {
130
- console.log("mounted");
131
- }, []);
132
-
133
- const [count, setCount] = useState(0);
134
-
135
- return <div>{title}</div>;
136
- };
137
-
138
- // Bad — context hook before useState in custom hook
139
- const useBadHook = () => {
140
- const { toast } = useToast(); // Should come after useState
141
- const [loading, setLoading] = useState(false);
142
- return { loading };
143
- };
144
-
145
- // Bad — handler before hooks
146
- const AnotherBadComponent = ({ title }) => {
147
- const handleClick = () => {
148
- console.log("clicked");
149
- };
150
-
151
- const dispatch = useDispatch();
152
- const [count, setCount] = useState(0);
153
-
154
- return <div onClick={handleClick}>{title}</div>;
155
- };
156
-
157
- // Bad — derived state after handler
158
- const YetAnotherBad = ({ title }) => {
159
- const [items, setItems] = useState([]);
160
-
161
- const handleAdd = () => {
162
- setItems([...items, "new"]);
163
- };
164
-
165
- const itemCount = items.length; // Should come before handleAdd
166
-
167
- return <div>{itemCount}</div>;
168
- };
169
- ```
170
-
171
- <br />
172
-
173
- ---
174
-
175
- [<- Back to Rules Index](./README.md) | [<- Back to Main README](../../README.md)
@@ -1,61 +0,0 @@
1
- # Spacing Rules
2
-
3
- ### `assignment-value-same-line`
4
-
5
- **What it does:** Ensures the assigned value starts on the same line as the `=` sign, not on a new line.
6
-
7
- **Why use it:** Breaking after `=` creates awkward formatting and wastes vertical space. Keeping values on the same line as `=` is more readable.
8
-
9
- ```javascript
10
- // ✅ Good — value starts on same line as =
11
- const name = "John";
12
- const config = {
13
- host: "localhost",
14
- port: 3000,
15
- };
16
- const items = [
17
- "first",
18
- "second",
19
- ];
20
-
21
- // ❌ Bad — value on new line after =
22
- const name =
23
- "John";
24
- const config =
25
- {
26
- host: "localhost",
27
- port: 3000,
28
- };
29
- const items =
30
- [
31
- "first",
32
- "second",
33
- ];
34
- ```
35
-
36
- ---
37
-
38
- ### `member-expression-bracket-spacing`
39
-
40
- **What it does:** Removes spaces inside brackets in computed member expressions (array access, dynamic property access).
41
-
42
- **Why use it:** Consistent with JavaScript conventions. Spaces inside brackets look inconsistent with array literals and other bracket usage.
43
-
44
- ```javascript
45
- // ✅ Good — no spaces inside brackets
46
- const value = arr[0];
47
- const name = obj[key];
48
- const item = data[index];
49
- const nested = matrix[row][col];
50
-
51
- // ❌ Bad — spaces inside brackets
52
- const value = arr[ 0 ];
53
- const name = obj[ key ];
54
- const item = data[ index ];
55
- ```
56
-
57
- <br />
58
-
59
- ---
60
-
61
- [← Back to Rules Index](./README.md) | [← Back to Main README](../../README.md)
@@ -1,92 +0,0 @@
1
- # String Rules
2
-
3
- ### `no-hardcoded-strings`
4
-
5
- **What it does:** Enforces that user-facing strings should be imported from constants/strings/data modules rather than hardcoded inline. This promotes maintainability, consistency, and enables easier internationalization.
6
-
7
- **Why use it:** Hardcoded strings scattered throughout your codebase are hard to maintain, translate, and keep consistent. Centralizing strings in constants makes them easy to find, update, and potentially translate.
8
-
9
- **Special detection (should be imported from `@/enums` or `@/data`):**
10
- - **HTTP status codes** — 2xx, 4xx, 5xx like "200", "404", "500"
11
- - **HTTP methods** — "GET", "POST", "PUT", "DELETE", "PATCH", etc.
12
- - **Role/permission names** — "admin", "user", "moderator", "editor", etc.
13
- - **Environment names** — "production", "development", "staging", "test", etc.
14
- - **Log levels** — "debug", "info", "warn", "error", "fatal", etc.
15
- - **Status strings** — "active", "pending", "approved", "rejected", "completed", etc.
16
- - **Priority levels** — "high", "medium", "low", "critical", "urgent", etc.
17
-
18
- **Options:**
19
-
20
- | Option | Type | Default | Description |
21
- |--------|------|---------|-------------|
22
- | `ignoreAttributes` | `string[]` | See below | JSX attributes to ignore (replaces defaults) |
23
- | `extraIgnoreAttributes` | `string[]` | `[]` | Additional JSX attributes to ignore (extends defaults) |
24
- | `ignorePatterns` | `string[]` | `[]` | Regex patterns for strings to ignore |
25
-
26
- **Default ignored attributes:** `className`, `id`, `type`, `name`, `href`, `src`, `alt`, `role`, `style`, `key`, `data-*`, `aria-*`, and many more HTML/SVG attributes.
27
-
28
- **Default ignored patterns:** Empty strings, single characters, CSS units (`px`, `em`, `%`), colors, URLs, paths, file extensions, MIME types, UUIDs, dates, camelCase/snake_case identifiers, HTTP methods, and other technical strings.
29
-
30
- ```javascript
31
- // Good — strings imported from constants
32
- import { BUTTON_LABEL, ERROR_MESSAGE, welcomeText } from "@/constants";
33
- import { FORM_LABELS } from "@/strings";
34
- import { HttpStatus, UserRole } from "@/enums";
35
-
36
- const ComponentHandler = () => (
37
- <div>
38
- <button>{BUTTON_LABEL}</button>
39
- <span>{ERROR_MESSAGE}</span>
40
- <p>{welcomeText}</p>
41
- </div>
42
- );
43
-
44
- const getMessageHandler = () => ERROR_MESSAGE;
45
-
46
- // Good — using enums for status codes and roles
47
- if (status === HttpStatus.NOT_FOUND) { ... }
48
- if (role === UserRole.ADMIN) { ... }
49
-
50
- // Good — technical strings are allowed
51
- <input type="text" className="input-field" />
52
- <a href="/dashboard">Link</a>
53
- const url = `/api/users/${id}`;
54
- const size = "100px";
55
-
56
- // Bad — hardcoded user-facing strings
57
- <button>Submit Form</button>
58
- <span>Something went wrong</span>
59
- const message = "Welcome to the application";
60
- return "User not found";
61
-
62
- // Bad — hardcoded status codes and roles
63
- if (status === "404") { ... }
64
- if (role === "admin") { ... }
65
- ```
66
-
67
- **Configuration example:**
68
-
69
- ```javascript
70
- // Allow more attributes, add custom ignore patterns
71
- "code-style/no-hardcoded-strings": ["error", {
72
- extraIgnoreAttributes: ["tooltip", "placeholder"],
73
- ignorePatterns: ["^TODO:", "^FIXME:"]
74
- }]
75
- ```
76
-
77
- **Valid import paths for strings:**
78
- - `@/data`
79
- - `@/strings` or `@/@strings`
80
- - `@/constants` or `@/@constants`
81
-
82
- **Valid import paths for enums (status codes, roles):**
83
- - `@/enums`
84
- - `@/data`
85
-
86
- ---
87
-
88
- <br />
89
-
90
- ---
91
-
92
- [<- Back to Rules Index](./README.md) | [<- Back to Main README](../../README.md)