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.
package/docs/rules/jsx.md DELETED
@@ -1,518 +0,0 @@
1
- # JSX Rules
2
-
3
- ### `classname-dynamic-at-end`
4
-
5
- **What it does:** Enforces that dynamic expressions in className template literals are placed at the end, after all static class names. Also applies to variables with names containing "class" or "Class".
6
-
7
- **Why use it:** When using Tailwind CSS with `tailwindcss/classnames-order`, static classes are automatically sorted. However, dynamic expressions like `${className}` or `${styles.button}` can break the visual order if placed in the middle. This rule ensures dynamic parts come last for consistent, readable class strings.
8
-
9
- ```javascript
10
- // ✅ Good — dynamic expressions at the end (JSX)
11
- <div className={`flex items-center gap-4 ${className}`} />
12
-
13
- // ✅ Good — dynamic expressions at the end (variable)
14
- const buttonClasses = `flex items-center ${className} ${styles.button}`;
15
-
16
- // ❌ Bad — dynamic expression at the beginning
17
- <div className={`${className} flex items-center gap-4`} />
18
-
19
- // ❌ Bad — dynamic expression in the middle (variable)
20
- const buttonClasses = `flex ${className} items-center gap-4`;
21
- ```
22
-
23
- ---
24
-
25
- ### `classname-multiline`
26
-
27
- **What it does:** Enforces that long className strings are broken into multiple lines, with each class on its own line. Triggers when either the class count exceeds `maxClassCount` (default: 3) or the string length exceeds `maxLength` (default: 80). Also enforces:
28
- - JSX `className` with no dynamic expressions uses `"..."` string literal format
29
- - JSX `className` with dynamic expressions uses `` {`...`} `` template literal format
30
- - Variables/object properties use `` `...` `` template literal for multiline (JS requires it)
31
- - No empty lines between classes or before/after the quotes
32
- - Under-threshold multiline classes are collapsed back to a single line
33
-
34
- Applies to JSX `className` attributes, variables with class-related names, and object properties within class-related objects.
35
-
36
- **Why use it:** Long single-line class strings are hard to read and review. Breaking them into one class per line makes diffs cleaner and classes easier to scan. Using string literals when no expressions are needed keeps the code simpler.
37
-
38
- ```javascript
39
- // ✅ Good — JSX with no expressions uses "..." format
40
- <div
41
- className="
42
- flex
43
- items-center
44
- justify-center
45
- rounded-lg
46
- p-4
47
- "
48
- />
49
-
50
- // ✅ Good — JSX with expressions uses {`...`} format
51
- <div
52
- className={`
53
- flex
54
- items-center
55
- justify-center
56
- ${className}
57
- `}
58
- />
59
-
60
- // ✅ Good — variable multiline uses template literal
61
- const buttonClasses = `
62
- flex
63
- items-center
64
- justify-center
65
- ${className}
66
- `;
67
-
68
- // ✅ Good — object property multiline uses template literal
69
- const variantClasses = {
70
- danger: `
71
- flex
72
- items-center
73
- justify-center
74
- bg-red-500
75
- `,
76
- };
77
-
78
- // ✅ Good — short class strings stay on one line
79
- <div className="flex items-center" />
80
-
81
- // ❌ Bad — too many classes on one line
82
- <div className="flex items-center justify-center rounded-lg p-4 font-bold" />
83
-
84
- // ❌ Bad — using template literal in JSX when no expressions
85
- <div className={`
86
- flex
87
- items-center
88
- justify-center
89
- rounded-lg
90
- `} />
91
-
92
- // ❌ Bad — empty lines between classes
93
- <div className="
94
- flex
95
-
96
- items-center
97
- justify-center
98
- " />
99
- ```
100
-
101
- ---
102
-
103
- ### `classname-no-extra-spaces`
104
-
105
- **What it does:** Removes multiple consecutive spaces and leading/trailing spaces inside className values. Applies to:
106
- - JSX `className` attributes (string literals and template literals)
107
- - Variables with names containing "class" (e.g., `buttonClasses`, `variantClasses`)
108
- - Object properties within class-related objects
109
-
110
- **Why use it:** Extra spaces between class names are usually unintentional and can cause issues. This rule normalizes spacing and removes unnecessary whitespace.
111
-
112
- ```javascript
113
- // ✅ Good — single space between classes
114
- <div className="flex items-center gap-4 rounded-lg" />
115
- const buttonClasses = `flex items-center ${className}`;
116
- const variantClasses = { primary: "bg-blue-500 text-white" };
117
-
118
- // ❌ Bad — multiple consecutive spaces
119
- <div className="flex items-center gap-4" />
120
- const buttonClasses = `flex items-center`;
121
- const variantClasses = { primary: "bg-blue-500 text-white" };
122
-
123
- // ❌ Bad — leading/trailing spaces in template literal
124
- const buttonClasses = ` flex items-center ${className} `;
125
- ```
126
-
127
- ---
128
-
129
- ### `classname-order`
130
-
131
- **What it does:** Enforces Tailwind CSS class ordering in variables, object properties, and return statements. Uses smart detection to identify Tailwind class strings.
132
-
133
- **Why use it:** This rule complements the official `tailwindcss/classnames-order` plugin by handling areas it doesn't cover:
134
- - **`tailwindcss/classnames-order`** — Handles JSX `className` attributes directly
135
- - **`classname-order`** — Handles class strings in variables, object properties, and return statements
136
-
137
- Both rules should be enabled together for complete Tailwind class ordering coverage.
138
-
139
- **Order enforced:** layout (flex, grid) → positioning → sizing (w, h) → spacing (p, m) → typography (text, font) → colors (bg, text) → effects (shadow, opacity) → transitions → states (hover, focus)
140
-
141
- ```javascript
142
- // ✅ Good — classes in correct order (variable)
143
- const buttonClasses = "flex items-center px-4 py-2 text-white bg-blue-500 hover:bg-blue-600";
144
-
145
- // ✅ Good — classes in correct order (object property)
146
- const variants = {
147
- primary: "flex items-center bg-blue-500 hover:bg-blue-600",
148
- secondary: "flex items-center bg-gray-500 hover:bg-gray-600",
149
- };
150
-
151
- // ✅ Good — classes in correct order (return statement)
152
- const getInputStyles = () => {
153
- return "border-error text-error placeholder-error/50 focus:border-error";
154
- };
155
-
156
- // ❌ Bad — hover state before base color (variable)
157
- const buttonClasses = "flex items-center hover:bg-blue-600 bg-blue-500";
158
-
159
- // ❌ Bad — unordered classes (object property)
160
- const variants = {
161
- primary: "hover:bg-blue-600 bg-blue-500 flex items-center",
162
- };
163
-
164
- // ❌ Bad — unordered classes (return statement)
165
- const getInputStyles = () => {
166
- return "focus:border-error text-error border-error";
167
- };
168
- ```
169
-
170
- ---
171
-
172
- ### `jsx-children-on-new-line`
173
-
174
- **What it does:** When a JSX element has multiple children, ensures each child is on its own line with proper indentation.
175
-
176
- **Why use it:** Multiple children on one line are hard to scan. Individual lines make the component structure clear.
177
-
178
- ```javascript
179
- // ✅ Good — each child on its own line
180
- <Container>
181
- <Header />
182
- <Content />
183
- <Footer />
184
- </Container>
185
-
186
- <Form>
187
- <Input name="email" />
188
- <Input name="password" />
189
- <Button type="submit">Login</Button>
190
- </Form>
191
-
192
- // ✅ Good — single child can stay inline
193
- <Button><Icon /></Button>
194
-
195
- // ❌ Bad — multiple children crammed together
196
- <Container><Header /><Content /><Footer /></Container>
197
-
198
- // ❌ Bad — inconsistent formatting
199
- <Form><Input name="email" />
200
- <Input name="password" />
201
- <Button>Login</Button></Form>
202
- ```
203
-
204
- ---
205
-
206
- ### `jsx-closing-bracket-spacing`
207
-
208
- **What it does:** Removes any space before `>` or `/>` in JSX tags.
209
-
210
- **Why use it:** Standard JSX convention. Spaces before closing brackets look inconsistent and can be confusing.
211
-
212
- ```javascript
213
- // ✅ Good — no space before closing
214
- <Button />
215
- <Input type="text" />
216
- <div className="container">
217
- <Modal isOpen={true}>
218
-
219
- // ❌ Bad — space before />
220
- <Button / >
221
- <Input type="text" / >
222
-
223
- // ❌ Bad — space before >
224
- <div className="container" >
225
- <Modal isOpen={true} >
226
- ```
227
-
228
- ---
229
-
230
- ### `jsx-element-child-new-line`
231
-
232
- **What it does:** When a JSX element contains another JSX element as a child, the child must be on its own line.
233
-
234
- **Why use it:** Nested elements on the same line hide the component structure. New lines make nesting visible.
235
-
236
- ```javascript
237
- // ✅ Good — nested element on new line
238
- <Button>
239
- <Icon name="check" />
240
- </Button>
241
-
242
- <Card>
243
- <CardHeader>
244
- <Title>Hello</Title>
245
- </CardHeader>
246
- </Card>
247
-
248
- // ✅ Good — text children can stay inline
249
- <Button>Click me</Button>
250
- <Title>{title}</Title>
251
-
252
- // ❌ Bad — nested element inline
253
- <Button><Icon name="check" /></Button>
254
-
255
- // ❌ Bad — complex nesting all inline
256
- <Card><CardHeader><Title>Hello</Title></CardHeader></Card>
257
- ```
258
-
259
- ---
260
-
261
- ### `jsx-logical-expression-simplify`
262
-
263
- **What it does:** Removes unnecessary parentheses around conditions and JSX elements in logical expressions.
264
-
265
- **Why use it:** Extra parentheses add visual noise. Simple conditions and elements don't need wrapping.
266
-
267
- ```javascript
268
- // ✅ Good — clean logical expressions
269
- {isLoading && <Spinner />}
270
- {error && <ErrorMessage>{error}</ErrorMessage>}
271
- {items.length > 0 && <List items={items} />}
272
- {user.isAdmin && <AdminPanel />}
273
-
274
- // ❌ Bad — unnecessary parentheses around condition
275
- {(isLoading) && <Spinner />}
276
- {(error) && <ErrorMessage />}
277
-
278
- // ❌ Bad — unnecessary parentheses around JSX
279
- {isLoading && (<Spinner />)}
280
- {error && (<ErrorMessage />)}
281
-
282
- // ❌ Bad — both
283
- {(isLoading) && (<Spinner />)}
284
- ```
285
-
286
- ---
287
-
288
- ### `jsx-parentheses-position`
289
-
290
- **What it does:** Ensures the opening parenthesis `(` for multiline JSX is on the same line as `return` or `=>`, not on a new line.
291
-
292
- **Why use it:** Parenthesis on new line wastes vertical space and looks disconnected from the statement it belongs to.
293
-
294
- ```javascript
295
- // ✅ Good — parenthesis on same line as =>
296
- const Card = () => (
297
- <div className="card">
298
- <h1>Title</h1>
299
- </div>
300
- );
301
-
302
- // ✅ Good — parenthesis on same line as return
303
- function Card() {
304
- return (
305
- <div className="card">
306
- <h1>Title</h1>
307
- </div>
308
- );
309
- }
310
-
311
- // ❌ Bad — parenthesis on new line after =>
312
- const Card = () =>
313
- (
314
- <div className="card">
315
- <h1>Title</h1>
316
- </div>
317
- );
318
-
319
- // ❌ Bad — parenthesis on new line after return
320
- function Card() {
321
- return
322
- (
323
- <div className="card">
324
- <h1>Title</h1>
325
- </div>
326
- );
327
- }
328
- ```
329
-
330
- ---
331
-
332
- ### `jsx-prop-naming-convention`
333
-
334
- **What it does:** Enforces camelCase naming for JSX props, with exceptions for:
335
- - `data-*` attributes (kebab-case allowed)
336
- - `aria-*` attributes (kebab-case allowed)
337
- - Props that reference components (PascalCase allowed)
338
-
339
- **Why use it:** Consistent prop naming follows React conventions and makes code predictable.
340
-
341
- ```javascript
342
- // ✅ Good — camelCase props
343
- <Button onClick={handleClick} isDisabled={false} />
344
- <Input onChange={handleChange} autoFocus />
345
- <Modal onClose={close} isVisible={true} />
346
-
347
- // ✅ Good — data-* and aria-* use kebab-case
348
- <Button data-testid="submit-btn" aria-label="Submit" />
349
- <Input data-cy="email-input" aria-describedby="help" />
350
-
351
- // ✅ Good — component reference props use PascalCase
352
- <Modal ContentComponent={Panel} />
353
- <Route Component={HomePage} />
354
-
355
- // ❌ Bad — snake_case props
356
- <Button on_click={handler} is_disabled={false} />
357
- <Input on_change={handler} auto_focus />
358
-
359
- // ❌ Bad — kebab-case for regular props
360
- <Button is-disabled={false} />
361
- ```
362
-
363
- ---
364
-
365
- ### `jsx-simple-element-one-line`
366
-
367
- **What it does:** Collapses simple JSX elements (single text or expression child) onto one line.
368
-
369
- **Why use it:** Simple elements don't need multi-line formatting. Single line is more compact and scannable.
370
-
371
- ```javascript
372
- // ✅ Good — simple elements on one line
373
- <Button>{buttonText}</Button>
374
- <Title>Welcome</Title>
375
- <span>{count}</span>
376
- <Label>{user.name}</Label>
377
-
378
- // ✅ Good — complex children stay multiline
379
- <Button>
380
- <Icon />
381
- {buttonText}
382
- </Button>
383
-
384
- // ❌ Bad — unnecessary multiline for simple content
385
- <Button>
386
- {buttonText}
387
- </Button>
388
-
389
- <Title>
390
- Welcome
391
- </Title>
392
-
393
- <span>
394
- {count}
395
- </span>
396
- ```
397
-
398
- ---
399
-
400
- ### `jsx-string-value-trim`
401
-
402
- **What it does:** Removes leading and trailing whitespace inside JSX string attribute values.
403
-
404
- **Why use it:** Whitespace in class names and other string values is usually unintentional and can cause bugs (e.g., CSS class not matching).
405
-
406
- ```javascript
407
- // ✅ Good — no extra whitespace
408
- <Button className="primary" />
409
- <Input placeholder="Enter email" />
410
- <a href="/home">Home</a>
411
-
412
- // ❌ Bad — leading whitespace
413
- <Button className=" primary" />
414
- <Input placeholder=" Enter email" />
415
-
416
- // ❌ Bad — trailing whitespace
417
- <Button className="primary " />
418
- <a href="/home ">Home</a>
419
-
420
- // ❌ Bad — both
421
- <Button className=" primary " />
422
- ```
423
-
424
- ---
425
-
426
- ### `jsx-ternary-format`
427
-
428
- **What it does:** Formats ternary expressions in JSX consistently:
429
- - Simple branches stay on one line
430
- - Complex/multiline branches get parentheses with proper indentation
431
-
432
- **Why use it:** Consistent ternary formatting makes conditional rendering predictable and readable.
433
-
434
- ```javascript
435
- // ✅ Good — simple ternary on one line
436
- {isLoading ? <Spinner /> : <Content />}
437
- {error ? <Error /> : <Success />}
438
-
439
- // ✅ Good — complex branches get parentheses
440
- {isLoading ? (
441
- <Spinner size="large" />
442
- ) : (
443
- <Content>
444
- <Header />
445
- <Body />
446
- </Content>
447
- )}
448
-
449
- // ✅ Good — one simple, one complex
450
- {isLoading ? <Spinner /> : (
451
- <Content>
452
- <Header />
453
- <Body />
454
- </Content>
455
- )}
456
-
457
- // ❌ Bad — awkward line breaks
458
- {isLoading
459
- ? <Spinner />
460
- : <Content />}
461
-
462
- // ❌ Bad — missing parentheses for complex branch
463
- {isLoading ? <Spinner /> : <Content>
464
- <Header />
465
- <Body />
466
- </Content>}
467
- ```
468
-
469
- ---
470
-
471
- ### `no-empty-lines-in-jsx`
472
-
473
- **What it does:** Removes empty lines inside JSX elements — between children and after opening/before closing tags.
474
-
475
- **Why use it:** Empty lines inside JSX create visual gaps that break the component's visual structure.
476
-
477
- ```javascript
478
- // ✅ Good — no empty lines inside
479
- <div>
480
- <Header />
481
- <Content />
482
- <Footer />
483
- </div>
484
-
485
- <Form>
486
- <Input name="email" />
487
- <Input name="password" />
488
- <Button>Submit</Button>
489
- </Form>
490
-
491
- // ❌ Bad — empty line after opening tag
492
- <div>
493
-
494
- <Header />
495
- <Content />
496
- </div>
497
-
498
- // ❌ Bad — empty lines between children
499
- <Form>
500
- <Input name="email" />
501
-
502
- <Input name="password" />
503
-
504
- <Button>Submit</Button>
505
- </Form>
506
-
507
- // ❌ Bad — empty line before closing tag
508
- <div>
509
- <Content />
510
-
511
- </div>
512
- ```
513
-
514
- <br />
515
-
516
- ---
517
-
518
- [← Back to Rules Index](./README.md) | [← Back to Main README](../../README.md)