diff --git a/packages/core/docs/README.md b/packages/core/docs/README.md index 4aae7dfeb3..c4d5a6493f 100644 --- a/packages/core/docs/README.md +++ b/packages/core/docs/README.md @@ -128,7 +128,6 @@ - [isInitializedFromReact](functions/isInitializedFromReact.md) - [isJsxLike](functions/isJsxLike.md) - [isJsxText](functions/isJsxText.md) -- [isKeyedElement](functions/isKeyedElement.md) - [isNeverType](functions/isNeverType.md) - [isNullishType](functions/isNullishType.md) - [isNumberType](functions/isNumberType.md) diff --git a/packages/core/docs/functions/isFragmentElement.md b/packages/core/docs/functions/isFragmentElement.md index 0ebe13c2b6..fa1eb24b38 100644 --- a/packages/core/docs/functions/isFragmentElement.md +++ b/packages/core/docs/functions/isFragmentElement.md @@ -6,46 +6,18 @@ # Function: isFragmentElement() -## Call Signature +> **isFragmentElement**(`context`, `node`): `node is JSXElement` -> **isFragmentElement**(`context`, `node`, `allowJSXFragment?`): `node is JSXElement` +## Parameters -### Parameters - -#### context +### context `RuleContext` -#### node - -`undefined` | `null` | `Node` +### node -#### allowJSXFragment? +`Node` -`false` - -### Returns +## Returns `node is JSXElement` - -## Call Signature - -> **isFragmentElement**(`context`, `node`, `allowJSXFragment?`): node is JSXElement \| JSXFragment - -### Parameters - -#### context - -`RuleContext` - -#### node - -`undefined` | `null` | `Node` - -#### allowJSXFragment? - -`true` - -### Returns - -node is JSXElement \| JSXFragment diff --git a/packages/core/docs/functions/isKeyedElement.md b/packages/core/docs/functions/isKeyedElement.md deleted file mode 100644 index 43969cb147..0000000000 --- a/packages/core/docs/functions/isKeyedElement.md +++ /dev/null @@ -1,27 +0,0 @@ -[**@eslint-react/core**](../README.md) - -*** - -[@eslint-react/core](../README.md) / isKeyedElement - -# Function: isKeyedElement() - -> **isKeyedElement**(`context`, `node`, `initialScope?`): `boolean` - -## Parameters - -### context - -`RuleContext` - -### node - -`Node` - -### initialScope? - -`Scope` - -## Returns - -`boolean` diff --git a/packages/core/src/jsx/index.ts b/packages/core/src/jsx/index.ts index f4469a15d8..6601705262 100644 --- a/packages/core/src/jsx/index.ts +++ b/packages/core/src/jsx/index.ts @@ -3,8 +3,8 @@ export * from "./jsx-attribute-name"; export * from "./jsx-attribute-value"; export * from "./jsx-detection"; export * from "./jsx-detection-hint"; +export * from "./jsx-element-is"; export * from "./jsx-element-type"; export * from "./jsx-has"; export * from "./jsx-hierarchy"; -export * from "./jsx-is"; export * from "./jsx-stringify"; diff --git a/packages/core/src/jsx/jsx-element-is.ts b/packages/core/src/jsx/jsx-element-is.ts new file mode 100644 index 0000000000..b73bda9b13 --- /dev/null +++ b/packages/core/src/jsx/jsx-element-is.ts @@ -0,0 +1,17 @@ +import type { RuleContext } from "@eslint-react/kit"; +import type { TSESTree } from "@typescript-eslint/types"; +import { AST_NODE_TYPES as T } from "@typescript-eslint/types"; +import { getElementType } from "./jsx-element-type"; + +export function isHostElement(context: RuleContext, node: TSESTree.Node) { + return node.type === T.JSXElement + && node.openingElement.name.type === T.JSXIdentifier + && /^[a-z]/u.test(node.openingElement.name.name); +} + +export function isFragmentElement(context: RuleContext, node: TSESTree.Node): node is TSESTree.JSXElement { + if (node.type !== T.JSXElement) return false; + return getElementType(context, node) + .split(".") + .at(-1) === "Fragment"; +} diff --git a/packages/core/src/jsx/jsx-is.ts b/packages/core/src/jsx/jsx-is.ts deleted file mode 100644 index 0ce0d5c02c..0000000000 --- a/packages/core/src/jsx/jsx-is.ts +++ /dev/null @@ -1,39 +0,0 @@ -import type { unit } from "@eslint-react/eff"; -import type { RuleContext } from "@eslint-react/kit"; -import type { Scope } from "@typescript-eslint/scope-manager"; -import type { TSESTree } from "@typescript-eslint/types"; -import { AST_NODE_TYPES as T } from "@typescript-eslint/types"; -import { getElementType } from "./jsx-element-type"; -import { hasAttribute } from "./jsx-has"; - -export function isHostElement(context: RuleContext, node: TSESTree.Node) { - return node.type === T.JSXElement - && node.openingElement.name.type === T.JSXIdentifier - && /^[a-z]/u.test(node.openingElement.name.name); -} - -export function isKeyedElement(context: RuleContext, node: TSESTree.Node, initialScope?: Scope) { - return node.type === T.JSXElement - && hasAttribute(context, "key", node.openingElement.attributes, initialScope); -} - -export function isFragmentElement( - context: RuleContext, - node: TSESTree.Node | null | unit, - allowJSXFragment?: false, -): node is TSESTree.JSXElement; -export function isFragmentElement( - context: RuleContext, - node: TSESTree.Node | null | unit, - allowJSXFragment?: true, -): node is TSESTree.JSXElement | TSESTree.JSXFragment; -export function isFragmentElement( - context: RuleContext, - node: TSESTree.Node | null | unit, - allowJSXFragment = false, -): node is TSESTree.JSXElement | TSESTree.JSXFragment { - if (node == null) return false; - if (node.type !== T.JSXElement && node.type !== T.JSXFragment) return false; - if (node.type === T.JSXFragment) return allowJSXFragment; - return getElementType(context, node).split(".").at(-1) === "Fragment"; -} diff --git a/packages/plugins/eslint-plugin-react-x/src/rules/no-useless-fragment.ts b/packages/plugins/eslint-plugin-react-x/src/rules/no-useless-fragment.ts index e24c84b075..e6cb06ff7a 100644 --- a/packages/plugins/eslint-plugin-react-x/src/rules/no-useless-fragment.ts +++ b/packages/plugins/eslint-plugin-react-x/src/rules/no-useless-fragment.ts @@ -105,7 +105,7 @@ function checkNode( ) { const initialScope = context.sourceCode.getScope(node); // return if the fragment is keyed (e.g. ) - if (ER.isKeyedElement(context, node, initialScope)) { + if (node.type === T.JSXElement && ER.hasAttribute(context, "key", node.openingElement.attributes, initialScope)) { return; } // report if the fragment is placed inside a host component (e.g.
<>
)