@eslint-react/jsx 5.16.0 → 5.17.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/dist/index.d.ts +92 -92
- package/dist/index.js +81 -81
- package/package.json +7 -7
package/dist/index.d.ts
CHANGED
|
@@ -3,7 +3,7 @@ import { TSESTree } from "@typescript-eslint/types";
|
|
|
3
3
|
import { RuleContext } from "@eslint-react/eslint";
|
|
4
4
|
//#region src/collapse-multiline-text.d.ts
|
|
5
5
|
/**
|
|
6
|
-
* Collapse a multiline JSX text string following React's whitespace rules
|
|
6
|
+
* Collapse a multiline JSX text string following React's whitespace rules.
|
|
7
7
|
*
|
|
8
8
|
* This mirrors Babel's `cleanJSXElementLiteralChild` algorithm:
|
|
9
9
|
* 1. Split the raw text into lines.
|
|
@@ -11,15 +11,15 @@ import { RuleContext } from "@eslint-react/eslint";
|
|
|
11
11
|
* 3. Trim leading spaces on non-first lines and trailing spaces on non-last lines.
|
|
12
12
|
* 4. Collapse tabs into spaces.
|
|
13
13
|
* 5. Append a single space after each non-last non-empty line.
|
|
14
|
-
* @param text The raw JSX text string to collapse
|
|
15
|
-
* @returns The collapsed string, or `null` if the text contains only whitespace
|
|
14
|
+
* @param text The raw JSX text string to collapse.
|
|
15
|
+
* @returns The collapsed string, or `null` if the text contains only whitespace.
|
|
16
16
|
* @see https://github.com/babel/babel/blob/main/packages/babel-types/src/utils/react/cleanJSXElementLiteralChild.ts
|
|
17
17
|
*/
|
|
18
18
|
declare function collapseMultilineText(text: string): string | null;
|
|
19
19
|
//#endregion
|
|
20
20
|
//#region src/find-attribute.d.ts
|
|
21
21
|
/**
|
|
22
|
-
* Find a JSX attribute (or spread attribute containing the property) by name on a given element
|
|
22
|
+
* Find a JSX attribute (or spread attribute containing the property) by name on a given element.
|
|
23
23
|
*
|
|
24
24
|
* Returns the last matching attribute to mirror React's behavior where later props win,
|
|
25
25
|
* or `undefined` when the attribute is not present.
|
|
@@ -27,43 +27,43 @@ declare function collapseMultilineText(text: string): string | null;
|
|
|
27
27
|
* Spread attributes are resolved when possible: if the spread argument is an identifier
|
|
28
28
|
* that resolves to an object expression, the object's properties are searched for a matching key.
|
|
29
29
|
* Nested object expressions and nested spread identifiers are also resolved.
|
|
30
|
-
* @param context The ESLint rule context (needed for variable resolution in spread attributes)
|
|
31
|
-
* @param element The `JSXElement` node to search
|
|
32
|
-
* @param name The attribute name to look for (ex: "className")
|
|
33
|
-
* @returns The matching `JSXAttribute` or `JSXSpreadAttribute`, or `undefined` when not found
|
|
30
|
+
* @param context The ESLint rule context (needed for variable resolution in spread attributes).
|
|
31
|
+
* @param element The `JSXElement` node to search.
|
|
32
|
+
* @param name The attribute name to look for (ex: "className").
|
|
33
|
+
* @returns The matching `JSXAttribute` or `JSXSpreadAttribute`, or `undefined` when not found.
|
|
34
34
|
*/
|
|
35
35
|
declare function findAttribute(context: RuleContext, element: TSESTree.JSXElement, name: string): TSESTreeJSXAttributeLike | undefined;
|
|
36
36
|
//#endregion
|
|
37
37
|
//#region src/find-parent-attribute.d.ts
|
|
38
38
|
/**
|
|
39
39
|
* Walk up the AST from `node` to find the nearest ancestor that is a `JSXAttribute`
|
|
40
|
-
* and (optionally) passes a predicate
|
|
40
|
+
* and (optionally) passes a predicate.
|
|
41
41
|
*
|
|
42
42
|
* This is useful when a rule visitor enters a deeply nested node (ex: a `Literal`
|
|
43
43
|
* inside an expression container) and needs to know which JSX attribute it belongs to.
|
|
44
|
-
* @param node The starting node for the upward search
|
|
45
|
-
* @param test Optional predicate to filter candidate `JSXAttribute` nodes. When omitted every `JSXAttribute` ancestor matches
|
|
46
|
-
* @returns The first matching `JSXAttribute` ancestor, or `null` if none is found before reaching the root
|
|
44
|
+
* @param node The starting node for the upward search.
|
|
45
|
+
* @param test Optional predicate to filter candidate `JSXAttribute` nodes. When omitted every `JSXAttribute` ancestor matches.
|
|
46
|
+
* @returns The first matching `JSXAttribute` ancestor, or `null` if none is found before reaching the root.
|
|
47
47
|
*/
|
|
48
48
|
declare function findParentAttribute(node: TSESTree.Node, test?: (node: TSESTree.JSXAttribute) => boolean): TSESTree.JSXAttribute | null;
|
|
49
49
|
//#endregion
|
|
50
50
|
//#region src/get-attribute-name.d.ts
|
|
51
51
|
/**
|
|
52
|
-
* Get the stringified name of a `JSXAttribute` node
|
|
52
|
+
* Get the stringified name of a `JSXAttribute` node.
|
|
53
53
|
*
|
|
54
54
|
* Handles both simple identifiers and namespaced names:
|
|
55
55
|
* - `className` -> `"className"`
|
|
56
56
|
* - `aria-label` -> `"aria-label"`
|
|
57
|
-
* - `xml:space` -> `"xml:space"
|
|
58
|
-
* @param node A `JSXAttribute` AST node
|
|
59
|
-
* @returns The attribute name as a plain string
|
|
57
|
+
* - `xml:space` -> `"xml:space"`.
|
|
58
|
+
* @param node A `JSXAttribute` AST node.
|
|
59
|
+
* @returns The attribute name as a plain string.
|
|
60
60
|
*/
|
|
61
61
|
declare function getAttributeName(node: TSESTree.JSXAttribute): string;
|
|
62
62
|
//#endregion
|
|
63
63
|
//#region src/get-attribute-static-value.d.ts
|
|
64
64
|
/**
|
|
65
65
|
* Find an attribute by name on a JSX element and collapse its value to a plain
|
|
66
|
-
* JavaScript value in a single step
|
|
66
|
+
* JavaScript value in a single step.
|
|
67
67
|
*
|
|
68
68
|
* This is a convenience composition of {@link findAttribute} ->
|
|
69
69
|
* {@link resolveAttributeValue} -> `toStatic()`, with automatic handling of the
|
|
@@ -72,60 +72,60 @@ declare function getAttributeName(node: TSESTree.JSXAttribute): string;
|
|
|
72
72
|
* Returns `null` when the attribute is absent, `undefined` when the value cannot
|
|
73
73
|
* be statically determined (including empty expression containers), and the
|
|
74
74
|
* resolved static value otherwise.
|
|
75
|
-
* @param context The ESLint rule context
|
|
76
|
-
* @param element The `JSXElement` node to inspect
|
|
77
|
-
* @param name The attribute name to look up (ex: "className")
|
|
78
|
-
* @returns The static value of the attribute, `null` when absent, or `undefined` when indeterminate
|
|
75
|
+
* @param context The ESLint rule context.
|
|
76
|
+
* @param element The `JSXElement` node to inspect.
|
|
77
|
+
* @param name The attribute name to look up (ex: "className").
|
|
78
|
+
* @returns The static value of the attribute, `null` when absent, or `undefined` when indeterminate.
|
|
79
79
|
*/
|
|
80
80
|
declare function getAttributeStaticValue(context: RuleContext, element: TSESTree.JSXElement, name: string): unknown;
|
|
81
81
|
//#endregion
|
|
82
82
|
//#region src/jsx-attribute-value.d.ts
|
|
83
83
|
/**
|
|
84
|
-
* Discriminated union representing the resolved value of a JSX attribute
|
|
84
|
+
* Discriminated union representing the resolved value of a JSX attribute.
|
|
85
85
|
*
|
|
86
86
|
* Each variant carries the original AST `node` (where applicable) and a
|
|
87
87
|
* `toStatic()` helper that attempts to collapse the value into a plain
|
|
88
88
|
* JavaScript value at analysis time.
|
|
89
89
|
*/
|
|
90
90
|
type JsxAttributeValue = JsxAttributeValueBoolean | JsxAttributeValueElement | JsxAttributeValueLiteral | JsxAttributeValueUnknown | JsxAttributeValueMissing | JsxAttributeValueSpreadChild | JsxAttributeValueSpreadProps;
|
|
91
|
-
/** Boolean attribute with no value (ex: `<input disabled />`) */
|
|
91
|
+
/** Boolean attribute with no value (ex: `<input disabled />`). */
|
|
92
92
|
interface JsxAttributeValueBoolean {
|
|
93
93
|
readonly kind: "boolean";
|
|
94
94
|
readonly node: null;
|
|
95
95
|
toStatic(): true;
|
|
96
96
|
}
|
|
97
|
-
/** JSX element used as an attribute value (ex: `<Slot icon=<Icon /> />`) */
|
|
97
|
+
/** JSX element used as an attribute value (ex: `<Slot icon=<Icon /> />`). */
|
|
98
98
|
interface JsxAttributeValueElement {
|
|
99
99
|
readonly kind: "element";
|
|
100
100
|
readonly node: TSESTree.JSXElement;
|
|
101
101
|
toStatic(): null;
|
|
102
102
|
}
|
|
103
|
-
/** Literal value (ex: `<img alt="photo" />`) */
|
|
103
|
+
/** Literal value (ex: `<img alt="photo" />`). */
|
|
104
104
|
interface JsxAttributeValueLiteral {
|
|
105
105
|
readonly kind: "literal";
|
|
106
106
|
readonly node: TSESTree.Literal;
|
|
107
107
|
toStatic(): TSESTree.Literal["value"];
|
|
108
108
|
}
|
|
109
|
-
/** Expression container value (ex: `<Comp value={expr} />`) */
|
|
109
|
+
/** Expression container value (ex: `<Comp value={expr} />`). */
|
|
110
110
|
interface JsxAttributeValueUnknown {
|
|
111
111
|
readonly kind: "unknown";
|
|
112
112
|
readonly node: TSESTree.JSXExpressionContainer["expression"];
|
|
113
113
|
toStatic(): unknown;
|
|
114
114
|
}
|
|
115
|
-
/** Empty expression container (ex: `<Comp value={} />`) */
|
|
115
|
+
/** Empty expression container (ex: `<Comp value={} />`). */
|
|
116
116
|
interface JsxAttributeValueMissing {
|
|
117
117
|
readonly kind: "missing";
|
|
118
118
|
readonly node: TSESTree.JSXEmptyExpression;
|
|
119
119
|
toStatic(): null;
|
|
120
120
|
}
|
|
121
|
-
/** Spread child expression (ex: `{...items}` as children) */
|
|
121
|
+
/** Spread child expression (ex: `{...items}` as children). */
|
|
122
122
|
interface JsxAttributeValueSpreadChild {
|
|
123
123
|
readonly kind: "spreadChild";
|
|
124
124
|
getChildren(): unknown;
|
|
125
125
|
readonly node: TSESTree.JSXSpreadChild["expression"];
|
|
126
126
|
toStatic(): null;
|
|
127
127
|
}
|
|
128
|
-
/** Spread props (ex: `<Comp {...props} />`) */
|
|
128
|
+
/** Spread props (ex: `<Comp {...props} />`). */
|
|
129
129
|
interface JsxAttributeValueSpreadProps {
|
|
130
130
|
readonly kind: "spreadProps";
|
|
131
131
|
getProperty(name: string): unknown;
|
|
@@ -135,21 +135,21 @@ interface JsxAttributeValueSpreadProps {
|
|
|
135
135
|
//#endregion
|
|
136
136
|
//#region src/get-attribute-value.d.ts
|
|
137
137
|
/**
|
|
138
|
-
* Find an attribute by name on a JSX element and resolve its value in a single call
|
|
138
|
+
* Find an attribute by name on a JSX element and resolve its value in a single call.
|
|
139
139
|
*
|
|
140
140
|
* This is a convenience composition of {@link findAttribute} and
|
|
141
141
|
* {@link resolveAttributeValue} that eliminates the most common two-step
|
|
142
142
|
* pattern in lint rules.
|
|
143
|
-
* @param context The ESLint rule context
|
|
144
|
-
* @param element The `JSXElement` node to search
|
|
145
|
-
* @param name The attribute name to look up (ex: "className")
|
|
146
|
-
* @returns A {@link JsxAttributeValue} descriptor, or `null` when the attribute is not present on the element
|
|
143
|
+
* @param context The ESLint rule context.
|
|
144
|
+
* @param element The `JSXElement` node to search.
|
|
145
|
+
* @param name The attribute name to look up (ex: "className").
|
|
146
|
+
* @returns A {@link JsxAttributeValue} descriptor, or `null` when the attribute is not present on the element.
|
|
147
147
|
*/
|
|
148
148
|
declare function getAttributeValue(context: RuleContext, element: TSESTree.JSXElement, name: string): JsxAttributeValue | null;
|
|
149
149
|
//#endregion
|
|
150
150
|
//#region src/get-children.d.ts
|
|
151
151
|
/**
|
|
152
|
-
* Get the meaningful children of a JSX element or fragment
|
|
152
|
+
* Get the meaningful children of a JSX element or fragment.
|
|
153
153
|
*
|
|
154
154
|
* Mirrors Babel's `buildChildren` helper:
|
|
155
155
|
* 1. Iterate over `element.children`.
|
|
@@ -157,69 +157,69 @@ declare function getAttributeValue(context: RuleContext, element: TSESTree.JSXEl
|
|
|
157
157
|
* 3. Skip `JSXExpressionContainer` nodes whose expression is empty.
|
|
158
158
|
* 4. Skip `JSXEmptyExpression` nodes.
|
|
159
159
|
* 5. Collect everything else.
|
|
160
|
-
* @param element A `JSXElement` or `JSXFragment` node
|
|
161
|
-
* @returns An array of children nodes that contribute to rendered output
|
|
160
|
+
* @param element A `JSXElement` or `JSXFragment` node.
|
|
161
|
+
* @returns An array of children nodes that contribute to rendered output.
|
|
162
162
|
*/
|
|
163
163
|
declare function getChildren(element: TSESTreeJSXElementLike): TSESTree.JSXChild[];
|
|
164
164
|
//#endregion
|
|
165
165
|
//#region src/get-element-type.d.ts
|
|
166
166
|
/**
|
|
167
|
-
* Get the string representation of a JSX element's type
|
|
167
|
+
* Get the string representation of a JSX element's type.
|
|
168
168
|
*
|
|
169
169
|
* - `<div>` -> `"div"`
|
|
170
170
|
* - `<Foo.Bar>` -> `"Foo.Bar"`
|
|
171
171
|
* - `<React.Fragment>` -> `"React.Fragment"`
|
|
172
|
-
* - `<></>` -> `""
|
|
173
|
-
* @param node A `JSXElement` or `JSXFragment` node
|
|
174
|
-
* @returns The fully-qualified element type string
|
|
172
|
+
* - `<></>` -> `""`.
|
|
173
|
+
* @param node A `JSXElement` or `JSXFragment` node.
|
|
174
|
+
* @returns The fully-qualified element type string.
|
|
175
175
|
*/
|
|
176
176
|
declare function getElementFullType(node: TSESTreeJSXElementLike): string;
|
|
177
177
|
/**
|
|
178
|
-
* Get the self name (last dot-separated segment) of a JSX element type
|
|
178
|
+
* Get the self name (last dot-separated segment) of a JSX element type.
|
|
179
179
|
*
|
|
180
180
|
* - `<Foo.Bar.Baz>` -> `"Baz"`
|
|
181
181
|
* - `<div>` -> `"div"`
|
|
182
|
-
* - `<></>` -> `""
|
|
183
|
-
* @param node A `JSXElement` or `JSXFragment` node
|
|
184
|
-
* @returns The last segment of the element type, or `""` for fragments
|
|
182
|
+
* - `<></>` -> `""`.
|
|
183
|
+
* @param node A `JSXElement` or `JSXFragment` node.
|
|
184
|
+
* @returns The last segment of the element type, or `""` for fragments.
|
|
185
185
|
*/
|
|
186
186
|
declare function getElementSelfType(node: TSESTreeJSXElementLike): string;
|
|
187
187
|
//#endregion
|
|
188
188
|
//#region src/has-any-attribute.d.ts
|
|
189
189
|
/**
|
|
190
|
-
* Check whether a JSX element carries at least one of the given attributes
|
|
190
|
+
* Check whether a JSX element carries at least one of the given attributes.
|
|
191
191
|
*
|
|
192
192
|
* This is a batch variant of {@link hasAttribute} for the common pattern of
|
|
193
193
|
* short-circuiting on multiple prop names.
|
|
194
194
|
*
|
|
195
195
|
* Spread attributes are taken into account (see {@link findAttribute}).
|
|
196
|
-
* @param context The ESLint rule context (needed for variable resolution in spread attributes)
|
|
197
|
-
* @param element The `JSXElement` node to inspect
|
|
198
|
-
* @param names The attribute names to look for
|
|
199
|
-
* @returns `true` when at least one of the attributes is present
|
|
196
|
+
* @param context The ESLint rule context (needed for variable resolution in spread attributes).
|
|
197
|
+
* @param element The `JSXElement` node to inspect.
|
|
198
|
+
* @param names The attribute names to look for.
|
|
199
|
+
* @returns `true` when at least one of the attributes is present.
|
|
200
200
|
*/
|
|
201
201
|
declare function hasAnyAttribute(context: RuleContext, element: TSESTree.JSXElement, names: string[]): boolean;
|
|
202
202
|
//#endregion
|
|
203
203
|
//#region src/has-attribute.d.ts
|
|
204
204
|
/**
|
|
205
|
-
* Check whether a JSX element carries a given attribute (prop)
|
|
205
|
+
* Check whether a JSX element carries a given attribute (prop).
|
|
206
206
|
*
|
|
207
207
|
* This is a thin convenience wrapper around {@link findAttribute} for the
|
|
208
208
|
* common case where you only need a boolean answer.
|
|
209
209
|
*
|
|
210
210
|
* Spread attributes are taken into account: `<Comp {...{ disabled: true }} />`
|
|
211
211
|
* will report `true` for `"disabled"`.
|
|
212
|
-
* @param context The ESLint rule context (needed for variable resolution in spread attributes)
|
|
213
|
-
* @param element The `JSXElement` node to inspect
|
|
214
|
-
* @param name The attribute name to look for (ex: "className")
|
|
215
|
-
* @returns `true` when the attribute is present on the element
|
|
212
|
+
* @param context The ESLint rule context (needed for variable resolution in spread attributes).
|
|
213
|
+
* @param element The `JSXElement` node to inspect.
|
|
214
|
+
* @param name The attribute name to look for (ex: "className").
|
|
215
|
+
* @returns `true` when the attribute is present on the element.
|
|
216
216
|
*/
|
|
217
217
|
declare function hasAttribute(context: RuleContext, element: TSESTree.JSXElement, name: string): boolean;
|
|
218
218
|
//#endregion
|
|
219
219
|
//#region src/has-children.d.ts
|
|
220
220
|
/**
|
|
221
221
|
* Check whether a JSX element (or fragment) has meaningful children, that is,
|
|
222
|
-
* at least one child that is not purely whitespace text or an empty string expression
|
|
222
|
+
* at least one child that is not purely whitespace text or an empty string expression.
|
|
223
223
|
*
|
|
224
224
|
* A `JSXText` child whose `raw` content is empty after trimming is considered
|
|
225
225
|
* non-meaningful because it is typically a code-formatting artifact
|
|
@@ -236,38 +236,38 @@ declare function hasAttribute(context: RuleContext, element: TSESTree.JSXElement
|
|
|
236
236
|
* always equal to `getChildren(node).length > 0`: they differ for
|
|
237
237
|
* whitespace-only children that have no newline, such as `<div> </div>` or
|
|
238
238
|
* `<div>\t\t</div>`. Choose the API that matches your rule's intent.
|
|
239
|
-
* @param element A `JSXElement` or `JSXFragment` node
|
|
240
|
-
* @returns `true` when the element has at least one meaningful child
|
|
239
|
+
* @param element A `JSXElement` or `JSXFragment` node.
|
|
240
|
+
* @returns `true` when the element has at least one meaningful child.
|
|
241
241
|
*/
|
|
242
242
|
declare function hasChildren(element: TSESTreeJSXElementLike): boolean;
|
|
243
243
|
//#endregion
|
|
244
244
|
//#region src/has-every-attribute.d.ts
|
|
245
245
|
/**
|
|
246
|
-
* Check whether a JSX element carries all of the given attributes (props)
|
|
246
|
+
* Check whether a JSX element carries all of the given attributes (props).
|
|
247
247
|
*
|
|
248
248
|
* This is a batch variant of {@link hasAttribute} for the common pattern
|
|
249
249
|
* where a rule needs to verify that a set of required props are all present.
|
|
250
250
|
*
|
|
251
251
|
* Spread attributes are taken into account (see {@link findAttribute}).
|
|
252
|
-
* @param context The ESLint rule context (needed for variable resolution in spread attributes)
|
|
253
|
-
* @param element The `JSXElement` node to inspect
|
|
254
|
-
* @param names The attribute names to look for
|
|
255
|
-
* @returns `true` when every name in `names` is present on the element
|
|
252
|
+
* @param context The ESLint rule context (needed for variable resolution in spread attributes).
|
|
253
|
+
* @param element The `JSXElement` node to inspect.
|
|
254
|
+
* @param names The attribute names to look for.
|
|
255
|
+
* @returns `true` when every name in `names` is present on the element.
|
|
256
256
|
*/
|
|
257
257
|
declare function hasEveryAttribute(context: RuleContext, element: TSESTree.JSXElement, names: string[]): boolean;
|
|
258
258
|
//#endregion
|
|
259
259
|
//#region src/is-element.d.ts
|
|
260
260
|
/**
|
|
261
|
-
* A test that determines whether a JSX element matches
|
|
261
|
+
* A test that determines whether a JSX element matches.
|
|
262
262
|
*
|
|
263
263
|
* - `string` matches against the full element type (ex: "div", "React.Fragment")
|
|
264
264
|
* - `string[]` matches when the element type equals any of the given strings
|
|
265
|
-
* - `function` receives the element type string and returns a boolean
|
|
265
|
+
* - `function` receives the element type string and returns a boolean.
|
|
266
266
|
*/
|
|
267
267
|
type ElementTest = string | readonly string[] | ((elementType: string, node: TSESTreeJSXElementLike) => boolean);
|
|
268
268
|
/**
|
|
269
269
|
* Check whether a node is a `JSXElement` (or `JSXFragment`) and optionally
|
|
270
|
-
* matches a given test
|
|
270
|
+
* matches a given test.
|
|
271
271
|
*
|
|
272
272
|
* Modelled after
|
|
273
273
|
* [`hast-util-is-element`](https://github.com/syntax-tree/hast-util-is-element):
|
|
@@ -275,15 +275,15 @@ type ElementTest = string | readonly string[] | ((elementType: string, node: TSE
|
|
|
275
275
|
*
|
|
276
276
|
* When called without a test, the function acts as a simple type-guard
|
|
277
277
|
* for `JSXElement | JSXFragment`.
|
|
278
|
-
* @param node The AST node to test
|
|
279
|
-
* @param test Optional test to match the element type against
|
|
280
|
-
* @returns `true` when the node is a matching JSX element
|
|
278
|
+
* @param node The AST node to test.
|
|
279
|
+
* @param test Optional test to match the element type against.
|
|
280
|
+
* @returns `true` when the node is a matching JSX element.
|
|
281
281
|
*/
|
|
282
282
|
declare function isElement(node: TSESTree.Node | null | undefined, test?: ElementTest): node is TSESTreeJSXElementLike;
|
|
283
283
|
//#endregion
|
|
284
284
|
//#region src/is-fragment-element.d.ts
|
|
285
285
|
/**
|
|
286
|
-
* Check whether a node is a React Fragment element
|
|
286
|
+
* Check whether a node is a React Fragment element.
|
|
287
287
|
*
|
|
288
288
|
* Recognizes both the shorthand `<>...</>` syntax (`JSXFragment`) and the
|
|
289
289
|
* explicit `<Fragment>` / `<React.Fragment>` form (`JSXElement`).
|
|
@@ -291,70 +291,70 @@ declare function isElement(node: TSESTree.Node | null | undefined, test?: Elemen
|
|
|
291
291
|
* The comparison is performed against the self name (last dot-separated
|
|
292
292
|
* segment) of both the node and the configured factory, so `<React.Fragment>`
|
|
293
293
|
* matches `"React.Fragment"` and `<Fragment>` matches `"Fragment"`.
|
|
294
|
-
* @param node The AST node to test
|
|
295
|
-
* @param jsxFragmentFactory The configured fragment factory string (ex: "React.Fragment")
|
|
296
|
-
* @returns `true` when the node represents a React Fragment
|
|
294
|
+
* @param node The AST node to test.
|
|
295
|
+
* @param jsxFragmentFactory The configured fragment factory string (ex: "React.Fragment").
|
|
296
|
+
* @returns `true` when the node represents a React Fragment.
|
|
297
297
|
*/
|
|
298
298
|
declare function isFragmentElement(node: TSESTree.Node, jsxFragmentFactory?: string): node is TSESTreeJSXElementLike;
|
|
299
299
|
//#endregion
|
|
300
300
|
//#region src/is-host-element.d.ts
|
|
301
301
|
/**
|
|
302
|
-
* Check whether a node is a host (intrinsic / DOM) element
|
|
302
|
+
* Check whether a node is a host (intrinsic / DOM) element.
|
|
303
303
|
*
|
|
304
304
|
* A host element is a `JSXElement` whose tag name is a plain `JSXIdentifier`
|
|
305
305
|
* starting with a lowercase letter, the same heuristic React uses to
|
|
306
306
|
* distinguish `<div>` from `<MyComponent>`.
|
|
307
|
-
* @param node The AST node to test
|
|
308
|
-
* @returns `true` when the node is a `JSXElement` with a lowercase tag name
|
|
307
|
+
* @param node The AST node to test.
|
|
308
|
+
* @returns `true` when the node is a `JSXElement` with a lowercase tag name.
|
|
309
309
|
*/
|
|
310
310
|
declare function isHostElement(node: TSESTree.Node): node is TSESTree.JSXElement;
|
|
311
311
|
//#endregion
|
|
312
312
|
//#region src/is-whitespace.d.ts
|
|
313
313
|
/**
|
|
314
314
|
* Check whether a JSX child node is whitespace padding that React would
|
|
315
|
-
* trim away during rendering
|
|
315
|
+
* trim away during rendering.
|
|
316
316
|
*
|
|
317
317
|
* A child is considered whitespace padding when it is a `JSXText` node whose
|
|
318
318
|
* content is empty after applying React's whitespace normalization
|
|
319
319
|
* (see {@link collapseMultilineText}, modelled after Babel's
|
|
320
320
|
* `cleanJSXElementLiteralChild`). This is the whitespace that appears between
|
|
321
321
|
* JSX tags purely for formatting.
|
|
322
|
-
* @param node A JSX child node
|
|
323
|
-
* @returns `true` when the node is purely formatting whitespace
|
|
322
|
+
* @param node A JSX child node.
|
|
323
|
+
* @returns `true` when the node is purely formatting whitespace.
|
|
324
324
|
*/
|
|
325
325
|
declare function isWhitespace(node: TSESTree.JSXChild): boolean;
|
|
326
326
|
/**
|
|
327
|
-
* Check whether a JSX child node is any whitespace-only text
|
|
327
|
+
* Check whether a JSX child node is any whitespace-only text.
|
|
328
328
|
*
|
|
329
329
|
* This is a looser variant of {@link isWhitespace}; it matches every
|
|
330
330
|
* `JSXText` node whose raw content is empty after trimming, regardless of
|
|
331
331
|
* whether it contains a newline.
|
|
332
|
-
* @param node A JSX child node
|
|
333
|
-
* @returns `true` when the node is a whitespace-only `JSXText
|
|
332
|
+
* @param node A JSX child node.
|
|
333
|
+
* @returns `true` when the node is a whitespace-only `JSXText`.
|
|
334
334
|
*/
|
|
335
335
|
declare function isWhitespaceText(node: TSESTree.JSXChild): boolean;
|
|
336
336
|
/**
|
|
337
|
-
* Check whether a JSX child node is an empty string expression (`{""}`)
|
|
337
|
+
* Check whether a JSX child node is an empty string expression (`{""}`).
|
|
338
338
|
*
|
|
339
339
|
* React's reconciler and SSR renderer explicitly skip empty strings,
|
|
340
340
|
* producing no DOM node (see `ReactChildFiber.js` and `ReactFizzConfigDOM.js`).
|
|
341
341
|
* Such expressions are therefore treated as non-rendered children, in the same
|
|
342
342
|
* way as whitespace padding.
|
|
343
|
-
* @param node A JSX child node
|
|
344
|
-
* @returns `true` when the node is a `{""}` expression container
|
|
343
|
+
* @param node A JSX child node.
|
|
344
|
+
* @returns `true` when the node is a `{""}` expression container.
|
|
345
345
|
*/
|
|
346
346
|
declare function isEmptyStringExpression(node: TSESTree.JSXChild): boolean;
|
|
347
347
|
//#endregion
|
|
348
348
|
//#region src/jsx-detection-hint.d.ts
|
|
349
349
|
/**
|
|
350
|
-
* BitFlags for configuring JSX detection behavior
|
|
350
|
+
* BitFlags for configuring JSX detection behavior.
|
|
351
351
|
*
|
|
352
352
|
* Used by `isJsxLike` to control which AST node kinds are considered
|
|
353
353
|
* "JSX-like". Combine flags with the `|` operator.
|
|
354
354
|
*/
|
|
355
355
|
type JsxDetectionHint = bigint;
|
|
356
356
|
/**
|
|
357
|
-
* Hints for JSX detection
|
|
357
|
+
* Hints for JSX detection.
|
|
358
358
|
*/
|
|
359
359
|
declare const JsxDetectionHint: {
|
|
360
360
|
readonly None: 0n;
|
|
@@ -371,7 +371,7 @@ declare const JsxDetectionHint: {
|
|
|
371
371
|
readonly RequireBothBranchesOfConditionalExpressionToBeJsx: bigint;
|
|
372
372
|
};
|
|
373
373
|
/**
|
|
374
|
-
* Default JSX detection hint
|
|
374
|
+
* Default JSX detection hint.
|
|
375
375
|
*
|
|
376
376
|
* Skips number, bigint, boolean, string, and undefined literals,
|
|
377
377
|
* the value types that are commonly returned alongside JSX in React
|
|
@@ -382,14 +382,14 @@ declare const DEFAULT_JSX_DETECTION_HINT: JsxDetectionHint;
|
|
|
382
382
|
//#region src/resolve-attribute-value.d.ts
|
|
383
383
|
/**
|
|
384
384
|
* Resolve the value of a JSX attribute (or spread attribute) into a
|
|
385
|
-
* {@link JsxAttributeValue} descriptor that can be inspected further
|
|
385
|
+
* {@link JsxAttributeValue} descriptor that can be inspected further.
|
|
386
386
|
*
|
|
387
387
|
* This is the low-level building block; it operates on a single attribute
|
|
388
388
|
* node that the caller has already located. For the higher-level "find by
|
|
389
389
|
* name and resolve" combo, see {@link getAttributeValue}.
|
|
390
|
-
* @param context The ESLint rule context (needed for scope look-ups)
|
|
391
|
-
* @param attribute A `JSXAttribute` or `JSXSpreadAttribute` node
|
|
392
|
-
* @returns A discriminated-union descriptor of the attribute's value
|
|
390
|
+
* @param context The ESLint rule context (needed for scope look-ups).
|
|
391
|
+
* @param attribute A `JSXAttribute` or `JSXSpreadAttribute` node.
|
|
392
|
+
* @returns A discriminated-union descriptor of the attribute's value.
|
|
393
393
|
*/
|
|
394
394
|
declare function resolveAttributeValue(context: RuleContext, attribute: TSESTreeJSXAttributeLike): JsxAttributeValue;
|
|
395
395
|
//#endregion
|
package/dist/index.js
CHANGED
|
@@ -6,7 +6,7 @@ import { P, match } from "ts-pattern";
|
|
|
6
6
|
|
|
7
7
|
//#region src/collapse-multiline-text.ts
|
|
8
8
|
/**
|
|
9
|
-
* Collapse a multiline JSX text string following React's whitespace rules
|
|
9
|
+
* Collapse a multiline JSX text string following React's whitespace rules.
|
|
10
10
|
*
|
|
11
11
|
* This mirrors Babel's `cleanJSXElementLiteralChild` algorithm:
|
|
12
12
|
* 1. Split the raw text into lines.
|
|
@@ -14,8 +14,8 @@ import { P, match } from "ts-pattern";
|
|
|
14
14
|
* 3. Trim leading spaces on non-first lines and trailing spaces on non-last lines.
|
|
15
15
|
* 4. Collapse tabs into spaces.
|
|
16
16
|
* 5. Append a single space after each non-last non-empty line.
|
|
17
|
-
* @param text The raw JSX text string to collapse
|
|
18
|
-
* @returns The collapsed string, or `null` if the text contains only whitespace
|
|
17
|
+
* @param text The raw JSX text string to collapse.
|
|
18
|
+
* @returns The collapsed string, or `null` if the text contains only whitespace.
|
|
19
19
|
* @see https://github.com/babel/babel/blob/main/packages/babel-types/src/utils/react/cleanJSXElementLiteralChild.ts
|
|
20
20
|
*/
|
|
21
21
|
function collapseMultilineText(text) {
|
|
@@ -42,14 +42,14 @@ function collapseMultilineText(text) {
|
|
|
42
42
|
//#endregion
|
|
43
43
|
//#region src/get-attribute-name.ts
|
|
44
44
|
/**
|
|
45
|
-
* Get the stringified name of a `JSXAttribute` node
|
|
45
|
+
* Get the stringified name of a `JSXAttribute` node.
|
|
46
46
|
*
|
|
47
47
|
* Handles both simple identifiers and namespaced names:
|
|
48
48
|
* - `className` -> `"className"`
|
|
49
49
|
* - `aria-label` -> `"aria-label"`
|
|
50
|
-
* - `xml:space` -> `"xml:space"
|
|
51
|
-
* @param node A `JSXAttribute` AST node
|
|
52
|
-
* @returns The attribute name as a plain string
|
|
50
|
+
* - `xml:space` -> `"xml:space"`.
|
|
51
|
+
* @param node A `JSXAttribute` AST node.
|
|
52
|
+
* @returns The attribute name as a plain string.
|
|
53
53
|
*/
|
|
54
54
|
function getAttributeName(node) {
|
|
55
55
|
if (node.name.type === AST_NODE_TYPES.JSXIdentifier) return node.name.name;
|
|
@@ -59,7 +59,7 @@ function getAttributeName(node) {
|
|
|
59
59
|
//#endregion
|
|
60
60
|
//#region src/find-attribute.ts
|
|
61
61
|
/**
|
|
62
|
-
* Find a JSX attribute (or spread attribute containing the property) by name on a given element
|
|
62
|
+
* Find a JSX attribute (or spread attribute containing the property) by name on a given element.
|
|
63
63
|
*
|
|
64
64
|
* Returns the last matching attribute to mirror React's behavior where later props win,
|
|
65
65
|
* or `undefined` when the attribute is not present.
|
|
@@ -67,10 +67,10 @@ function getAttributeName(node) {
|
|
|
67
67
|
* Spread attributes are resolved when possible: if the spread argument is an identifier
|
|
68
68
|
* that resolves to an object expression, the object's properties are searched for a matching key.
|
|
69
69
|
* Nested object expressions and nested spread identifiers are also resolved.
|
|
70
|
-
* @param context The ESLint rule context (needed for variable resolution in spread attributes)
|
|
71
|
-
* @param element The `JSXElement` node to search
|
|
72
|
-
* @param name The attribute name to look for (ex: "className")
|
|
73
|
-
* @returns The matching `JSXAttribute` or `JSXSpreadAttribute`, or `undefined` when not found
|
|
70
|
+
* @param context The ESLint rule context (needed for variable resolution in spread attributes).
|
|
71
|
+
* @param element The `JSXElement` node to search.
|
|
72
|
+
* @param name The attribute name to look for (ex: "className").
|
|
73
|
+
* @returns The matching `JSXAttribute` or `JSXSpreadAttribute`, or `undefined` when not found.
|
|
74
74
|
*/
|
|
75
75
|
function findAttribute(context, element, name) {
|
|
76
76
|
function findProperty(properties, name, seen = /* @__PURE__ */ new Set()) {
|
|
@@ -115,13 +115,13 @@ function findAttribute(context, element, name) {
|
|
|
115
115
|
//#region src/find-parent-attribute.ts
|
|
116
116
|
/**
|
|
117
117
|
* Walk up the AST from `node` to find the nearest ancestor that is a `JSXAttribute`
|
|
118
|
-
* and (optionally) passes a predicate
|
|
118
|
+
* and (optionally) passes a predicate.
|
|
119
119
|
*
|
|
120
120
|
* This is useful when a rule visitor enters a deeply nested node (ex: a `Literal`
|
|
121
121
|
* inside an expression container) and needs to know which JSX attribute it belongs to.
|
|
122
|
-
* @param node The starting node for the upward search
|
|
123
|
-
* @param test Optional predicate to filter candidate `JSXAttribute` nodes. When omitted every `JSXAttribute` ancestor matches
|
|
124
|
-
* @returns The first matching `JSXAttribute` ancestor, or `null` if none is found before reaching the root
|
|
122
|
+
* @param node The starting node for the upward search.
|
|
123
|
+
* @param test Optional predicate to filter candidate `JSXAttribute` nodes. When omitted every `JSXAttribute` ancestor matches.
|
|
124
|
+
* @returns The first matching `JSXAttribute` ancestor, or `null` if none is found before reaching the root.
|
|
125
125
|
*/
|
|
126
126
|
function findParentAttribute(node, test = () => true) {
|
|
127
127
|
const guard = (n) => {
|
|
@@ -134,14 +134,14 @@ function findParentAttribute(node, test = () => true) {
|
|
|
134
134
|
//#region src/resolve-attribute-value.ts
|
|
135
135
|
/**
|
|
136
136
|
* Resolve the value of a JSX attribute (or spread attribute) into a
|
|
137
|
-
* {@link JsxAttributeValue} descriptor that can be inspected further
|
|
137
|
+
* {@link JsxAttributeValue} descriptor that can be inspected further.
|
|
138
138
|
*
|
|
139
139
|
* This is the low-level building block; it operates on a single attribute
|
|
140
140
|
* node that the caller has already located. For the higher-level "find by
|
|
141
141
|
* name and resolve" combo, see {@link getAttributeValue}.
|
|
142
|
-
* @param context The ESLint rule context (needed for scope look-ups)
|
|
143
|
-
* @param attribute A `JSXAttribute` or `JSXSpreadAttribute` node
|
|
144
|
-
* @returns A discriminated-union descriptor of the attribute's value
|
|
142
|
+
* @param context The ESLint rule context (needed for scope look-ups).
|
|
143
|
+
* @param attribute A `JSXAttribute` or `JSXSpreadAttribute` node.
|
|
144
|
+
* @returns A discriminated-union descriptor of the attribute's value.
|
|
145
145
|
*/
|
|
146
146
|
function resolveAttributeValue(context, attribute) {
|
|
147
147
|
if (attribute.type === AST_NODE_TYPES.JSXAttribute) return resolveJsxAttribute(context, attribute);
|
|
@@ -221,7 +221,7 @@ function resolveJsxSpreadAttribute(context, node) {
|
|
|
221
221
|
//#region src/get-attribute-static-value.ts
|
|
222
222
|
/**
|
|
223
223
|
* Find an attribute by name on a JSX element and collapse its value to a plain
|
|
224
|
-
* JavaScript value in a single step
|
|
224
|
+
* JavaScript value in a single step.
|
|
225
225
|
*
|
|
226
226
|
* This is a convenience composition of {@link findAttribute} ->
|
|
227
227
|
* {@link resolveAttributeValue} -> `toStatic()`, with automatic handling of the
|
|
@@ -230,10 +230,10 @@ function resolveJsxSpreadAttribute(context, node) {
|
|
|
230
230
|
* Returns `null` when the attribute is absent, `undefined` when the value cannot
|
|
231
231
|
* be statically determined (including empty expression containers), and the
|
|
232
232
|
* resolved static value otherwise.
|
|
233
|
-
* @param context The ESLint rule context
|
|
234
|
-
* @param element The `JSXElement` node to inspect
|
|
235
|
-
* @param name The attribute name to look up (ex: "className")
|
|
236
|
-
* @returns The static value of the attribute, `null` when absent, or `undefined` when indeterminate
|
|
233
|
+
* @param context The ESLint rule context.
|
|
234
|
+
* @param element The `JSXElement` node to inspect.
|
|
235
|
+
* @param name The attribute name to look up (ex: "className").
|
|
236
|
+
* @returns The static value of the attribute, `null` when absent, or `undefined` when indeterminate.
|
|
237
237
|
*/
|
|
238
238
|
function getAttributeStaticValue(context, element, name) {
|
|
239
239
|
const attr = findAttribute(context, element, name);
|
|
@@ -247,15 +247,15 @@ function getAttributeStaticValue(context, element, name) {
|
|
|
247
247
|
//#endregion
|
|
248
248
|
//#region src/get-attribute-value.ts
|
|
249
249
|
/**
|
|
250
|
-
* Find an attribute by name on a JSX element and resolve its value in a single call
|
|
250
|
+
* Find an attribute by name on a JSX element and resolve its value in a single call.
|
|
251
251
|
*
|
|
252
252
|
* This is a convenience composition of {@link findAttribute} and
|
|
253
253
|
* {@link resolveAttributeValue} that eliminates the most common two-step
|
|
254
254
|
* pattern in lint rules.
|
|
255
|
-
* @param context The ESLint rule context
|
|
256
|
-
* @param element The `JSXElement` node to search
|
|
257
|
-
* @param name The attribute name to look up (ex: "className")
|
|
258
|
-
* @returns A {@link JsxAttributeValue} descriptor, or `null` when the attribute is not present on the element
|
|
255
|
+
* @param context The ESLint rule context.
|
|
256
|
+
* @param element The `JSXElement` node to search.
|
|
257
|
+
* @param name The attribute name to look up (ex: "className").
|
|
258
|
+
* @returns A {@link JsxAttributeValue} descriptor, or `null` when the attribute is not present on the element.
|
|
259
259
|
*/
|
|
260
260
|
function getAttributeValue(context, element, name) {
|
|
261
261
|
const attr = findAttribute(context, element, name);
|
|
@@ -267,42 +267,42 @@ function getAttributeValue(context, element, name) {
|
|
|
267
267
|
//#region src/is-whitespace.ts
|
|
268
268
|
/**
|
|
269
269
|
* Check whether a JSX child node is whitespace padding that React would
|
|
270
|
-
* trim away during rendering
|
|
270
|
+
* trim away during rendering.
|
|
271
271
|
*
|
|
272
272
|
* A child is considered whitespace padding when it is a `JSXText` node whose
|
|
273
273
|
* content is empty after applying React's whitespace normalization
|
|
274
274
|
* (see {@link collapseMultilineText}, modelled after Babel's
|
|
275
275
|
* `cleanJSXElementLiteralChild`). This is the whitespace that appears between
|
|
276
276
|
* JSX tags purely for formatting.
|
|
277
|
-
* @param node A JSX child node
|
|
278
|
-
* @returns `true` when the node is purely formatting whitespace
|
|
277
|
+
* @param node A JSX child node.
|
|
278
|
+
* @returns `true` when the node is purely formatting whitespace.
|
|
279
279
|
*/
|
|
280
280
|
function isWhitespace(node) {
|
|
281
281
|
if (node.type !== AST_NODE_TYPES.JSXText) return false;
|
|
282
282
|
return collapseMultilineText(node.value) == null && node.value.includes("\n");
|
|
283
283
|
}
|
|
284
284
|
/**
|
|
285
|
-
* Check whether a JSX child node is any whitespace-only text
|
|
285
|
+
* Check whether a JSX child node is any whitespace-only text.
|
|
286
286
|
*
|
|
287
287
|
* This is a looser variant of {@link isWhitespace}; it matches every
|
|
288
288
|
* `JSXText` node whose raw content is empty after trimming, regardless of
|
|
289
289
|
* whether it contains a newline.
|
|
290
|
-
* @param node A JSX child node
|
|
291
|
-
* @returns `true` when the node is a whitespace-only `JSXText
|
|
290
|
+
* @param node A JSX child node.
|
|
291
|
+
* @returns `true` when the node is a whitespace-only `JSXText`.
|
|
292
292
|
*/
|
|
293
293
|
function isWhitespaceText(node) {
|
|
294
294
|
if (node.type !== AST_NODE_TYPES.JSXText) return false;
|
|
295
295
|
return node.raw.trim() === "";
|
|
296
296
|
}
|
|
297
297
|
/**
|
|
298
|
-
* Check whether a JSX child node is an empty string expression (`{""}`)
|
|
298
|
+
* Check whether a JSX child node is an empty string expression (`{""}`).
|
|
299
299
|
*
|
|
300
300
|
* React's reconciler and SSR renderer explicitly skip empty strings,
|
|
301
301
|
* producing no DOM node (see `ReactChildFiber.js` and `ReactFizzConfigDOM.js`).
|
|
302
302
|
* Such expressions are therefore treated as non-rendered children, in the same
|
|
303
303
|
* way as whitespace padding.
|
|
304
|
-
* @param node A JSX child node
|
|
305
|
-
* @returns `true` when the node is a `{""}` expression container
|
|
304
|
+
* @param node A JSX child node.
|
|
305
|
+
* @returns `true` when the node is a `{""}` expression container.
|
|
306
306
|
*/
|
|
307
307
|
function isEmptyStringExpression(node) {
|
|
308
308
|
if (node.type !== AST_NODE_TYPES.JSXExpressionContainer) return false;
|
|
@@ -314,7 +314,7 @@ function isEmptyStringExpression(node) {
|
|
|
314
314
|
//#endregion
|
|
315
315
|
//#region src/get-children.ts
|
|
316
316
|
/**
|
|
317
|
-
* Get the meaningful children of a JSX element or fragment
|
|
317
|
+
* Get the meaningful children of a JSX element or fragment.
|
|
318
318
|
*
|
|
319
319
|
* Mirrors Babel's `buildChildren` helper:
|
|
320
320
|
* 1. Iterate over `element.children`.
|
|
@@ -322,8 +322,8 @@ function isEmptyStringExpression(node) {
|
|
|
322
322
|
* 3. Skip `JSXExpressionContainer` nodes whose expression is empty.
|
|
323
323
|
* 4. Skip `JSXEmptyExpression` nodes.
|
|
324
324
|
* 5. Collect everything else.
|
|
325
|
-
* @param element A `JSXElement` or `JSXFragment` node
|
|
326
|
-
* @returns An array of children nodes that contribute to rendered output
|
|
325
|
+
* @param element A `JSXElement` or `JSXFragment` node.
|
|
326
|
+
* @returns An array of children nodes that contribute to rendered output.
|
|
327
327
|
*/
|
|
328
328
|
function getChildren(element) {
|
|
329
329
|
const elements = [];
|
|
@@ -348,14 +348,14 @@ function getChildren(element) {
|
|
|
348
348
|
//#endregion
|
|
349
349
|
//#region src/get-element-type.ts
|
|
350
350
|
/**
|
|
351
|
-
* Get the string representation of a JSX element's type
|
|
351
|
+
* Get the string representation of a JSX element's type.
|
|
352
352
|
*
|
|
353
353
|
* - `<div>` -> `"div"`
|
|
354
354
|
* - `<Foo.Bar>` -> `"Foo.Bar"`
|
|
355
355
|
* - `<React.Fragment>` -> `"React.Fragment"`
|
|
356
|
-
* - `<></>` -> `""
|
|
357
|
-
* @param node A `JSXElement` or `JSXFragment` node
|
|
358
|
-
* @returns The fully-qualified element type string
|
|
356
|
+
* - `<></>` -> `""`.
|
|
357
|
+
* @param node A `JSXElement` or `JSXFragment` node.
|
|
358
|
+
* @returns The fully-qualified element type string.
|
|
359
359
|
*/
|
|
360
360
|
function getElementFullType(node) {
|
|
361
361
|
if (node.type === AST_NODE_TYPES.JSXFragment) return "";
|
|
@@ -369,13 +369,13 @@ function getElementFullType(node) {
|
|
|
369
369
|
return getQualifiedName(node.openingElement.name);
|
|
370
370
|
}
|
|
371
371
|
/**
|
|
372
|
-
* Get the self name (last dot-separated segment) of a JSX element type
|
|
372
|
+
* Get the self name (last dot-separated segment) of a JSX element type.
|
|
373
373
|
*
|
|
374
374
|
* - `<Foo.Bar.Baz>` -> `"Baz"`
|
|
375
375
|
* - `<div>` -> `"div"`
|
|
376
|
-
* - `<></>` -> `""
|
|
377
|
-
* @param node A `JSXElement` or `JSXFragment` node
|
|
378
|
-
* @returns The last segment of the element type, or `""` for fragments
|
|
376
|
+
* - `<></>` -> `""`.
|
|
377
|
+
* @param node A `JSXElement` or `JSXFragment` node.
|
|
378
|
+
* @returns The last segment of the element type, or `""` for fragments.
|
|
379
379
|
*/
|
|
380
380
|
function getElementSelfType(node) {
|
|
381
381
|
return getElementFullType(node).split(".").at(-1) ?? "";
|
|
@@ -384,16 +384,16 @@ function getElementSelfType(node) {
|
|
|
384
384
|
//#endregion
|
|
385
385
|
//#region src/has-any-attribute.ts
|
|
386
386
|
/**
|
|
387
|
-
* Check whether a JSX element carries at least one of the given attributes
|
|
387
|
+
* Check whether a JSX element carries at least one of the given attributes.
|
|
388
388
|
*
|
|
389
389
|
* This is a batch variant of {@link hasAttribute} for the common pattern of
|
|
390
390
|
* short-circuiting on multiple prop names.
|
|
391
391
|
*
|
|
392
392
|
* Spread attributes are taken into account (see {@link findAttribute}).
|
|
393
|
-
* @param context The ESLint rule context (needed for variable resolution in spread attributes)
|
|
394
|
-
* @param element The `JSXElement` node to inspect
|
|
395
|
-
* @param names The attribute names to look for
|
|
396
|
-
* @returns `true` when at least one of the attributes is present
|
|
393
|
+
* @param context The ESLint rule context (needed for variable resolution in spread attributes).
|
|
394
|
+
* @param element The `JSXElement` node to inspect.
|
|
395
|
+
* @param names The attribute names to look for.
|
|
396
|
+
* @returns `true` when at least one of the attributes is present.
|
|
397
397
|
*/
|
|
398
398
|
function hasAnyAttribute(context, element, names) {
|
|
399
399
|
return names.some((name) => findAttribute(context, element, name) != null);
|
|
@@ -402,17 +402,17 @@ function hasAnyAttribute(context, element, names) {
|
|
|
402
402
|
//#endregion
|
|
403
403
|
//#region src/has-attribute.ts
|
|
404
404
|
/**
|
|
405
|
-
* Check whether a JSX element carries a given attribute (prop)
|
|
405
|
+
* Check whether a JSX element carries a given attribute (prop).
|
|
406
406
|
*
|
|
407
407
|
* This is a thin convenience wrapper around {@link findAttribute} for the
|
|
408
408
|
* common case where you only need a boolean answer.
|
|
409
409
|
*
|
|
410
410
|
* Spread attributes are taken into account: `<Comp {...{ disabled: true }} />`
|
|
411
411
|
* will report `true` for `"disabled"`.
|
|
412
|
-
* @param context The ESLint rule context (needed for variable resolution in spread attributes)
|
|
413
|
-
* @param element The `JSXElement` node to inspect
|
|
414
|
-
* @param name The attribute name to look for (ex: "className")
|
|
415
|
-
* @returns `true` when the attribute is present on the element
|
|
412
|
+
* @param context The ESLint rule context (needed for variable resolution in spread attributes).
|
|
413
|
+
* @param element The `JSXElement` node to inspect.
|
|
414
|
+
* @param name The attribute name to look for (ex: "className").
|
|
415
|
+
* @returns `true` when the attribute is present on the element.
|
|
416
416
|
*/
|
|
417
417
|
function hasAttribute(context, element, name) {
|
|
418
418
|
return findAttribute(context, element, name) != null;
|
|
@@ -422,7 +422,7 @@ function hasAttribute(context, element, name) {
|
|
|
422
422
|
//#region src/has-children.ts
|
|
423
423
|
/**
|
|
424
424
|
* Check whether a JSX element (or fragment) has meaningful children, that is,
|
|
425
|
-
* at least one child that is not purely whitespace text or an empty string expression
|
|
425
|
+
* at least one child that is not purely whitespace text or an empty string expression.
|
|
426
426
|
*
|
|
427
427
|
* A `JSXText` child whose `raw` content is empty after trimming is considered
|
|
428
428
|
* non-meaningful because it is typically a code-formatting artifact
|
|
@@ -439,8 +439,8 @@ function hasAttribute(context, element, name) {
|
|
|
439
439
|
* always equal to `getChildren(node).length > 0`: they differ for
|
|
440
440
|
* whitespace-only children that have no newline, such as `<div> </div>` or
|
|
441
441
|
* `<div>\t\t</div>`. Choose the API that matches your rule's intent.
|
|
442
|
-
* @param element A `JSXElement` or `JSXFragment` node
|
|
443
|
-
* @returns `true` when the element has at least one meaningful child
|
|
442
|
+
* @param element A `JSXElement` or `JSXFragment` node.
|
|
443
|
+
* @returns `true` when the element has at least one meaningful child.
|
|
444
444
|
*/
|
|
445
445
|
function hasChildren(element) {
|
|
446
446
|
if (element.children.length === 0) return false;
|
|
@@ -450,16 +450,16 @@ function hasChildren(element) {
|
|
|
450
450
|
//#endregion
|
|
451
451
|
//#region src/has-every-attribute.ts
|
|
452
452
|
/**
|
|
453
|
-
* Check whether a JSX element carries all of the given attributes (props)
|
|
453
|
+
* Check whether a JSX element carries all of the given attributes (props).
|
|
454
454
|
*
|
|
455
455
|
* This is a batch variant of {@link hasAttribute} for the common pattern
|
|
456
456
|
* where a rule needs to verify that a set of required props are all present.
|
|
457
457
|
*
|
|
458
458
|
* Spread attributes are taken into account (see {@link findAttribute}).
|
|
459
|
-
* @param context The ESLint rule context (needed for variable resolution in spread attributes)
|
|
460
|
-
* @param element The `JSXElement` node to inspect
|
|
461
|
-
* @param names The attribute names to look for
|
|
462
|
-
* @returns `true` when every name in `names` is present on the element
|
|
459
|
+
* @param context The ESLint rule context (needed for variable resolution in spread attributes).
|
|
460
|
+
* @param element The `JSXElement` node to inspect.
|
|
461
|
+
* @param names The attribute names to look for.
|
|
462
|
+
* @returns `true` when every name in `names` is present on the element.
|
|
463
463
|
*/
|
|
464
464
|
function hasEveryAttribute(context, element, names) {
|
|
465
465
|
return names.every((name) => findAttribute(context, element, name) != null);
|
|
@@ -469,7 +469,7 @@ function hasEveryAttribute(context, element, names) {
|
|
|
469
469
|
//#region src/is-element.ts
|
|
470
470
|
/**
|
|
471
471
|
* Check whether a node is a `JSXElement` (or `JSXFragment`) and optionally
|
|
472
|
-
* matches a given test
|
|
472
|
+
* matches a given test.
|
|
473
473
|
*
|
|
474
474
|
* Modelled after
|
|
475
475
|
* [`hast-util-is-element`](https://github.com/syntax-tree/hast-util-is-element):
|
|
@@ -477,9 +477,9 @@ function hasEveryAttribute(context, element, names) {
|
|
|
477
477
|
*
|
|
478
478
|
* When called without a test, the function acts as a simple type-guard
|
|
479
479
|
* for `JSXElement | JSXFragment`.
|
|
480
|
-
* @param node The AST node to test
|
|
481
|
-
* @param test Optional test to match the element type against
|
|
482
|
-
* @returns `true` when the node is a matching JSX element
|
|
480
|
+
* @param node The AST node to test.
|
|
481
|
+
* @param test Optional test to match the element type against.
|
|
482
|
+
* @returns `true` when the node is a matching JSX element.
|
|
483
483
|
*/
|
|
484
484
|
function isElement(node, test) {
|
|
485
485
|
if (node == null) return false;
|
|
@@ -496,7 +496,7 @@ function isElement(node, test) {
|
|
|
496
496
|
//#endregion
|
|
497
497
|
//#region src/is-fragment-element.ts
|
|
498
498
|
/**
|
|
499
|
-
* Check whether a node is a React Fragment element
|
|
499
|
+
* Check whether a node is a React Fragment element.
|
|
500
500
|
*
|
|
501
501
|
* Recognizes both the shorthand `<>...</>` syntax (`JSXFragment`) and the
|
|
502
502
|
* explicit `<Fragment>` / `<React.Fragment>` form (`JSXElement`).
|
|
@@ -504,9 +504,9 @@ function isElement(node, test) {
|
|
|
504
504
|
* The comparison is performed against the self name (last dot-separated
|
|
505
505
|
* segment) of both the node and the configured factory, so `<React.Fragment>`
|
|
506
506
|
* matches `"React.Fragment"` and `<Fragment>` matches `"Fragment"`.
|
|
507
|
-
* @param node The AST node to test
|
|
508
|
-
* @param jsxFragmentFactory The configured fragment factory string (ex: "React.Fragment")
|
|
509
|
-
* @returns `true` when the node represents a React Fragment
|
|
507
|
+
* @param node The AST node to test.
|
|
508
|
+
* @param jsxFragmentFactory The configured fragment factory string (ex: "React.Fragment").
|
|
509
|
+
* @returns `true` when the node represents a React Fragment.
|
|
510
510
|
*/
|
|
511
511
|
function isFragmentElement(node, jsxFragmentFactory = "React.Fragment") {
|
|
512
512
|
if (node.type === AST_NODE_TYPES.JSXFragment) return true;
|
|
@@ -518,13 +518,13 @@ function isFragmentElement(node, jsxFragmentFactory = "React.Fragment") {
|
|
|
518
518
|
//#endregion
|
|
519
519
|
//#region src/is-host-element.ts
|
|
520
520
|
/**
|
|
521
|
-
* Check whether a node is a host (intrinsic / DOM) element
|
|
521
|
+
* Check whether a node is a host (intrinsic / DOM) element.
|
|
522
522
|
*
|
|
523
523
|
* A host element is a `JSXElement` whose tag name is a plain `JSXIdentifier`
|
|
524
524
|
* starting with a lowercase letter, the same heuristic React uses to
|
|
525
525
|
* distinguish `<div>` from `<MyComponent>`.
|
|
526
|
-
* @param node The AST node to test
|
|
527
|
-
* @returns `true` when the node is a `JSXElement` with a lowercase tag name
|
|
526
|
+
* @param node The AST node to test.
|
|
527
|
+
* @returns `true` when the node is a `JSXElement` with a lowercase tag name.
|
|
528
528
|
*/
|
|
529
529
|
function isHostElement(node) {
|
|
530
530
|
if (node.type !== AST_NODE_TYPES.JSXElement) return false;
|
|
@@ -537,7 +537,7 @@ function isHostElement(node) {
|
|
|
537
537
|
//#endregion
|
|
538
538
|
//#region src/jsx-detection-hint.ts
|
|
539
539
|
/**
|
|
540
|
-
* Hints for JSX detection
|
|
540
|
+
* Hints for JSX detection.
|
|
541
541
|
*/
|
|
542
542
|
const JsxDetectionHint = {
|
|
543
543
|
None: 0n,
|
|
@@ -554,7 +554,7 @@ const JsxDetectionHint = {
|
|
|
554
554
|
RequireBothBranchesOfConditionalExpressionToBeJsx: 1n << 10n
|
|
555
555
|
};
|
|
556
556
|
/**
|
|
557
|
-
* Default JSX detection hint
|
|
557
|
+
* Default JSX detection hint.
|
|
558
558
|
*
|
|
559
559
|
* Skips number, bigint, boolean, string, and undefined literals,
|
|
560
560
|
* the value types that are commonly returned alongside JSX in React
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@eslint-react/jsx",
|
|
3
|
-
"version": "5.
|
|
3
|
+
"version": "5.17.0",
|
|
4
4
|
"description": "ESLint React's TSESTree JSX utility module for static analysis of JSX patterns.",
|
|
5
5
|
"homepage": "https://github.com/Rel1cx/eslint-react",
|
|
6
6
|
"bugs": {
|
|
@@ -32,17 +32,17 @@
|
|
|
32
32
|
"@typescript-eslint/types": "^8.64.0",
|
|
33
33
|
"@typescript-eslint/utils": "^8.64.0",
|
|
34
34
|
"ts-pattern": "^5.9.0",
|
|
35
|
-
"@eslint-react/ast": "5.
|
|
36
|
-
"@eslint-react/eslint": "5.
|
|
37
|
-
"@eslint-react/shared": "5.
|
|
38
|
-
"@eslint-react/var": "5.
|
|
35
|
+
"@eslint-react/ast": "5.17.0",
|
|
36
|
+
"@eslint-react/eslint": "5.17.0",
|
|
37
|
+
"@eslint-react/shared": "5.17.0",
|
|
38
|
+
"@eslint-react/var": "5.17.0"
|
|
39
39
|
},
|
|
40
40
|
"devDependencies": {
|
|
41
41
|
"eslint": "^10.7.0",
|
|
42
42
|
"tsdown": "^0.22.7",
|
|
43
43
|
"typescript": "6.0.3",
|
|
44
|
-
"@local/
|
|
45
|
-
"@local/
|
|
44
|
+
"@local/eff": "0.0.0",
|
|
45
|
+
"@local/configs": "0.0.0"
|
|
46
46
|
},
|
|
47
47
|
"peerDependencies": {
|
|
48
48
|
"eslint": "*",
|