): RuleListener {
- function hasCommentLike(node: TSESTree.JSXText | TSESTree.Literal) {
- if (AST.isOneOf([T.JSXAttribute, T.JSXExpressionContainer])(node.parent)) {
- return false;
- }
- const rawValue = context.sourceCode.getText(node);
- return /^\s*\/(?:\/|\*)/mu.test(rawValue);
- }
- const visitorFunction = (node: TSESTree.JSXText | TSESTree.Literal): void => {
- if (!AST.isOneOf([T.JSXElement, T.JSXFragment])(node.parent)) {
- return;
- }
- if (!hasCommentLike(node)) {
- return;
- }
- if (!node.parent.type.includes("JSX")) {
- return;
- }
- context.report({
- messageId: "noCommentTextnodes",
- node,
- });
- };
- return {
- JSXText: visitorFunction,
- Literal: visitorFunction,
- };
-}
diff --git a/packages/plugins/eslint-plugin-react-x/src/rules-removed/no-complex-conditional-rendering.md b/packages/plugins/eslint-plugin-react-x/src/rules-removed/no-complex-conditional-rendering.md
deleted file mode 100644
index b01327fa15..0000000000
--- a/packages/plugins/eslint-plugin-react-x/src/rules-removed/no-complex-conditional-rendering.md
+++ /dev/null
@@ -1,62 +0,0 @@
----
-title: no-complex-conditional-rendering
----
-
-This rule is experimental and may change in the future or be removed. It is not recommended to use it in production code at this time.
-
-**Full Name in `eslint-plugin-react-x`**
-
-```sh copy
-react-x/no-complex-conditional-rendering
-```
-
-**Full Name in `@eslint-react/eslint-plugin`**
-
-```sh copy
-@eslint-react/no-complex-conditional-rendering
-```
-
-**Features**
-
-`🧪`
-
-## Description
-
-Disallow complex conditional rendering in JSX expressions.
-
-## Examples
-
-### Failing
-
-```tsx
-function MyComponent({ condition1, condition2, condition3, condition4 }) {
- return {condition1 || condition2 ?
X
: condition3 || condition4 ?
Y
: null}
;
-}
-```
-
-### Passing
-
-```tsx
-function MyComponent({ condition1, condition2, condition3, condition4 }) {
- const shouldDisplayX = condition1 || condition2;
- const shouldDisplayY = condition3 || condition4;
- return (
-
- {shouldDisplayX &&
X
}
- {shouldDisplayY &&
Y
}
-
- );
-}
-```
-
-## Implementation
-
-- [Rule Source](https://github.com/Rel1cx/eslint-react/tree/main/packages/plugins/eslint-plugin-react-x/src/rules/no-complex-conditional-rendering.ts)
-- [Test Source](https://github.com/Rel1cx/eslint-react/tree/main/packages/plugins/eslint-plugin-react-x/src/rules/no-complex-conditional-rendering.spec.ts)
-
----
-
-## See Also
-
-- [`no-leaked-conditional-rendering`](./no-leaked-conditional-rendering)\
- Prevents problematic leaked values from being rendered.
diff --git a/packages/plugins/eslint-plugin-react-x/src/rules-removed/no-complex-conditional-rendering.spec.ts b/packages/plugins/eslint-plugin-react-x/src/rules-removed/no-complex-conditional-rendering.spec.ts
deleted file mode 100644
index 2efa5aafbe..0000000000
--- a/packages/plugins/eslint-plugin-react-x/src/rules-removed/no-complex-conditional-rendering.spec.ts
+++ /dev/null
@@ -1,557 +0,0 @@
-import tsx from "dedent";
-
-import { allValid, ruleTester } from "../../../../../test";
-import rule, { RULE_NAME } from "./no-complex-conditional-rendering";
-
-ruleTester.run(RULE_NAME, rule, {
- invalid: [
- {
- code: tsx`
- function Component({ hideShapes, debugSvg }) {
- return {hideShapes ? null : debugSvg ? : }
;
- }
- `,
- errors: [
- {
- messageId: "noComplexConditionalRendering",
- },
- ],
- },
- {
- code: tsx`
- type AppProps = {
- items: string[];
- count: number;
- }
-
- const App = ({ items, count }: AppProps) => {
- return {direction ? (direction === "down" ? "▼" : "▲") : ""}
- }
- `,
- errors: [
- {
- messageId: "noComplexConditionalRendering",
- },
- ],
- },
- {
- code: tsx`
- const someCondition = 0;
- const SomeComponent = () =>
;
-
- const App = () => {
- return (
- <>
- {!!someCondition
- ? (
- )
- : someCondition ? null :
- }
- >
- )
- }
- `,
- errors: [
- {
- messageId: "noComplexConditionalRendering",
- },
- ],
- },
- {
- code: tsx`
- const someCondition = 0;
- const SomeComponent = () =>
;
-
- const App = () => {
- return (
- <>
- {!!someCondition
- ? (
- )
- : someCondition &&
- }
- >
- )
- }
- `,
- errors: [
- {
- messageId: "noComplexConditionalRendering",
- },
- ],
- },
- {
- code: tsx`
- const someCondition = 0;
- const SomeComponent = () =>
;
-
- const App = () => {
- return (
- <>
- {!!someCondition
- ? (
- )
- : someCondition ? someCondition :
- }
- >
- )
- }
- `,
- errors: [
- {
- messageId: "noComplexConditionalRendering",
- },
- ],
- },
- {
- code: tsx`
- const someCondition = 0;
- const SomeComponent = () =>
;
-
- const App = () => {
- return (
- <>
- {!!someCondition
- ? (
- )
- : someCondition ? "aaa"
- : someCondition && someCondition
- ?
- : null
- }
- >
- )
- }
- `,
- errors: [
- {
- messageId: "noComplexConditionalRendering",
- },
- ],
- },
- {
- code: tsx`
- const App = () => {
- return (
- <>
- {0 && 1 || }
- {NaN || 0 && }
- >
- )
- }
- `,
- errors: [
- {
- messageId: "noComplexConditionalRendering",
- },
- {
- messageId: "noComplexConditionalRendering",
- },
- ],
- },
- {
- code: tsx`
- const App = () => {
- return (
- <>
- {0 && 1 && 2 || }
- {NaN || 1 || 0 && }
- >
- )
- }
- `,
- errors: [
- {
- messageId: "noComplexConditionalRendering",
- },
- {
- messageId: "noComplexConditionalRendering",
- },
- ],
- },
- ],
- valid: [
- ...allValid,
- tsx`
- function Component({ hideShapes, debugSvg }) {
- // Early return if_to render
- if (hideShapes) {
- return null;
- }
-
- return debugSvg ? : ;
- }
- `,
- tsx`
- const foo = Math.random() > 0.5;
- const bar = "bar";
-
- const App = () => {
- return {foo || bar}
- }
- `,
- tsx`
- type AppProps = {
- foo: string;
- }
-
- const App = ({ foo }: AppProps) => {
- return {foo}
- }
- `,
- tsx`
- type AppProps = {
- items: string[];
- }
-
- const App = ({ items }: AppProps) => {
- return There are {items.length} elements
- }
- `,
- tsx`
- type AppProps = {
- items: string[];
- count: number;
- }
-
- const App = ({ items, count }: AppProps) => {
- return {!count && 'No results found'}
- }
- `,
- tsx`
- type ListProps = {
- items: string[];
- }
-
- const List = ({ items }: ListProps) => {
- return {items.map(item =>
{item}
)}
- }
-
- type AppProps = {
- items: string[];
- }
-
- const App = ({ items }: AppProps) => {
- return {!!items.length && }
- }
- `,
- tsx`
- type ListProps = {
- items: string[];
- }
-
- const List = ({ items }: ListProps) => {
- return {items.map(item =>
{item}
)}
- }
-
- type AppProps = {
- items: string[];
- }
-
- const App = ({ items }: AppProps) => {
- return {Boolean(items.length) && }
- }
- `,
- tsx`
- type ListProps = {
- items: string[];
- }
-
- const List = ({ items }: ListProps) => {
- return {items.map(item =>
{item}
)}
- }
-
- type AppProps = {
- items: string[];
- }
-
- const App = ({ items }: AppProps) => {
- return {items.length > 0 && }
- }
- `,
- tsx`
- type ListProps = {
- items: string[];
- }
-
- const List = ({ items }: ListProps) => {
- return {items.map(item =>
{item}
)}
- }
-
- type AppProps = {
- items: string[];
- }
-
- const App = ({ items }: AppProps) => {
- return {items.length ? : null}
- }
- `,
- tsx`
- type ListProps = {
- items: string[];
- }
-
- const List = ({ items }: ListProps) => {
- return {items.map(item =>
{item}
)}
- }
-
- type AppProps = {
- items: string[];
- count: number;
- }
-
- const App = ({ items, count }: AppProps) => {
- return {count ? : null}
- }
- `,
- tsx`
- type ListProps = {
- items: string[];
- }
-
- const List = ({ items }: ListProps) => {
- return {items.map(item =>
{item}
)}
- }
-
- type AppProps = {
- items: string[];
- count: number;
- }
-
- const App = ({ items, count }: AppProps) => {
- return {!!count && }
- }
- `,
- tsx`
- const App = () => {
- return (
- <>
- {0 ? : null}
- {'' && }
- {NaN ? : null}
- >
- )
- }
- `,
- tsx`
- const foo = Math.random() > 0.5;
- const bar = 0;
- function App() {
- return (
- {}}
- />
- );
- }
- `,
- `
- const someCondition = JSON.parse("true") as boolean;
- const SomeComponent = () =>
;
-
- const App = () => {
- return (
- <>
- {!!someCondition && (
-
- )}
- >
- )
- }
- `,
- tsx`
- const someCondition = JSON.parse("") as any;
- const SomeComponent = () =>
;
-
- const App = () => {
- return (
- <>
- {!!someCondition && (
-
- )}
- >
- )
- }
- `,
- tsx`
- const someCondition = JSON.parse("") as unknown;
- const SomeComponent = () =>
;
-
- const App = () => {
- return (
- <>
- {!!someCondition && (
-
- )}
- >
- )
- }
- `,
- tsx`
- const someCondition = 0
- const SomeComponent = () =>
;
-
- const App = () => {
- return (
- <>
- {!!someCondition && (
-
- )}
- >
- )
- }
- `,
- tsx`
- const someCondition = 1
- const SomeComponent = () =>
;
-
- const App = () => {
- return (
- <>
- {!!someCondition && (
-
- )}
- >
- )
- }
- `,
- tsx`
- const SomeComponent = () =>
;
- const App = ({
- someCondition,
- }: {
- someCondition?: number | undefined;
- }) => {
- return (
- <>
- {someCondition
- ? someCondition
- :
- }
- >
- )
- }
- `,
- tsx`
- const someCondition = true
- const SomeComponent = () =>
;
-
- const App = () => {
- return (
- <>
- {someCondition
- ? (
- )
- : "else"
- }
- >
- )
- }
- `,
- tsx`
- const SomeComponent = () =>
;
- const someFunction = (input: unknown): 10 => 10
-
- const App = ({ someCondition }: { someCondition?: number | undefined }) => {
- return <>{someCondition ? someFunction(someCondition) : }>;
- };
- `,
- tsx`
- const SomeComponent = () =>
;
-
- const App = ({
- someCondition,
- }:{
- someCondition?: boolean | undefined;
- }) => {
- return (
- <>
- {someCondition && }
- >
- )
- }
- `,
- tsx`
- type AppProps = {
- someFunction: (data: T) => React.ReactNode;
- };
-
- function App({ someFunction }: AppProps) {
- return <>{!!someFunction && someFunction(1)}>;
- }
- `,
- tsx`
- const App = () => {
- return (
- <>
- {0 && }
- {NaN && }
- >
- )
- }
- `,
- tsx`
- const App = () => {
- return (
- <>
- {0 && 1 && }
- {NaN && 0 && }
- >
- )
- }
- `,
- tsx`
- const App = () => {
- return Hello
- }
- `,
- tsx`
- function Example({ condition1, condition2, condition3, condition4 }) {
- return (
-
- {condition1 && condition2 &&
1
}
- {condition3 && condition4 &&
2
}
-
- );
- }
- `,
- tsx`
- function Example({ condition1, condition2, condition3, condition4 }) {
- const shouldDisplay1 = condition1 && condition2;
- const shouldDisplay2 = condition3 && condition4;
- return {shouldDisplay1 &&
1
}{shouldDisplay2 &&
2
}
;
- }
- `,
- ],
-});
diff --git a/packages/plugins/eslint-plugin-react-x/src/rules-removed/no-complex-conditional-rendering.ts b/packages/plugins/eslint-plugin-react-x/src/rules-removed/no-complex-conditional-rendering.ts
deleted file mode 100644
index eab2906b5b..0000000000
--- a/packages/plugins/eslint-plugin-react-x/src/rules-removed/no-complex-conditional-rendering.ts
+++ /dev/null
@@ -1,61 +0,0 @@
-import * as AST from "@eslint-react/ast";
-import type { RuleContext, RuleFeature } from "@eslint-react/kit";
-import { AST_NODE_TYPES as T } from "@typescript-eslint/types";
-import type { TSESTree } from "@typescript-eslint/utils";
-import type { RuleListener } from "@typescript-eslint/utils/ts-eslint";
-import type { CamelCase } from "string-ts";
-
-import { createRule } from "../utils";
-
-export const RULE_NAME = "no-complex-conditional-rendering";
-
-export const RULE_FEATURES = [
- "EXP",
-] as const satisfies RuleFeature[];
-
-export type MessageID = CamelCase;
-
-export default createRule<[], MessageID>({
- meta: {
- type: "problem",
- deprecated: true,
- docs: {
- description: "Disallow complex conditional rendering in JSX expressions.",
- [Symbol.for("rule_features")]: RULE_FEATURES,
- },
- messages: {
- noComplexConditionalRendering:
- "Avoid complex conditional rendering. Extract the logic into separate elements or components.",
- },
- schema: [],
- },
- name: RULE_NAME,
- create,
- defaultOptions: [],
-});
-
-export function create(context: RuleContext): RuleListener {
- const visitorFunction = (node: TSESTree.Node): void => {
- const jsxExpContainer = node.parent?.parent;
- if (!AST.is(T.JSXExpressionContainer)(jsxExpContainer)) {
- return;
- }
- if (!AST.isOneOf([T.JSXElement, T.JSXFragment])(jsxExpContainer.parent)) {
- return;
- }
- if (!jsxExpContainer.parent.children.includes(jsxExpContainer)) {
- return;
- }
- context.report({
- messageId: "noComplexConditionalRendering",
- node: jsxExpContainer,
- });
- };
- return {
- "JSXExpressionContainer > ConditionalExpression > ConditionalExpression": visitorFunction,
- "JSXExpressionContainer > ConditionalExpression > LogicalExpression": visitorFunction,
- "JSXExpressionContainer > LogicalExpression > ConditionalExpression": visitorFunction,
- "JSXExpressionContainer > LogicalExpression[operator='&&'] > LogicalExpression[operator='||']": visitorFunction,
- "JSXExpressionContainer > LogicalExpression[operator='||'] > LogicalExpression[operator='&&']": visitorFunction,
- };
-}
diff --git a/packages/plugins/eslint-plugin-react-x/src/rules-removed/prefer-react-namespace-import.md b/packages/plugins/eslint-plugin-react-x/src/rules-removed/prefer-react-namespace-import.md
deleted file mode 100644
index c6ef1a09be..0000000000
--- a/packages/plugins/eslint-plugin-react-x/src/rules-removed/prefer-react-namespace-import.md
+++ /dev/null
@@ -1,54 +0,0 @@
----
-title: prefer-namespace-import
----
-
-**Full Name in `eslint-plugin-react-x`**
-
-```sh copy
-react-x/prefer-namespace-import
-```
-
-**Full Name in `@eslint-react/eslint-plugin`**
-
-```sh copy
-@eslint-react/prefer-namespace-import
-```
-
-**Features**
-
-`🔧`
-
-## Description
-
-Enforces React is imported via a namespace import.
-
-## Examples
-
-### Failing
-
-```tsx
-import React from "react";
-
-import type React from "react";
-
-import React, { useState } from "react";
-
-import type React, { useState } from "react";
-```
-
-### Passing
-
-```tsx
-import * as React from "react";
-
-import type * as React from "react";
-
-import { useState } from "react";
-
-import type { useState } from "react";
-```
-
-## Implementation
-
-- [Rule Source](https://github.com/Rel1cx/eslint-react/tree/main/packages/plugins/eslint-plugin-react-x/src/rules/prefer-namespace-import.ts)
-- [Test Source](https://github.com/Rel1cx/eslint-react/tree/main/packages/plugins/eslint-plugin-react-x/src/rules/prefer-namespace-import.spec.ts)
diff --git a/packages/plugins/eslint-plugin-react-x/src/rules-removed/prefer-react-namespace-import.spec.ts b/packages/plugins/eslint-plugin-react-x/src/rules-removed/prefer-react-namespace-import.spec.ts
deleted file mode 100644
index afa2172096..0000000000
--- a/packages/plugins/eslint-plugin-react-x/src/rules-removed/prefer-react-namespace-import.spec.ts
+++ /dev/null
@@ -1,132 +0,0 @@
-import { AST_NODE_TYPES as T } from "@typescript-eslint/types";
-
-import { ruleTester } from "../../../../../test";
-import rule, { RULE_NAME } from "./prefer-react-namespace-import";
-
-ruleTester.run(RULE_NAME, rule, {
- invalid: [
- {
- code: `import React from 'react';`,
- errors: [{ type: T.ImportDeclaration, messageId: "preferReactNamespaceImport" }],
- output: `import * as React from 'react';`,
- },
- {
- code: `import REACT from 'react';`,
- errors: [{ type: T.ImportDeclaration, messageId: "preferReactNamespaceImport" }],
- output: `import * as REACT from 'react';`,
- },
- {
- code: `import type React from 'react';`,
- errors: [{ type: T.ImportDeclaration, messageId: "preferReactNamespaceImport" }],
- output: `import type * as React from 'react';`,
- },
- {
- code: `import React, {useState} from 'react';`,
- errors: [{ type: T.ImportDefaultSpecifier, messageId: "preferReactNamespaceImport" }],
- output: `import * as React from 'react';\nimport {useState} from 'react';`,
- },
- {
- code: `import React, {useState, useReducer} from 'react';`,
- errors: [{ type: T.ImportDefaultSpecifier, messageId: "preferReactNamespaceImport" }],
- output: `import * as React from 'react';\nimport {useState, useReducer} from 'react';`,
- },
- {
- code: `import REACT, {useState} from 'react';`,
- errors: [{ type: T.ImportDefaultSpecifier, messageId: "preferReactNamespaceImport" }],
- output: `import * as REACT from 'react';\nimport {useState} from 'react';`,
- },
- {
- code: `import type React, {useState} from 'react';`,
- errors: [{ type: T.ImportDefaultSpecifier, messageId: "preferReactNamespaceImport" }],
- output: `import type * as React from 'react';\nimport type {useState} from 'react';`,
- },
- {
- code: `import type React, {useState} from '@pika/react';`,
- errors: [{ type: T.ImportDefaultSpecifier, messageId: "preferReactNamespaceImport" }],
- output: `import type * as React from '@pika/react';\nimport type {useState} from '@pika/react';`,
- settings: {
- "react-x": {
- importSource: "@pika/react",
- },
- },
- },
- {
- code: `import React from "react";`,
- errors: [{ type: T.ImportDeclaration, messageId: "preferReactNamespaceImport" }],
- output: `import * as React from "react";`,
- },
- {
- code: `import REACT from "react";`,
- errors: [{ type: T.ImportDeclaration, messageId: "preferReactNamespaceImport" }],
- output: `import * as REACT from "react";`,
- },
- {
- code: `import type React from "react";`,
- errors: [{ type: T.ImportDeclaration, messageId: "preferReactNamespaceImport" }],
- output: `import type * as React from "react";`,
- },
- {
- code: `import React, {useState} from "react";`,
- errors: [{ type: T.ImportDefaultSpecifier, messageId: "preferReactNamespaceImport" }],
- output: `import * as React from "react";\nimport {useState} from "react";`,
- },
- {
- code: `import React, {useState, useReducer} from "react";`,
- errors: [{ type: T.ImportDefaultSpecifier, messageId: "preferReactNamespaceImport" }],
- output: `import * as React from "react";\nimport {useState, useReducer} from "react";`,
- },
- {
- code: `import REACT, {useState} from "react";`,
- errors: [{ type: T.ImportDefaultSpecifier, messageId: "preferReactNamespaceImport" }],
- output: `import * as REACT from "react";\nimport {useState} from "react";`,
- },
- {
- code: `import type React, {useState} from "react";`,
- errors: [{ type: T.ImportDefaultSpecifier, messageId: "preferReactNamespaceImport" }],
- output: `import type * as React from "react";\nimport type {useState} from "react";`,
- },
- {
- code: `import type React, {useState} from "@pika/react";`,
- errors: [{ type: T.ImportDefaultSpecifier, messageId: "preferReactNamespaceImport" }],
- output: `import type * as React from "@pika/react";\nimport type {useState} from "@pika/react";`,
- settings: {
- "react-x": {
- importSource: "@pika/react",
- },
- },
- },
- {
- code: `import React from 'react'`,
- errors: [{ type: T.ImportDeclaration, messageId: "preferReactNamespaceImport" }],
- output: `import * as React from 'react'`,
- },
- ],
- valid: [
- {
- code: `import * as React from 'react';`,
- },
- {
- code: `import {useState} from 'react';`,
- },
- {
- code: `import {} from 'react';`,
- },
- {
- code: `import * as React from "react";`,
- },
- {
- code: `import {useState} from "react";`,
- },
- {
- code: `import {} from "react";`,
- },
- {
- code: `import * as React from "@pika/react";`,
- settings: {
- "react-x": {
- importSource: "@pika/react",
- },
- },
- },
- ],
-});
diff --git a/packages/plugins/eslint-plugin-react-x/src/rules-removed/prefer-react-namespace-import.ts b/packages/plugins/eslint-plugin-react-x/src/rules-removed/prefer-react-namespace-import.ts
deleted file mode 100644
index 1473ffa7d3..0000000000
--- a/packages/plugins/eslint-plugin-react-x/src/rules-removed/prefer-react-namespace-import.ts
+++ /dev/null
@@ -1,77 +0,0 @@
-import { type RuleContext, type RuleFeature } from "@eslint-react/kit";
-import { getSettingsFromContext } from "@eslint-react/shared";
-import type { TSESTree } from "@typescript-eslint/types";
-import type { RuleListener } from "@typescript-eslint/utils/ts-eslint";
-import type { CamelCase } from "string-ts";
-
-import { createRule } from "../utils";
-
-export const RULE_NAME = "prefer-react-namespace-import";
-
-export const RULE_FEATURES = [
- "FIX",
-] as const satisfies RuleFeature[];
-
-export type MessageID = CamelCase;
-
-export default createRule<[], MessageID>({
- meta: {
- type: "problem",
- deprecated: true,
- docs: {
- description: "Enforces React is imported via a namespace import.",
- [Symbol.for("rule_features")]: RULE_FEATURES,
- },
- fixable: "code",
- messages: {
- preferReactNamespaceImport: "Prefer importing React as 'import * as React from \"{{importSource}}\"';",
- },
- replacedBy: [
- "react-x/prefer-namespace-import",
- ],
- schema: [],
- },
- name: RULE_NAME,
- create,
- defaultOptions: [],
-});
-
-export function create(context: RuleContext): RuleListener {
- const { importSource } = getSettingsFromContext(context);
- return {
- [`ImportDeclaration[source.value="${importSource}"] ImportDefaultSpecifier`](
- node: TSESTree.ImportDefaultSpecifier,
- ) {
- const hasOtherSpecifiers = node.parent.specifiers.length > 1;
- context.report({
- messageId: "preferReactNamespaceImport",
- node: hasOtherSpecifiers ? node : node.parent,
- data: { importSource },
- fix(fixer) {
- const importDeclarationText = context.sourceCode.getText(node.parent);
- const semi = importDeclarationText.endsWith(";") ? ";" : "";
- const quote = node.parent.source.raw.at(0) ?? "'";
- const isTypeImport = node.parent.importKind === "type";
- const importStringPrefix = `import${isTypeImport ? " type" : ""}`;
- const importSourceQuoted = `${quote}${importSource}${quote}`;
- if (!hasOtherSpecifiers) {
- return fixer.replaceText(
- node.parent,
- `${importStringPrefix} * as ${node.local.name} from ${importSourceQuoted}${semi}`,
- );
- }
- // dprint-ignore
- // remove the default specifier and prepend the namespace import specifier
- const specifiers = importDeclarationText.slice(importDeclarationText.indexOf("{"), importDeclarationText.indexOf("}") + 1);
- return fixer.replaceText(
- node.parent,
- [
- `${importStringPrefix} * as ${node.local.name} from ${importSourceQuoted}${semi}`,
- `${importStringPrefix} ${specifiers} from ${importSourceQuoted}${semi}`,
- ].join("\n"),
- );
- },
- });
- },
- };
-}
diff --git a/packages/plugins/eslint-plugin-react-x/src/rules-removed/prefer-shorthand-boolean.md b/packages/plugins/eslint-plugin-react-x/src/rules-removed/prefer-shorthand-boolean.md
deleted file mode 100644
index 6d92b1359f..0000000000
--- a/packages/plugins/eslint-plugin-react-x/src/rules-removed/prefer-shorthand-boolean.md
+++ /dev/null
@@ -1,63 +0,0 @@
----
-title: prefer-shorthand-boolean
----
-
-**Full Name in `eslint-plugin-react-x`**
-
-```sh copy
-react-x/prefer-shorthand-boolean
-```
-
-**Full Name in `@eslint-react/eslint-plugin`**
-
-```sh copy
-@eslint-react/prefer-shorthand-boolean
-```
-
-**Features**
-
-`🔧`
-
-## Description
-
-Enforces shorthand syntax for boolean attributes.
-
-## Examples
-
-### Failing
-
-```tsx
-import React from "react";
-
-function MyComponent() {
- return ;
- // ^^^^^^^^^^^^^^^
- // - Use shorthand boolean attribute 'disabled'.
-}
-```
-
-### Passing
-
-```tsx
-import React from "react";
-
-function MyComponent() {
- return ;
-}
-```
-
-## Implementation
-
-- [Rule Source](https://github.com/Rel1cx/eslint-react/tree/main/packages/plugins/eslint-plugin-react-x/src/rules/prefer-shorthand-boolean.ts)
-- [Test Source](https://github.com/Rel1cx/eslint-react/tree/main/packages/plugins/eslint-plugin-react-x/src/rules/prefer-shorthand-boolean.spec.ts)
-
----
-
-## See Also
-
-- [`avoid-shorthand-boolean`](./avoid-shorthand-boolean)\
- Enforces the use of explicit boolean values for boolean attributes.
-- [`avoid-shorthand-fragment`](./avoid-shorthand-fragment)\
- Enforces the use of explicit `` or `` components instead of the shorthand `<>` or `>` syntax.
-- [`prefer-shorthand-fragment`](./prefer-shorthand-fragment)\
- Enforces the use of shorthand syntax for fragments.
diff --git a/packages/plugins/eslint-plugin-react-x/src/rules-removed/prefer-shorthand-boolean.spec.ts b/packages/plugins/eslint-plugin-react-x/src/rules-removed/prefer-shorthand-boolean.spec.ts
deleted file mode 100644
index fad413b888..0000000000
--- a/packages/plugins/eslint-plugin-react-x/src/rules-removed/prefer-shorthand-boolean.spec.ts
+++ /dev/null
@@ -1,41 +0,0 @@
-import tsx from "dedent";
-
-import { allValid, ruleTester } from "../../../../../test";
-import rule, { RULE_NAME } from "./prefer-shorthand-boolean";
-
-ruleTester.run(RULE_NAME, rule, {
- invalid: [
- {
- code: tsx` `,
- errors: [{
- messageId: "preferShorthandBoolean",
- data: { propName: "disabled" },
- }],
- output: tsx` `,
- },
- {
- code: tsx` `,
- errors: [{
- messageId: "preferShorthandBoolean",
- data: { propName: "foo" },
- }],
- output: tsx` `,
- },
- {
- code: tsx` `,
- errors: [{
- messageId: "preferShorthandBoolean",
- data: { propName: "foo" },
- }],
- output: tsx` `,
- },
- ],
- valid: [
- ...allValid,
- tsx` `,
- " ",
- " ",
- " ",
- " ",
- ],
-});
diff --git a/packages/plugins/eslint-plugin-react-x/src/rules-removed/prefer-shorthand-boolean.ts b/packages/plugins/eslint-plugin-react-x/src/rules-removed/prefer-shorthand-boolean.ts
deleted file mode 100644
index d432f52845..0000000000
--- a/packages/plugins/eslint-plugin-react-x/src/rules-removed/prefer-shorthand-boolean.ts
+++ /dev/null
@@ -1,63 +0,0 @@
-import type { RuleContext, RuleFeature } from "@eslint-react/kit";
-import type { TSESTree } from "@typescript-eslint/types";
-import type { RuleListener } from "@typescript-eslint/utils/ts-eslint";
-import type { CamelCase } from "string-ts";
-
-import * as ER from "@eslint-react/core";
-
-import { AST_NODE_TYPES as T } from "@typescript-eslint/types";
-
-import { createRule } from "../utils";
-
-export const RULE_NAME = "prefer-shorthand-boolean";
-
-export const RULE_FEATURES = [
- "FIX",
-] as const satisfies RuleFeature[];
-
-export type MessageID = CamelCase;
-
-export default createRule<[], MessageID>({
- meta: {
- type: "problem",
- deprecated: true,
- docs: {
- description: "Enforces shorthand syntax for boolean attributes.",
- [Symbol.for("rule_features")]: RULE_FEATURES,
- },
- fixable: "code",
- messages: {
- preferShorthandBoolean: "Use shorthand boolean attribute '{{propName}}'.",
- },
- replacedBy: [
- "react-x/jsx-shorthand-boolean",
- ],
- schema: [],
- },
- name: RULE_NAME,
- create,
- defaultOptions: [],
-});
-
-export function create(context: RuleContext): RuleListener {
- return {
- JSXAttribute(node: TSESTree.JSXAttribute) {
- const { value } = node;
- const propName = ER.getAttributeName(context, node);
- const hasValueTrue = value?.type === T.JSXExpressionContainer
- && value.expression.type === T.Literal
- && value.expression.value === true;
- if (!hasValueTrue) {
- return;
- }
- context.report({
- messageId: "preferShorthandBoolean",
- node: node.value ?? node,
- data: {
- propName,
- },
- fix: (fixer) => fixer.removeRange([node.name.range[1], value.range[1]]),
- });
- },
- };
-}
diff --git a/packages/plugins/eslint-plugin-react-x/src/rules-removed/prefer-shorthand-fragment.md b/packages/plugins/eslint-plugin-react-x/src/rules-removed/prefer-shorthand-fragment.md
deleted file mode 100644
index d47d9636a5..0000000000
--- a/packages/plugins/eslint-plugin-react-x/src/rules-removed/prefer-shorthand-fragment.md
+++ /dev/null
@@ -1,71 +0,0 @@
----
-title: prefer-shorthand-fragment
----
-
-**Full Name in `eslint-plugin-react-x`**
-
-```sh copy
-react-x/prefer-shorthand-fragment
-```
-
-**Full Name in `@eslint-react/eslint-plugin`**
-
-```sh copy
-@eslint-react/prefer-shorthand-fragment
-```
-
-**Features**
-
-`🔧`
-
-## Description
-
-Enforces shorthand syntax for fragments.
-
-## Examples
-
-### Failing
-
-```tsx
-import React, { Fragment } from "react";
-
-function MyComponent() {
- return (
-
-
-
-
- );
-}
-```
-
-### Passing
-
-```tsx
-import React from "react";
-
-function MyComponent() {
- return (
- <>
-
-
- >
- );
-}
-```
-
-## Implementation
-
-- [Rule Source](https://github.com/Rel1cx/eslint-react/tree/main/packages/plugins/eslint-plugin-react-x/src/rules/prefer-shorthand-fragment.ts)
-- [Test Source](https://github.com/Rel1cx/eslint-react/tree/main/packages/plugins/eslint-plugin-react-x/src/rules/prefer-shorthand-fragment.spec.ts)
-
----
-
-## See Also
-
-- [`avoid-shorthand-boolean`](./avoid-shorthand-boolean)\
- Enforces the use of explicit boolean values for boolean attributes.
-- [`avoid-shorthand-fragment`](./avoid-shorthand-fragment)\
- Enforces the use of explicit `` or `` components instead of the shorthand `<>` or `>` syntax.
-- [`prefer-shorthand-boolean`](./prefer-shorthand-boolean)\
- Enforces the use of shorthand syntax for boolean attributes.
diff --git a/packages/plugins/eslint-plugin-react-x/src/rules-removed/prefer-shorthand-fragment.spec.ts b/packages/plugins/eslint-plugin-react-x/src/rules-removed/prefer-shorthand-fragment.spec.ts
deleted file mode 100644
index 1c3d16cf02..0000000000
--- a/packages/plugins/eslint-plugin-react-x/src/rules-removed/prefer-shorthand-fragment.spec.ts
+++ /dev/null
@@ -1,58 +0,0 @@
-import tsx from "dedent";
-
-import { allValid, ruleTester } from "../../../../../test";
-import rule, { RULE_NAME } from "./prefer-shorthand-fragment";
-
-ruleTester.run(RULE_NAME, rule, {
- invalid: [
- {
- code: tsx`
`,
- errors: [
- {
- messageId: "preferShorthandFragment",
- },
- ],
- output: tsx`<>
>`,
- },
- {
- code: tsx`
`,
- errors: [
- {
- messageId: "preferShorthandFragment",
- },
- ],
- output: tsx`<>
>`,
- },
- {
- code: tsx`
-
-
-
- `,
- errors: [
- {
- messageId: "preferShorthandFragment",
- },
- ],
- output: tsx`
- <>
-
- >
- `,
- },
- ],
- valid: [
- ...allValid,
- tsx`<> >`,
- tsx`<>foo
>`,
- tsx`<>
>`,
- tsx`<>{"moo"} >`,
- tsx` `,
- tsx` `,
- tsx`<>
> `,
- tsx`{"a"}{"b"}>} />`,
- tsx`
{item.value} `,
- tsx`
eeee ee eeeeeee eeeeeeee>} />`,
- tsx`<>{foos.map(foo => foo)}>`,
- ],
-});
diff --git a/packages/plugins/eslint-plugin-react-x/src/rules-removed/prefer-shorthand-fragment.ts b/packages/plugins/eslint-plugin-react-x/src/rules-removed/prefer-shorthand-fragment.ts
deleted file mode 100644
index cdb05e5142..0000000000
--- a/packages/plugins/eslint-plugin-react-x/src/rules-removed/prefer-shorthand-fragment.ts
+++ /dev/null
@@ -1,63 +0,0 @@
-import * as ER from "@eslint-react/core";
-import type { RuleContext, RuleFeature } from "@eslint-react/kit";
-import type { TSESTree } from "@typescript-eslint/types";
-import type { RuleListener } from "@typescript-eslint/utils/ts-eslint";
-import type { CamelCase } from "string-ts";
-
-import { createRule } from "../utils";
-
-export const RULE_NAME = "prefer-shorthand-fragment";
-
-export const RULE_FEATURES = [
- "FIX",
-] as const satisfies RuleFeature[];
-
-export type MessageID = CamelCase;
-
-export default createRule<[], MessageID>({
- meta: {
- type: "problem",
- deprecated: true,
- docs: {
- description: "Enforces shorthand syntax for fragments.",
- [Symbol.for("rule_features")]: RULE_FEATURES,
- },
- fixable: "code",
- messages: {
- preferShorthandFragment: "Use fragment shorthand syntax instead of 'Fragment' component.",
- },
- replacedBy: [
- "react-x/jsx-shorthand-fragment",
- ],
- schema: [],
- },
- name: RULE_NAME,
- create,
- defaultOptions: [],
-});
-
-export function create(context: RuleContext): RuleListener {
- return {
- JSXElement(node: TSESTree.JSXElement) {
- if (!ER.isFragmentElement(context, node)) return;
- const hasAttributes = node.openingElement.attributes.length > 0;
- if (hasAttributes) {
- return;
- }
- context.report({
- messageId: "preferShorthandFragment",
- node,
- fix: (fixer) => {
- const { closingElement, openingElement } = node;
- if (closingElement == null) {
- return [];
- }
- return [
- fixer.replaceTextRange([openingElement.range[0], openingElement.range[1]], "<>"),
- fixer.replaceTextRange([closingElement.range[0], closingElement.range[1]], ">"),
- ];
- },
- });
- },
- };
-}
diff --git a/packages/plugins/eslint-plugin-react-x/src/rules/no-unnecessary-use-callback.spec.ts b/packages/plugins/eslint-plugin-react-x/src/rules/no-unnecessary-use-callback.spec.ts
index 3174561fc9..959a4e2db5 100644
--- a/packages/plugins/eslint-plugin-react-x/src/rules/no-unnecessary-use-callback.spec.ts
+++ b/packages/plugins/eslint-plugin-react-x/src/rules/no-unnecessary-use-callback.spec.ts
@@ -405,32 +405,6 @@ ruleTester.run(RULE_NAME, rule, {
},
},
},
- {
- code: tsx`
- import React from "react";
-
- const Comp = () => {
- const style = useCustomCallback((theme) => ({
- input: {
- fontFamily: theme.fontFamilyMonospace
- }
- }), []);
- return
- }
- `,
- errors: [
- {
- messageId: "noUnnecessaryUseCallback",
- },
- ],
- settings: {
- "react-x": {
- additionalHooks: {
- useCallback: ["useCustomCallback"],
- },
- },
- },
- },
],
valid: [
...allValid,
diff --git a/packages/plugins/eslint-plugin-react-x/src/rules/no-unnecessary-use-callback.ts b/packages/plugins/eslint-plugin-react-x/src/rules/no-unnecessary-use-callback.ts
index f21554c6b0..fe33a45b9f 100644
--- a/packages/plugins/eslint-plugin-react-x/src/rules/no-unnecessary-use-callback.ts
+++ b/packages/plugins/eslint-plugin-react-x/src/rules/no-unnecessary-use-callback.ts
@@ -2,7 +2,6 @@ import * as AST from "@eslint-react/ast";
import * as ER from "@eslint-react/core";
import { identity } from "@eslint-react/eff";
import type { RuleContext, RuleFeature } from "@eslint-react/kit";
-import { getSettingsFromContext } from "@eslint-react/shared";
import * as VAR from "@eslint-react/var";
import { AST_NODE_TYPES as T } from "@typescript-eslint/types";
import type { RuleListener } from "@typescript-eslint/utils/ts-eslint";
@@ -38,20 +37,14 @@ export default createRule<[], MessageID>({
});
export function create(context: RuleContext): RuleListener {
- if (!context.sourceCode.text.includes("use")) return {};
- const alias = getSettingsFromContext(context).additionalHooks.useCallback ?? [];
- const isUseCallbackCall = ER.isReactHookCallWithNameAlias(context, "useCallback", alias);
+ if (!context.sourceCode.text.includes("useCallback")) return {};
return {
CallExpression(node) {
- if (!ER.isReactHookCall(node)) {
+ if (!ER.isUseCallbackCall(node)) {
return;
}
const initialScope = context.sourceCode.getScope(node);
- if (!isUseCallbackCall(node)) {
- return;
- }
- const scope = context.sourceCode.getScope(node);
- const component = scope.block;
+ const component = initialScope.block;
if (!AST.isFunction(component)) {
return;
}
diff --git a/packages/plugins/eslint-plugin-react-x/src/rules/no-unnecessary-use-memo.ts b/packages/plugins/eslint-plugin-react-x/src/rules/no-unnecessary-use-memo.ts
index c83d2f9ae2..eccfd13585 100644
--- a/packages/plugins/eslint-plugin-react-x/src/rules/no-unnecessary-use-memo.ts
+++ b/packages/plugins/eslint-plugin-react-x/src/rules/no-unnecessary-use-memo.ts
@@ -2,7 +2,6 @@ import * as AST from "@eslint-react/ast";
import * as ER from "@eslint-react/core";
import { identity } from "@eslint-react/eff";
import type { RuleContext, RuleFeature } from "@eslint-react/kit";
-import { getSettingsFromContext } from "@eslint-react/shared";
import * as VAR from "@eslint-react/var";
import { AST_NODE_TYPES as T } from "@typescript-eslint/types";
import type { RuleListener } from "@typescript-eslint/utils/ts-eslint";
@@ -37,16 +36,11 @@ export default createRule<[], MessageID>({
});
export function create(context: RuleContext): RuleListener {
- if (!context.sourceCode.text.includes("use")) return {};
- const alias = getSettingsFromContext(context).additionalHooks.useMemo ?? [];
- const isUseMemoCall = ER.isReactHookCallWithNameAlias(context, "useMemo", alias);
+ if (!context.sourceCode.text.includes("useMemo")) return {};
return {
CallExpression(node) {
- if (!ER.isReactHookCall(node)) {
- return;
- }
const initialScope = context.sourceCode.getScope(node);
- if (!isUseMemoCall(node)) {
+ if (!ER.isUseMemoCall(node)) {
return;
}
const scope = context.sourceCode.getScope(node);
diff --git a/packages/plugins/eslint-plugin-react-x/src/rules/no-use-context.spec.ts b/packages/plugins/eslint-plugin-react-x/src/rules/no-use-context.spec.ts
index 8f1b8a280f..8a2063233d 100644
--- a/packages/plugins/eslint-plugin-react-x/src/rules/no-use-context.spec.ts
+++ b/packages/plugins/eslint-plugin-react-x/src/rules/no-use-context.spec.ts
@@ -166,33 +166,6 @@ ruleTester.run(RULE_NAME, rule, {
},
},
},
- {
- code: tsx`
- import { use, useContext as useCtx } from 'react'
-
- export const Component = () => {
- const value = useCtx(MyContext)
- return {value}
- }
- `,
- errors: [
- { messageId: "noUseContext" },
- { messageId: "noUseContext" },
- ],
- output: tsx`
- import { use } from 'react'
-
- export const Component = () => {
- const value = use(MyContext)
- return {value}
- }
- `,
- settings: {
- "react-x": {
- version: "19.0.0",
- },
- },
- },
],
valid: [
{
diff --git a/packages/plugins/eslint-plugin-react-x/src/rules/no-use-context.ts b/packages/plugins/eslint-plugin-react-x/src/rules/no-use-context.ts
index e4e7b7ef61..f279afcc3c 100644
--- a/packages/plugins/eslint-plugin-react-x/src/rules/no-use-context.ts
+++ b/packages/plugins/eslint-plugin-react-x/src/rules/no-use-context.ts
@@ -42,7 +42,6 @@ export function create(context: RuleContext): RuleListener {
if (compare(settings.version, "19.0.0", "<")) {
return {};
}
- const useContextNames = new Set();
const hookCalls = new Set();
return {
CallExpression(node) {
@@ -61,11 +60,6 @@ export function create(context: RuleContext): RuleListener {
if (specifier.type !== T.ImportSpecifier) continue;
if (specifier.imported.type !== T.Identifier) continue;
if (specifier.imported.name === "useContext") {
- // import { useContext as useCtx } from 'react'
- if (specifier.local.name !== "useContext") {
- // add alias to useContextAlias to keep track of it in future call expressions
- useContextNames.add(specifier.local.name);
- }
context.report({
messageId: "noUseContext",
node: specifier,
@@ -90,9 +84,8 @@ export function create(context: RuleContext): RuleListener {
}
},
"Program:exit"() {
- const isUseContextCall = ER.isReactHookCallWithNameAlias(context, "useContext", [...useContextNames]);
for (const node of hookCalls) {
- if (!isUseContextCall(node)) {
+ if (!ER.isUseContextCall(node)) {
continue;
}
context.report({
diff --git a/packages/plugins/eslint-plugin-react-x/src/rules/prefer-use-state-lazy-initialization.spec.ts b/packages/plugins/eslint-plugin-react-x/src/rules/prefer-use-state-lazy-initialization.spec.ts
index 2061388b92..8f0187b7dc 100644
--- a/packages/plugins/eslint-plugin-react-x/src/rules/prefer-use-state-lazy-initialization.spec.ts
+++ b/packages/plugins/eslint-plugin-react-x/src/rules/prefer-use-state-lazy-initialization.spec.ts
@@ -139,22 +139,6 @@ ruleTester.run(RULE_NAME, rule, {
},
},
},
- {
- code: tsx`useLocalStorageState(1 || getValue())`,
- errors: [
- {
- type: T.CallExpression,
- messageId: "preferUseStateLazyInitialization",
- },
- ],
- settings: {
- "react-x": {
- additionalHooks: {
- useState: ["useLocalStorageState"],
- },
- },
- },
- },
],
valid: [
...allValid,
@@ -248,15 +232,5 @@ ruleTester.run(RULE_NAME, rule, {
},
},
},
- {
- code: "useLocalStorage(() => JSON.parse('{}'))",
- settings: {
- "react-x": {
- additionalHooks: {
- useState: ["useLocalStorage"],
- },
- },
- },
- },
],
});
diff --git a/packages/plugins/eslint-plugin-react-x/src/rules/prefer-use-state-lazy-initialization.ts b/packages/plugins/eslint-plugin-react-x/src/rules/prefer-use-state-lazy-initialization.ts
index 08c01ad7b9..3a17dae6a8 100644
--- a/packages/plugins/eslint-plugin-react-x/src/rules/prefer-use-state-lazy-initialization.ts
+++ b/packages/plugins/eslint-plugin-react-x/src/rules/prefer-use-state-lazy-initialization.ts
@@ -2,7 +2,6 @@
import * as AST from "@eslint-react/ast";
import * as ER from "@eslint-react/core";
import type { RuleContext, RuleFeature } from "@eslint-react/kit";
-import { getSettingsFromContext } from "@eslint-react/shared";
import type { RuleListener } from "@typescript-eslint/utils/ts-eslint";
import type { CamelCase } from "string-ts";
@@ -43,14 +42,9 @@ export default createRule<[], MessageID>({
});
export function create(context: RuleContext): RuleListener {
- const alias = getSettingsFromContext(context).additionalHooks.useState ?? [];
- const isUseStateCall = ER.isReactHookCallWithNameAlias(context, "useState", alias);
return {
CallExpression(node) {
- if (!ER.isReactHookCall(node)) {
- return;
- }
- if (!isUseStateCall(node)) {
+ if (!ER.isUseStateCall(node)) {
return;
}
const [useStateInput] = node.arguments;
@@ -60,7 +54,7 @@ export function create(context: RuleContext): RuleListener {
for (const expr of AST.getNestedNewExpressions(useStateInput)) {
if (!("name" in expr.callee)) continue;
if (ALLOW_LIST.includes(expr.callee.name)) continue;
- if (AST.findParentNode(expr, (n) => ER.isUseCall(context, n)) != null) continue;
+ if (AST.findParentNode(expr, ER.isUseCall) != null) continue;
context.report({
messageId: "preferUseStateLazyInitialization",
node: expr,
@@ -70,7 +64,7 @@ export function create(context: RuleContext): RuleListener {
if (!("name" in expr.callee)) continue;
if (ER.isReactHookName(expr.callee.name)) continue;
if (ALLOW_LIST.includes(expr.callee.name)) continue;
- if (AST.findParentNode(expr, (n) => ER.isUseCall(context, n)) != null) continue;
+ if (AST.findParentNode(expr, ER.isUseCall) != null) continue;
context.report({
messageId: "preferUseStateLazyInitialization",
node: expr,
diff --git a/packages/shared/docs/README.md b/packages/shared/docs/README.md
index d810e773c3..dc4b095d44 100644
--- a/packages/shared/docs/README.md
+++ b/packages/shared/docs/README.md
@@ -10,13 +10,11 @@
## Type Aliases
-- [CustomHooks](type-aliases/CustomHooks.md)
- [ESLintReactSettings](type-aliases/ESLintReactSettings.md)
- [ESLintSettings](type-aliases/ESLintSettings.md)
## Variables
-- [CustomHooksSchema](variables/CustomHooksSchema.md)
- [DEFAULT\_ESLINT\_REACT\_SETTINGS](variables/DEFAULT_ESLINT_REACT_SETTINGS.md)
- [DEFAULT\_ESLINT\_SETTINGS](variables/DEFAULT_ESLINT_SETTINGS.md)
- [defineSettings](variables/defineSettings.md)
diff --git a/packages/shared/docs/functions/coerceSettings.md b/packages/shared/docs/functions/coerceSettings.md
index 0adaf0c137..3a363db8c2 100644
--- a/packages/shared/docs/functions/coerceSettings.md
+++ b/packages/shared/docs/functions/coerceSettings.md
@@ -20,94 +20,6 @@ The settings object to coerce
## Returns
-### additionalHooks?
-
-> `optional` **additionalHooks**: `object`
-
-Custom hooks that should be treated as equivalent to built-in React Hooks
-
-#### Example
-
-```ts
-{ useEffect: ["useIsomorphicLayoutEffect"] }
-```
-
-#### additionalHooks.use?
-
-> `optional` **use**: `string`[]
-
-#### additionalHooks.useActionState?
-
-> `optional` **useActionState**: `string`[]
-
-#### additionalHooks.useCallback?
-
-> `optional` **useCallback**: `string`[]
-
-#### additionalHooks.useContext?
-
-> `optional` **useContext**: `string`[]
-
-#### additionalHooks.useDebugValue?
-
-> `optional` **useDebugValue**: `string`[]
-
-#### additionalHooks.useDeferredValue?
-
-> `optional` **useDeferredValue**: `string`[]
-
-#### additionalHooks.useEffect?
-
-> `optional` **useEffect**: `string`[]
-
-#### additionalHooks.useFormStatus?
-
-> `optional` **useFormStatus**: `string`[]
-
-#### additionalHooks.useId?
-
-> `optional` **useId**: `string`[]
-
-#### additionalHooks.useImperativeHandle?
-
-> `optional` **useImperativeHandle**: `string`[]
-
-#### additionalHooks.useInsertionEffect?
-
-> `optional` **useInsertionEffect**: `string`[]
-
-#### additionalHooks.useLayoutEffect?
-
-> `optional` **useLayoutEffect**: `string`[]
-
-#### additionalHooks.useMemo?
-
-> `optional` **useMemo**: `string`[]
-
-#### additionalHooks.useOptimistic?
-
-> `optional` **useOptimistic**: `string`[]
-
-#### additionalHooks.useReducer?
-
-> `optional` **useReducer**: `string`[]
-
-#### additionalHooks.useRef?
-
-> `optional` **useRef**: `string`[]
-
-#### additionalHooks.useState?
-
-> `optional` **useState**: `string`[]
-
-#### additionalHooks.useSyncExternalStore?
-
-> `optional` **useSyncExternalStore**: `string`[]
-
-#### additionalHooks.useTransition?
-
-> `optional` **useTransition**: `string`[]
-
### importSource?
> `optional` **importSource**: `string`
diff --git a/packages/shared/docs/functions/decodeSettings.md b/packages/shared/docs/functions/decodeSettings.md
index f95a6dc201..dbd603bcdd 100644
--- a/packages/shared/docs/functions/decodeSettings.md
+++ b/packages/shared/docs/functions/decodeSettings.md
@@ -20,94 +20,6 @@ The settings object to decode
## Returns
-### additionalHooks?
-
-> `optional` **additionalHooks**: `object`
-
-Custom hooks that should be treated as equivalent to built-in React Hooks
-
-#### Example
-
-```ts
-{ useEffect: ["useIsomorphicLayoutEffect"] }
-```
-
-#### additionalHooks.use?
-
-> `optional` **use**: `string`[]
-
-#### additionalHooks.useActionState?
-
-> `optional` **useActionState**: `string`[]
-
-#### additionalHooks.useCallback?
-
-> `optional` **useCallback**: `string`[]
-
-#### additionalHooks.useContext?
-
-> `optional` **useContext**: `string`[]
-
-#### additionalHooks.useDebugValue?
-
-> `optional` **useDebugValue**: `string`[]
-
-#### additionalHooks.useDeferredValue?
-
-> `optional` **useDeferredValue**: `string`[]
-
-#### additionalHooks.useEffect?
-
-> `optional` **useEffect**: `string`[]
-
-#### additionalHooks.useFormStatus?
-
-> `optional` **useFormStatus**: `string`[]
-
-#### additionalHooks.useId?
-
-> `optional` **useId**: `string`[]
-
-#### additionalHooks.useImperativeHandle?
-
-> `optional` **useImperativeHandle**: `string`[]
-
-#### additionalHooks.useInsertionEffect?
-
-> `optional` **useInsertionEffect**: `string`[]
-
-#### additionalHooks.useLayoutEffect?
-
-> `optional` **useLayoutEffect**: `string`[]
-
-#### additionalHooks.useMemo?
-
-> `optional` **useMemo**: `string`[]
-
-#### additionalHooks.useOptimistic?
-
-> `optional` **useOptimistic**: `string`[]
-
-#### additionalHooks.useReducer?
-
-> `optional` **useReducer**: `string`[]
-
-#### additionalHooks.useRef?
-
-> `optional` **useRef**: `string`[]
-
-#### additionalHooks.useState?
-
-> `optional` **useState**: `string`[]
-
-#### additionalHooks.useSyncExternalStore?
-
-> `optional` **useSyncExternalStore**: `string`[]
-
-#### additionalHooks.useTransition?
-
-> `optional` **useTransition**: `string`[]
-
### importSource?
> `optional` **importSource**: `string`
diff --git a/packages/shared/docs/functions/isESLintReactSettings.md b/packages/shared/docs/functions/isESLintReactSettings.md
index a160cd5774..a702523861 100644
--- a/packages/shared/docs/functions/isESLintReactSettings.md
+++ b/packages/shared/docs/functions/isESLintReactSettings.md
@@ -6,7 +6,7 @@
# Function: isESLintReactSettings()
-> **isESLintReactSettings**(`settings`): `settings is { additionalHooks?: { use?: string[]; useActionState?: string[]; useCallback?: string[]; useContext?: string[]; useDebugValue?: string[]; useDeferredValue?: string[]; useEffect?: string[]; useFormStatus?: string[]; useId?: string[]; useImperativeHandle?: string[]; useInsertionEffect?: string[]; useLayoutEffect?: string[]; useMemo?: string[]; useOptimistic?: string[]; useReducer?: string[]; useRef?: string[]; useState?: string[]; useSyncExternalStore?: string[]; useTransition?: string[] }; importSource?: string; polymorphicPropName?: string; version?: string }`
+> **isESLintReactSettings**(`settings`): `settings is { importSource?: string; polymorphicPropName?: string; version?: string }`
Checks if the provided settings conform to ESLintReactSettings schema
@@ -20,4 +20,4 @@ The settings object to validate
## Returns
-`settings is { additionalHooks?: { use?: string[]; useActionState?: string[]; useCallback?: string[]; useContext?: string[]; useDebugValue?: string[]; useDeferredValue?: string[]; useEffect?: string[]; useFormStatus?: string[]; useId?: string[]; useImperativeHandle?: string[]; useInsertionEffect?: string[]; useLayoutEffect?: string[]; useMemo?: string[]; useOptimistic?: string[]; useReducer?: string[]; useRef?: string[]; useState?: string[]; useSyncExternalStore?: string[]; useTransition?: string[] }; importSource?: string; polymorphicPropName?: string; version?: string }`
+`settings is { importSource?: string; polymorphicPropName?: string; version?: string }`
diff --git a/packages/shared/docs/functions/normalizeSettings.md b/packages/shared/docs/functions/normalizeSettings.md
index fcd6ef60cf..0e8cb1f87b 100644
--- a/packages/shared/docs/functions/normalizeSettings.md
+++ b/packages/shared/docs/functions/normalizeSettings.md
@@ -15,94 +15,6 @@ Transforms component definitions and resolves version information
### \_\_namedParameters
-#### additionalHooks?
-
-\{ `use?`: `string`[]; `useActionState?`: `string`[]; `useCallback?`: `string`[]; `useContext?`: `string`[]; `useDebugValue?`: `string`[]; `useDeferredValue?`: `string`[]; `useEffect?`: `string`[]; `useFormStatus?`: `string`[]; `useId?`: `string`[]; `useImperativeHandle?`: `string`[]; `useInsertionEffect?`: `string`[]; `useLayoutEffect?`: `string`[]; `useMemo?`: `string`[]; `useOptimistic?`: `string`[]; `useReducer?`: `string`[]; `useRef?`: `string`[]; `useState?`: `string`[]; `useSyncExternalStore?`: `string`[]; `useTransition?`: `string`[]; \} = `{}`
-
-Custom hooks that should be treated as equivalent to built-in React Hooks
-
-**Example**
-
-```ts
-{ useEffect: ["useIsomorphicLayoutEffect"] }
-```
-
-#### additionalHooks.use?
-
-`string`[] = `...`
-
-#### additionalHooks.useActionState?
-
-`string`[] = `...`
-
-#### additionalHooks.useCallback?
-
-`string`[] = `...`
-
-#### additionalHooks.useContext?
-
-`string`[] = `...`
-
-#### additionalHooks.useDebugValue?
-
-`string`[] = `...`
-
-#### additionalHooks.useDeferredValue?
-
-`string`[] = `...`
-
-#### additionalHooks.useEffect?
-
-`string`[] = `...`
-
-#### additionalHooks.useFormStatus?
-
-`string`[] = `...`
-
-#### additionalHooks.useId?
-
-`string`[] = `...`
-
-#### additionalHooks.useImperativeHandle?
-
-`string`[] = `...`
-
-#### additionalHooks.useInsertionEffect?
-
-`string`[] = `...`
-
-#### additionalHooks.useLayoutEffect?
-
-`string`[] = `...`
-
-#### additionalHooks.useMemo?
-
-`string`[] = `...`
-
-#### additionalHooks.useOptimistic?
-
-`string`[] = `...`
-
-#### additionalHooks.useReducer?
-
-`string`[] = `...`
-
-#### additionalHooks.useRef?
-
-`string`[] = `...`
-
-#### additionalHooks.useState?
-
-`string`[] = `...`
-
-#### additionalHooks.useSyncExternalStore?
-
-`string`[] = `...`
-
-#### additionalHooks.useTransition?
-
-`string`[] = `...`
-
#### importSource?
`string` = `"react"`
@@ -158,86 +70,6 @@ React version to use
`object`
-### additionalHooks
-
-> **additionalHooks**: `object`
-
-#### additionalHooks.use?
-
-> `optional` **use**: `string`[]
-
-#### additionalHooks.useActionState?
-
-> `optional` **useActionState**: `string`[]
-
-#### additionalHooks.useCallback?
-
-> `optional` **useCallback**: `string`[]
-
-#### additionalHooks.useContext?
-
-> `optional` **useContext**: `string`[]
-
-#### additionalHooks.useDebugValue?
-
-> `optional` **useDebugValue**: `string`[]
-
-#### additionalHooks.useDeferredValue?
-
-> `optional` **useDeferredValue**: `string`[]
-
-#### additionalHooks.useEffect?
-
-> `optional` **useEffect**: `string`[]
-
-#### additionalHooks.useFormStatus?
-
-> `optional` **useFormStatus**: `string`[]
-
-#### additionalHooks.useId?
-
-> `optional` **useId**: `string`[]
-
-#### additionalHooks.useImperativeHandle?
-
-> `optional` **useImperativeHandle**: `string`[]
-
-#### additionalHooks.useInsertionEffect?
-
-> `optional` **useInsertionEffect**: `string`[]
-
-#### additionalHooks.useLayoutEffect?
-
-> `optional` **useLayoutEffect**: `string`[]
-
-#### additionalHooks.useMemo?
-
-> `optional` **useMemo**: `string`[]
-
-#### additionalHooks.useOptimistic?
-
-> `optional` **useOptimistic**: `string`[]
-
-#### additionalHooks.useReducer?
-
-> `optional` **useReducer**: `string`[]
-
-#### additionalHooks.useRef?
-
-> `optional` **useRef**: `string`[]
-
-#### additionalHooks.useState?
-
-> `optional` **useState**: `string`[]
-
-#### additionalHooks.useSyncExternalStore?
-
-> `optional` **useSyncExternalStore**: `string`[]
-
-#### additionalHooks.useTransition?
-
-> `optional` **useTransition**: `string`[]
-
### importSource
> **importSource**: `string`
@@ -246,14 +78,6 @@ React version to use
> **polymorphicPropName**: `string`
-### skipImportCheck
-
-> **skipImportCheck**: `boolean`
-
-### strict
-
-> **strict**: `boolean`
-
### version
> `readonly` **version**: `string`
diff --git a/packages/shared/docs/interfaces/ESLintReactSettingsNormalized.md b/packages/shared/docs/interfaces/ESLintReactSettingsNormalized.md
index 6b9a880606..8b756beba9 100644
--- a/packages/shared/docs/interfaces/ESLintReactSettingsNormalized.md
+++ b/packages/shared/docs/interfaces/ESLintReactSettingsNormalized.md
@@ -10,88 +10,6 @@ Normalized ESLint React settings with processed values
## Properties
-### additionalHooks
-
-> **additionalHooks**: `object`
-
-#### use?
-
-> `optional` **use**: `string`[]
-
-#### useActionState?
-
-> `optional` **useActionState**: `string`[]
-
-#### useCallback?
-
-> `optional` **useCallback**: `string`[]
-
-#### useContext?
-
-> `optional` **useContext**: `string`[]
-
-#### useDebugValue?
-
-> `optional` **useDebugValue**: `string`[]
-
-#### useDeferredValue?
-
-> `optional` **useDeferredValue**: `string`[]
-
-#### useEffect?
-
-> `optional` **useEffect**: `string`[]
-
-#### useFormStatus?
-
-> `optional` **useFormStatus**: `string`[]
-
-#### useId?
-
-> `optional` **useId**: `string`[]
-
-#### useImperativeHandle?
-
-> `optional` **useImperativeHandle**: `string`[]
-
-#### useInsertionEffect?
-
-> `optional` **useInsertionEffect**: `string`[]
-
-#### useLayoutEffect?
-
-> `optional` **useLayoutEffect**: `string`[]
-
-#### useMemo?
-
-> `optional` **useMemo**: `string`[]
-
-#### useOptimistic?
-
-> `optional` **useOptimistic**: `string`[]
-
-#### useReducer?
-
-> `optional` **useReducer**: `string`[]
-
-#### useRef?
-
-> `optional` **useRef**: `string`[]
-
-#### useState?
-
-> `optional` **useState**: `string`[]
-
-#### useSyncExternalStore?
-
-> `optional` **useSyncExternalStore**: `string`[]
-
-#### useTransition?
-
-> `optional` **useTransition**: `string`[]
-
-***
-
### importSource
> **importSource**: `string`
@@ -104,18 +22,6 @@ Normalized ESLint React settings with processed values
***
-### skipImportCheck
-
-> **skipImportCheck**: `boolean`
-
-***
-
-### strict
-
-> **strict**: `boolean`
-
-***
-
### version
> **version**: `string`
diff --git a/packages/shared/docs/type-aliases/CustomHooks.md b/packages/shared/docs/type-aliases/CustomHooks.md
deleted file mode 100644
index 5f3fd253df..0000000000
--- a/packages/shared/docs/type-aliases/CustomHooks.md
+++ /dev/null
@@ -1,9 +0,0 @@
-[**@eslint-react/shared**](../README.md)
-
-***
-
-[@eslint-react/shared](../README.md) / CustomHooks
-
-# Type Alias: CustomHooks
-
-> **CustomHooks** = `z.infer`\<*typeof* [`CustomHooksSchema`](../variables/CustomHooksSchema.md)\>
diff --git a/packages/shared/docs/variables/CustomHooksSchema.md b/packages/shared/docs/variables/CustomHooksSchema.md
deleted file mode 100644
index 2afb33083a..0000000000
--- a/packages/shared/docs/variables/CustomHooksSchema.md
+++ /dev/null
@@ -1,11 +0,0 @@
-[**@eslint-react/shared**](../README.md)
-
-***
-
-[@eslint-react/shared](../README.md) / CustomHooksSchema
-
-# Variable: CustomHooksSchema
-
-> `const` **CustomHooksSchema**: `ZodObject`\<\{ `use`: `ZodOptional`\<`ZodArray`\<`ZodString`\>\>; `useActionState`: `ZodOptional`\<`ZodArray`\<`ZodString`\>\>; `useCallback`: `ZodOptional`\<`ZodArray`\<`ZodString`\>\>; `useContext`: `ZodOptional`\<`ZodArray`\<`ZodString`\>\>; `useDebugValue`: `ZodOptional`\<`ZodArray`\<`ZodString`\>\>; `useDeferredValue`: `ZodOptional`\<`ZodArray`\<`ZodString`\>\>; `useEffect`: `ZodOptional`\<`ZodArray`\<`ZodString`\>\>; `useFormStatus`: `ZodOptional`\<`ZodArray`\<`ZodString`\>\>; `useId`: `ZodOptional`\<`ZodArray`\<`ZodString`\>\>; `useImperativeHandle`: `ZodOptional`\<`ZodArray`\<`ZodString`\>\>; `useInsertionEffect`: `ZodOptional`\<`ZodArray`\<`ZodString`\>\>; `useLayoutEffect`: `ZodOptional`\<`ZodArray`\<`ZodString`\>\>; `useMemo`: `ZodOptional`\<`ZodArray`\<`ZodString`\>\>; `useOptimistic`: `ZodOptional`\<`ZodArray`\<`ZodString`\>\>; `useReducer`: `ZodOptional`\<`ZodArray`\<`ZodString`\>\>; `useRef`: `ZodOptional`\<`ZodArray`\<`ZodString`\>\>; `useState`: `ZodOptional`\<`ZodArray`\<`ZodString`\>\>; `useSyncExternalStore`: `ZodOptional`\<`ZodArray`\<`ZodString`\>\>; `useTransition`: `ZodOptional`\<`ZodArray`\<`ZodString`\>\>; \}, `$strip`\>
-
-Schema for custom hooks aliases that should be treated as React Hooks
diff --git a/packages/shared/docs/variables/DEFAULT_ESLINT_REACT_SETTINGS.md b/packages/shared/docs/variables/DEFAULT_ESLINT_REACT_SETTINGS.md
index bfbe70de13..fcc2d063e8 100644
--- a/packages/shared/docs/variables/DEFAULT_ESLINT_REACT_SETTINGS.md
+++ b/packages/shared/docs/variables/DEFAULT_ESLINT_REACT_SETTINGS.md
@@ -12,18 +12,6 @@ Default ESLint React settings
## Type Declaration
-### additionalHooks
-
-> `readonly` **additionalHooks**: `object`
-
-#### additionalHooks.useEffect
-
-> `readonly` **useEffect**: \[`"useIsomorphicLayoutEffect"`\]
-
-#### additionalHooks.useLayoutEffect
-
-> `readonly` **useLayoutEffect**: \[`"useIsomorphicLayoutEffect"`\]
-
### importSource
> `readonly` **importSource**: `"react"` = `"react"`
@@ -32,14 +20,6 @@ Default ESLint React settings
> `readonly` **polymorphicPropName**: `"as"` = `"as"`
-### skipImportCheck
-
-> `readonly` **skipImportCheck**: `true` = `true`
-
-### strict
-
-> `readonly` **strict**: `true` = `true`
-
### version
> `readonly` **version**: `"detect"` = `"detect"`
diff --git a/packages/shared/docs/variables/DEFAULT_ESLINT_SETTINGS.md b/packages/shared/docs/variables/DEFAULT_ESLINT_SETTINGS.md
index a884be212c..54e632e132 100644
--- a/packages/shared/docs/variables/DEFAULT_ESLINT_SETTINGS.md
+++ b/packages/shared/docs/variables/DEFAULT_ESLINT_SETTINGS.md
@@ -16,18 +16,6 @@ Default ESLint settings with React settings included
> `readonly` **react-x**: `object` = `DEFAULT_ESLINT_REACT_SETTINGS`
-#### react-x.additionalHooks
-
-> `readonly` **additionalHooks**: `object`
-
-#### react-x.additionalHooks.useEffect
-
-> `readonly` **useEffect**: \[`"useIsomorphicLayoutEffect"`\]
-
-#### react-x.additionalHooks.useLayoutEffect
-
-> `readonly` **useLayoutEffect**: \[`"useIsomorphicLayoutEffect"`\]
-
#### react-x.importSource
> `readonly` **importSource**: `"react"` = `"react"`
@@ -36,14 +24,6 @@ Default ESLint settings with React settings included
> `readonly` **polymorphicPropName**: `"as"` = `"as"`
-#### react-x.skipImportCheck
-
-> `readonly` **skipImportCheck**: `true` = `true`
-
-#### react-x.strict
-
-> `readonly` **strict**: `true` = `true`
-
#### react-x.version
> `readonly` **version**: `"detect"` = `"detect"`
diff --git a/packages/shared/src/settings.ts b/packages/shared/src/settings.ts
index 35eca5b63e..399ab7feb8 100644
--- a/packages/shared/src/settings.ts
+++ b/packages/shared/src/settings.ts
@@ -13,31 +13,6 @@ import { getReactVersion } from "./get-react-version";
// ===== Schema Definitions =====
-/**
- * Schema for custom hooks aliases that should be treated as React Hooks
- */
-export const CustomHooksSchema = z.object({
- use: z.optional(z.array(z.string())),
- useActionState: z.optional(z.array(z.string())),
- useCallback: z.optional(z.array(z.string())),
- useContext: z.optional(z.array(z.string())),
- useDebugValue: z.optional(z.array(z.string())),
- useDeferredValue: z.optional(z.array(z.string())),
- useEffect: z.optional(z.array(z.string())),
- useFormStatus: z.optional(z.array(z.string())),
- useId: z.optional(z.array(z.string())),
- useImperativeHandle: z.optional(z.array(z.string())),
- useInsertionEffect: z.optional(z.array(z.string())),
- useLayoutEffect: z.optional(z.array(z.string())),
- useMemo: z.optional(z.array(z.string())),
- useOptimistic: z.optional(z.array(z.string())),
- useReducer: z.optional(z.array(z.string())),
- useRef: z.optional(z.array(z.string())),
- useState: z.optional(z.array(z.string())),
- useSyncExternalStore: z.optional(z.array(z.string())),
- useTransition: z.optional(z.array(z.string())),
-});
-
/**
* Schema for ESLint React settings configuration
* @internal
@@ -58,20 +33,6 @@ export const ESLintReactSettingsSchema = z.object({
*/
polymorphicPropName: z.optional(z.string()),
- /**
- * Whether to use strict mode
- * @default true
- * @internal
- */
- strict: z.optional(z.boolean()),
-
- /**
- * Whether to skip import checks when determining if an API is from React
- * @default true
- * @internal
- */
- skipImportCheck: z.optional(z.boolean()),
-
/**
* React version to use
* "detect" means auto-detect React version from project dependencies
@@ -79,12 +40,6 @@ export const ESLintReactSettingsSchema = z.object({
* @default "detect"
*/
version: z.optional(z.string()),
-
- /**
- * Custom hooks that should be treated as equivalent to built-in React Hooks
- * @example { useEffect: ["useIsomorphicLayoutEffect"] }
- */
- additionalHooks: z.optional(CustomHooksSchema),
});
/**
@@ -98,7 +53,6 @@ export const ESLintSettingsSchema = z.optional(
);
// ===== Type Definitions =====
-export type CustomHooks = z.infer;
export type ESLintSettings = z.infer;
export type ESLintReactSettings = z.infer;
@@ -106,11 +60,8 @@ export type ESLintReactSettings = z.infer;
* Normalized ESLint React settings with processed values
*/
export interface ESLintReactSettingsNormalized {
- additionalHooks: CustomHooks;
importSource: string;
polymorphicPropName: string | unit;
- skipImportCheck: boolean;
- strict: boolean;
version: string;
}
@@ -122,13 +73,7 @@ export interface ESLintReactSettingsNormalized {
export const DEFAULT_ESLINT_REACT_SETTINGS = {
version: "detect",
importSource: "react",
- strict: true,
- skipImportCheck: true,
polymorphicPropName: "as",
- additionalHooks: {
- useEffect: ["useIsomorphicLayoutEffect"],
- useLayoutEffect: ["useIsomorphicLayoutEffect"],
- },
} as const satisfies ESLintReactSettings;
/**
@@ -199,21 +144,15 @@ export const decodeSettings = (settings: unknown): ESLintReactSettings => {
* Transforms component definitions and resolves version information
*/
export const normalizeSettings = ({
- additionalHooks = {},
importSource = "react",
polymorphicPropName = "as",
- skipImportCheck = true,
- strict = true,
version,
...rest
}: ESLintReactSettings) => {
return {
...rest,
- additionalHooks,
importSource,
polymorphicPropName,
- skipImportCheck,
- strict,
version: match(version)
.with(P.union(P.nullish, "", "detect"), () => getReactVersion("19.1.0"))
.otherwise(identity),