eslint-plugin-nextfriday 1.17.0 → 1.19.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,17 @@
1
1
  # eslint-plugin-nextfriday
2
2
 
3
+ ## 1.19.0
4
+
5
+ ### Minor Changes
6
+
7
+ - [#83](https://github.com/next-friday/eslint-plugin-nextfriday/pull/83) [`b7143d2`](https://github.com/next-friday/eslint-plugin-nextfriday/commit/b7143d2f779ca1ca34f6562d09c1a6168b74c338) Thanks [@joetakara](https://github.com/joetakara)! - Add jsx-no-ternary-null rule to enforce logical AND over ternary with null/undefined in JSX
8
+
9
+ ## 1.18.0
10
+
11
+ ### Minor Changes
12
+
13
+ - [#81](https://github.com/next-friday/eslint-plugin-nextfriday/pull/81) [`081326a`](https://github.com/next-friday/eslint-plugin-nextfriday/commit/081326adf199aee711e97b1627def3bf867ad89c) Thanks [@joetakara](https://github.com/joetakara)! - Add hyphenated string group to jsx-sort-props for props like aria-label and data-slot. Fix jsx-newline-between-elements to include self-closing elements
14
+
3
15
  ## 1.17.0
4
16
 
5
17
  ### Minor Changes
package/README.md CHANGED
@@ -126,6 +126,7 @@ export default [
126
126
  "nextfriday/jsx-no-inline-object-prop": "error",
127
127
  "nextfriday/jsx-no-newline-single-line-elements": "error",
128
128
  "nextfriday/jsx-no-non-component-function": "error",
129
+ "nextfriday/jsx-no-ternary-null": "error",
129
130
  "nextfriday/jsx-no-variable-in-callback": "error",
130
131
  "nextfriday/jsx-require-suspense": "error",
131
132
  "nextfriday/jsx-simple-props": "error",
@@ -217,6 +218,7 @@ export default [
217
218
  | [jsx-no-inline-object-prop](docs/rules/JSX_NO_INLINE_OBJECT_PROP.md) | Disallow inline object literals in JSX props | ❌ |
218
219
  | [jsx-no-newline-single-line-elements](docs/rules/JSX_NO_NEWLINE_SINGLE_LINE_ELEMENTS.md) | Disallow empty lines between single-line sibling JSX elements | ✅ |
219
220
  | [jsx-no-non-component-function](docs/rules/JSX_NO_NON_COMPONENT_FUNCTION.md) | Disallow non-component functions at top level in .tsx/.jsx files | ❌ |
221
+ | [jsx-no-ternary-null](docs/rules/JSX_NO_TERNARY_NULL.md) | Enforce logical AND over ternary with null/undefined in JSX | ✅ |
220
222
  | [jsx-no-variable-in-callback](docs/rules/JSX_NO_VARIABLE_IN_CALLBACK.md) | Disallow variable declarations inside callback functions in JSX | ❌ |
221
223
  | [jsx-require-suspense](docs/rules/JSX_REQUIRE_SUSPENSE.md) | Require lazy-loaded components to be wrapped in Suspense | ❌ |
222
224
  | [jsx-simple-props](docs/rules/JSX_SIMPLE_PROPS.md) | Enforce simple prop values (strings, variables, callbacks, ReactNode) | ❌ |
@@ -240,10 +242,10 @@ export default [
240
242
  | -------------------- | -------- | ---------- | --------- | ------------- | ----------- |
241
243
  | `base` | warn | 36 | 0 | 0 | 36 |
242
244
  | `base/recommended` | error | 36 | 0 | 0 | 36 |
243
- | `react` | warn | 36 | 14 | 0 | 50 |
244
- | `react/recommended` | error | 36 | 14 | 0 | 50 |
245
- | `nextjs` | warn | 36 | 14 | 1 | 51 |
246
- | `nextjs/recommended` | error | 36 | 14 | 1 | 51 |
245
+ | `react` | warn | 36 | 15 | 0 | 51 |
246
+ | `react/recommended` | error | 36 | 15 | 0 | 51 |
247
+ | `nextjs` | warn | 36 | 15 | 1 | 52 |
248
+ | `nextjs/recommended` | error | 36 | 15 | 1 | 52 |
247
249
 
248
250
  ### Base Configuration Rules (36 rules)
249
251
 
@@ -286,7 +288,7 @@ Included in `base`, `base/recommended`, and all other presets:
286
288
  - `nextfriday/sort-type-alphabetically`
287
289
  - `nextfriday/sort-type-required-first`
288
290
 
289
- ### JSX Rules (14 rules)
291
+ ### JSX Rules (15 rules)
290
292
 
291
293
  Additionally included in `react`, `react/recommended`, `nextjs`, `nextjs/recommended`:
292
294
 
@@ -296,6 +298,7 @@ Additionally included in `react`, `react/recommended`, `nextjs`, `nextjs/recomme
296
298
  - `nextfriday/jsx-no-inline-object-prop`
297
299
  - `nextfriday/jsx-no-newline-single-line-elements`
298
300
  - `nextfriday/jsx-no-non-component-function`
301
+ - `nextfriday/jsx-no-ternary-null`
299
302
  - `nextfriday/jsx-no-variable-in-callback`
300
303
  - `nextfriday/jsx-pascal-case`
301
304
  - `nextfriday/jsx-require-suspense`
@@ -329,7 +332,7 @@ Additionally included in `nextjs`, `nextjs/recommended` only:
329
332
 
330
333
  ## Agent Skill
331
334
 
332
- This plugin ships with an [Agent Skill](https://github.com/anthropics/skills) that teaches AI coding assistants (Claude Code, Cursor, etc.) all 51 rules so they generate compliant code from the start.
335
+ This plugin ships with an [Agent Skill](https://github.com/anthropics/skills) that teaches AI coding assistants (Claude Code, Cursor, etc.) all 52 rules so they generate compliant code from the start.
333
336
 
334
337
  ```bash
335
338
  npx skills add next-friday/eslint-plugin-nextfriday --skill eslint-plugin-nextfriday
@@ -0,0 +1,42 @@
1
+ # jsx-no-ternary-null
2
+
3
+ Enforce logical AND over ternary with null/undefined in JSX expressions.
4
+
5
+ > This rule is auto-fixable using `--fix`.
6
+
7
+ ## Rule Details
8
+
9
+ This rule flags ternary expressions inside JSX where one branch is `null` or `undefined`. These patterns are better expressed using the logical AND (`&&`) operator, which is more concise and idiomatic in React.
10
+
11
+ ### Why?
12
+
13
+ - **Readability**: `{condition && <Component />}` is cleaner than `{condition ? <Component /> : null}`
14
+ - **Consistency**: Encourages a single pattern for conditional rendering
15
+ - **Conciseness**: Removes unnecessary null/undefined branches
16
+
17
+ ## Examples
18
+
19
+ ### Incorrect
20
+
21
+ ```tsx
22
+ <div>{condition ? <span>Hello</span> : null}</div>
23
+ <div>{condition ? <Component /> : undefined}</div>
24
+ <div>{condition ? null : <span>Fallback</span>}</div>
25
+ ```
26
+
27
+ ### Correct
28
+
29
+ ```tsx
30
+ <div>{condition && <span>Hello</span>}</div>
31
+ <div>{condition && <Component />}</div>
32
+ <div>{!condition && <span>Fallback</span>}</div>
33
+ <div>{condition ? <A /> : <B />}</div>
34
+ ```
35
+
36
+ ## When Not To Use It
37
+
38
+ If your team prefers explicit ternary expressions for conditional rendering, even when one branch is null or undefined.
39
+
40
+ ## Related Rules
41
+
42
+ - [no-nested-ternary](JSX_NO_TERNARY_NULL.md)
@@ -6,13 +6,14 @@ Enforce JSX props are sorted by value type.
6
6
 
7
7
  This rule enforces a consistent ordering of JSX props based on the type of their value. Props must appear in the following order:
8
8
 
9
- 1. **String** - String literals and template literals
10
- 2. **Number/Boolean/Null** - Numeric literals, boolean literals, null, and undefined
11
- 3. **Expression** - Variable references, member expressions, call expressions, and other dynamic values
12
- 4. **Object/Array** - Inline objects and arrays
13
- 5. **Function** - Arrow functions and function expressions
14
- 6. **JSX Element** - JSX elements and fragments
15
- 7. **Shorthand boolean** - Props with no value (e.g., `disabled`, `required`)
9
+ 1. **String** - String literals and template literals (e.g., `className="cover"`)
10
+ 2. **Hyphenated string** - Props with hyphenated names and string values (e.g., `aria-label="label"`, `data-slot="nav"`)
11
+ 3. **Number/Boolean/Null** - Numeric literals, boolean literals, null, and undefined
12
+ 4. **Expression** - Variable references, member expressions, call expressions, and other dynamic values
13
+ 5. **Object/Array** - Inline objects and arrays
14
+ 6. **Function** - Arrow functions and function expressions
15
+ 7. **JSX Element** - JSX elements and fragments
16
+ 8. **Shorthand boolean** - Props with no value (e.g., `disabled`, `required`)
16
17
 
17
18
  Spread attributes (`{...props}`) reset the ordering context.
18
19
 
@@ -29,7 +30,6 @@ Spread attributes (`{...props}`) reset the ordering context.
29
30
  ```tsx
30
31
  <Component disabled title="hello" />
31
32
  <Component onClick={() => {}} count={42} />
32
- <Component icon={<Icon />} style={{ color: "red" }} />
33
33
  <Component className="cover" src={src} fill sizes={sizes} />
34
34
  ```
35
35
 
@@ -38,6 +38,7 @@ Spread attributes (`{...props}`) reset the ordering context.
38
38
  ```tsx
39
39
  <Component
40
40
  title="hello"
41
+ aria-label="close"
41
42
  count={100}
42
43
  src={src}
43
44
  style={{ color: "red" }}