Skip to content

Commit d96e562

Browse files
committed
refactor: minor improvements
1 parent d7a7b06 commit d96e562

File tree

11 files changed

+58
-52
lines changed

11 files changed

+58
-52
lines changed

packages/core/docs/README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@
4141
## Functions
4242

4343
- [getComponentNameFromIdentifier](functions/getComponentNameFromIdentifier.md)
44+
- [getElementType](functions/getElementType.md)
4445
- [getFunctionComponentIdentifier](functions/getFunctionComponentIdentifier.md)
4546
- [hasNoneOrValidComponentName](functions/hasNoneOrValidComponentName.md)
4647
- [isCallFromReact](functions/isCallFromReact.md)
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
[**@eslint-react/core**](../README.md)
2+
3+
***
4+
5+
[@eslint-react/core](../README.md) / getElementType
6+
7+
# Function: getElementType()
8+
9+
> **getElementType**(`node`, `context`): `string`
10+
11+
## Parameters
12+
13+
### node
14+
15+
`JSXOpeningElement`
16+
17+
### context
18+
19+
`Readonly`\<`RuleContext`\<`string`, readonly `unknown`[]\>\>
20+
21+
## Returns
22+
23+
`string`
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
import * as JSX from "@eslint-react/jsx";
2+
import { decodeSettings, normalizeSettings } from "@eslint-react/shared";
3+
import { F, isString, O } from "@eslint-react/tools";
4+
import type { RuleContext } from "@eslint-react/types";
5+
import type { TSESTree } from "@typescript-eslint/types";
6+
7+
export function getElementType(node: TSESTree.JSXOpeningElement, context: RuleContext) {
8+
const elementName = JSX.getElementName(node);
9+
if (elementName === elementName.toLowerCase()) return elementName;
10+
const { components, polymorphicPropName } = normalizeSettings(decodeSettings(context.settings));
11+
const asElementName = components.get(elementName);
12+
if (isString(asElementName)) return asElementName;
13+
return F.pipe(
14+
O.fromNullable(polymorphicPropName),
15+
O.flatMap(JSX.findPropInAttributes(node.attributes, context.sourceCode.getScope(node))),
16+
O.flatMap(attr => JSX.getPropValue(attr, context.sourceCode.getScope(attr))),
17+
O.filter(isString),
18+
O.getOrElse(() => elementName),
19+
);
20+
}

packages/core/src/element/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
1+
export * from "./get-element-type";
12
export * from "./hierarchy";
23
export * from "./misc";

packages/plugins/eslint-plugin-react-dom/src/rules/no-children-in-void-dom-elements.ts

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
1+
import { getElementType } from "@eslint-react/core";
12
import * as JSX from "@eslint-react/jsx";
2-
import { decodeSettings, normalizeSettings } from "@eslint-react/shared";
33
import { O } from "@eslint-react/tools";
4-
import type { TSESTree } from "@typescript-eslint/utils";
54
import type { CamelCase } from "string-ts";
65

76
import { createRule } from "../utils";
@@ -43,12 +42,9 @@ export default createRule<[], MessageID>({
4342
},
4443
name: RULE_NAME,
4544
create(context) {
46-
const { components, polymorphicPropName } = normalizeSettings(decodeSettings(context.settings));
4745
return {
4846
JSXElement(node) {
49-
const openingElementNameExpression = node.openingElement;
50-
const jsxCtx = { getScope: (node: TSESTree.Node) => context.sourceCode.getScope(node) } as const;
51-
const elementType = JSX.getElementType(jsxCtx, components, polymorphicPropName)(openingElementNameExpression);
47+
const elementType = getElementType(node.openingElement, context);
5248
if (!elementType || !voidElements.has(elementType)) return;
5349
if (node.children.length > 0) {
5450
context.report({

packages/plugins/eslint-plugin-react-dom/src/rules/no-missing-button-type.ts

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
1+
import { getElementType } from "@eslint-react/core";
12
import * as JSX from "@eslint-react/jsx";
2-
import { decodeSettings, normalizeSettings } from "@eslint-react/shared";
33
import { O } from "@eslint-react/tools";
4-
import type { TSESTree } from "@typescript-eslint/utils";
54
import type { CamelCase } from "string-ts";
65

76
import { createRule } from "../utils";
@@ -24,11 +23,9 @@ export default createRule<[], MessageID>({
2423
},
2524
name: RULE_NAME,
2625
create(context) {
27-
const { components, polymorphicPropName } = normalizeSettings(decodeSettings(context.settings));
2826
return {
2927
JSXElement(node) {
30-
const jsxCtx = { getScope: (node: TSESTree.Node) => context.sourceCode.getScope(node) } as const;
31-
const elementType = JSX.getElementType(jsxCtx, components, polymorphicPropName)(node.openingElement);
28+
const elementType = getElementType(node.openingElement, context);
3229
if (elementType !== "button") return;
3330
const { attributes } = node.openingElement;
3431
const initialScope = context.sourceCode.getScope(node);

packages/plugins/eslint-plugin-react-dom/src/rules/no-missing-iframe-sandbox.ts

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import type { TSESTree } from "@typescript-eslint/utils";
55
import type { CamelCase } from "string-ts";
66

77
import { createRule } from "../utils";
8+
import { getElementType } from "@eslint-react/core";
89

910
export const RULE_NAME = "no-missing-iframe-sandbox";
1011

@@ -43,11 +44,9 @@ export default createRule<[], MessageID>({
4344
},
4445
name: RULE_NAME,
4546
create(context) {
46-
const { components, polymorphicPropName } = normalizeSettings(decodeSettings(context.settings));
4747
return {
4848
JSXElement(node) {
49-
const jsxCtx = { getScope: (node: TSESTree.Node) => context.sourceCode.getScope(node) } as const;
50-
const elementType = JSX.getElementType(jsxCtx, components, polymorphicPropName)(node.openingElement);
49+
const elementType = getElementType(node.openingElement, context);
5150
if (elementType !== "iframe") return;
5251
const { attributes } = node.openingElement;
5352
const initialScope = context.sourceCode.getScope(node);

packages/plugins/eslint-plugin-react-dom/src/rules/no-unsafe-iframe-sandbox.ts

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import type { CamelCase } from "string-ts";
66
import { match, P } from "ts-pattern";
77

88
import { createRule } from "../utils";
9+
import { getElementType } from "@eslint-react/core";
910

1011
export const RULE_NAME = "no-unsafe-iframe-sandbox";
1112

@@ -30,11 +31,9 @@ export default createRule<[], MessageID>({
3031
},
3132
name: RULE_NAME,
3233
create(context) {
33-
const { components, polymorphicPropName } = normalizeSettings(decodeSettings(context.settings));
3434
return {
3535
JSXElement(node) {
36-
const jsxCtx = { getScope: (node: TSESTree.Node) => context.sourceCode.getScope(node) } as const;
37-
const elementType = JSX.getElementType(jsxCtx, components, polymorphicPropName)(node.openingElement);
36+
const elementType = getElementType(node.openingElement, context);
3837
if (elementType !== "iframe") return;
3938
const { attributes } = node.openingElement;
4039
const initialScope = context.sourceCode.getScope(node);

packages/plugins/eslint-plugin-react-dom/src/rules/no-unsafe-target-blank.ts

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import { getElementType } from "@eslint-react/core";
12
import * as JSX from "@eslint-react/jsx";
23
import { decodeSettings, normalizeSettings } from "@eslint-react/shared";
34
import { F, isString, O } from "@eslint-react/tools";
@@ -38,13 +39,10 @@ export default createRule<[], MessageID>({
3839
name: RULE_NAME,
3940
create(context) {
4041
const settings = normalizeSettings(decodeSettings(context.settings));
41-
const polymorphicPropName = settings.polymorphicPropName;
42-
const components = settings.components;
4342
const additionalComponents = settings.additionalComponents.filter(c => c.as === "a");
4443
function getReportDescriptor(node: TSESTree.JSXElement): O.Option<ReportDescriptor<MessageID>> {
4544
const name = JSX.getElementName(node.openingElement);
46-
const jsxCtx = { getScope: (node: TSESTree.Node) => context.sourceCode.getScope(node) };
47-
const elementType = JSX.getElementType(jsxCtx, components, polymorphicPropName)(node.openingElement);
45+
const elementType = getElementType(node.openingElement, context);
4846
if (elementType !== "a" && !additionalComponents.some(c => c.re.test(name))) return O.none();
4947
const { attributes } = node.openingElement;
5048
const initialScope = context.sourceCode.getScope(node);
@@ -61,7 +59,7 @@ export default createRule<[], MessageID>({
6159
? O.fromNullable(targetPropDefaultValue)
6260
: F.pipe(
6361
targetProp,
64-
O.flatMap(attr => JSX.getPropValue(attr, jsxCtx.getScope(attr))),
62+
O.flatMap(attr => JSX.getPropValue(attr, context.sourceCode.getScope(attr))),
6563
O.flatMapNullable(v =>
6664
match(v)
6765
.with(P.string, F.identity)
@@ -80,7 +78,7 @@ export default createRule<[], MessageID>({
8078
? O.fromNullable(hrefPropDefaultValue)
8179
: F.pipe(
8280
hrefProp,
83-
O.flatMap(attr => JSX.getPropValue(attr, jsxCtx.getScope(attr))),
81+
O.flatMap(attr => JSX.getPropValue(attr, context.sourceCode.getScope(attr))),
8482
O.flatMapNullable(v =>
8583
match(v)
8684
.with(P.string, F.identity)
@@ -99,7 +97,7 @@ export default createRule<[], MessageID>({
9997
? O.fromNullable(relPropDefaultValue)
10098
: F.pipe(
10199
relProp,
102-
O.flatMap(attr => JSX.getPropValue(attr, jsxCtx.getScope(attr))),
100+
O.flatMap(attr => JSX.getPropValue(attr, context.sourceCode.getScope(attr))),
103101
O.flatMapNullable(v =>
104102
match(v)
105103
.with(P.string, F.identity)

packages/utilities/jsx/src/get-element-type.ts

Lines changed: 0 additions & 27 deletions
This file was deleted.

0 commit comments

Comments
 (0)