diff --git a/eslint.config.mjs b/eslint.config.mjs index 6e0f2b9a7a6..01245ec83fa 100644 --- a/eslint.config.mjs +++ b/eslint.config.mjs @@ -9,7 +9,6 @@ import {defineConfig, globalIgnores} from 'eslint/config' import githubPlugin from 'eslint-plugin-github' import storybook from 'eslint-plugin-storybook' import react from 'eslint-plugin-react' -import reactCompiler from 'eslint-plugin-react-compiler' import reactHooks from 'eslint-plugin-react-hooks' import playwright from 'eslint-plugin-playwright' import prettierRecommended from 'eslint-plugin-prettier/recommended' @@ -61,8 +60,7 @@ const config = defineConfig([ react.configs.flat.recommended, react.configs.flat['jsx-runtime'], - reactCompiler.configs.recommended, - reactHooks.configs['recommended-latest'], + reactHooks.configs.flat['recommended-latest'], github.browser, github.recommended, diff --git a/package-lock.json b/package-lock.json index 78922667a76..5ab8f2abce0 100644 --- a/package-lock.json +++ b/package-lock.json @@ -34,6 +34,7 @@ "@vitest/browser": "^4.0.3", "@vitest/browser-playwright": "^4.0.3", "@vitest/eslint-plugin": "^1.3.24", + "babel-plugin-react-compiler": "^1.0.0", "eslint": "^9.35.0", "eslint-import-resolver-typescript": "3.7.0", "eslint-plugin-clsx": "^0.0.10", @@ -44,8 +45,7 @@ "eslint-plugin-prettier": "^5.5.4", "eslint-plugin-primer-react": "^8.2.0", "eslint-plugin-react": "^7.35.5", - "eslint-plugin-react-compiler": "^19.1.0-rc.2", - "eslint-plugin-react-hooks": "^5.2.0", + "eslint-plugin-react-hooks": "^7.0.1", "eslint-plugin-ssr-friendly": "1.3.0", "eslint-plugin-storybook": "^9.1.5", "eslint-plugin-testing-library": "^7.7.0", @@ -761,21 +761,6 @@ "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/plugin-proposal-private-methods": { - "version": "7.18.6", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-create-class-features-plugin": "^7.18.6", - "@babel/helper-plugin-utils": "^7.18.6" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, "node_modules/@babel/plugin-proposal-private-property-in-object": { "version": "7.21.0-placeholder-for-preset-env.2", "dev": true, @@ -10546,9 +10531,9 @@ } }, "node_modules/babel-plugin-react-compiler": { - "version": "19.1.0-rc.3", - "resolved": "https://registry.npmjs.org/babel-plugin-react-compiler/-/babel-plugin-react-compiler-19.1.0-rc.3.tgz", - "integrity": "sha512-mjRn69WuTz4adL0bXGx8Rsyk1086zFJeKmes6aK0xPuK3aaXmDJdLHqwKKMrpm6KAI1MCoUK72d2VeqQbu8YIA==", + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/babel-plugin-react-compiler/-/babel-plugin-react-compiler-1.0.0.tgz", + "integrity": "sha512-Ixm8tFfoKKIPYdCCKYTsqv+Fd4IJ0DQqMyEimo+pxUOMUR9cVPlwTrFt9Avu+3cb6Zp3mAzl+t1MrG2fxxKsxw==", "dev": true, "license": "MIT", "dependencies": { @@ -13539,25 +13524,6 @@ "eslint": "^3 || ^4 || ^5 || ^6 || ^7 || ^8 || ^9.7" } }, - "node_modules/eslint-plugin-react-compiler": { - "version": "19.1.0-rc.2", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/core": "^7.24.4", - "@babel/parser": "^7.24.4", - "@babel/plugin-proposal-private-methods": "^7.18.6", - "hermes-parser": "^0.25.1", - "zod": "^3.22.4", - "zod-validation-error": "^3.0.3" - }, - "engines": { - "node": "^14.17.0 || ^16.0.0 || >= 18.0.0" - }, - "peerDependencies": { - "eslint": ">=7" - } - }, "node_modules/eslint-plugin-react-debug": { "version": "1.52.6", "dev": true, @@ -13627,11 +13593,20 @@ } }, "node_modules/eslint-plugin-react-hooks": { - "version": "5.2.0", + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-7.0.1.tgz", + "integrity": "sha512-O0d0m04evaNzEPoSW+59Mezf8Qt0InfgGIBJnpC0h3NH/WjUAR7BIKUfysC6todmtiZ/A0oUVS8Gce0WhBrHsA==", "dev": true, "license": "MIT", + "dependencies": { + "@babel/core": "^7.24.4", + "@babel/parser": "^7.24.4", + "hermes-parser": "^0.25.1", + "zod": "^3.25.0 || ^4.0.0", + "zod-validation-error": "^3.5.0 || ^4.0.0" + }, "engines": { - "node": ">=10" + "node": ">=18" }, "peerDependencies": { "eslint": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0 || ^9.0.0" @@ -13671,6 +13646,29 @@ } } }, + "node_modules/eslint-plugin-react-hooks/node_modules/zod": { + "version": "4.1.12", + "resolved": "https://registry.npmjs.org/zod/-/zod-4.1.12.tgz", + "integrity": "sha512-JInaHOamG8pt5+Ey8kGmdcAcg3OL9reK8ltczgHTAwNhMys/6ThXHityHxVV2p3fkw/c+MAvBHFVYHFZDmjMCQ==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/colinhacks" + } + }, + "node_modules/eslint-plugin-react-hooks/node_modules/zod-validation-error": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/zod-validation-error/-/zod-validation-error-4.0.2.tgz", + "integrity": "sha512-Q6/nZLe6jxuU80qb/4uJ4t5v2VEZ44lzQjPDhYJNztRQ4wyWc6VF3D3Kb/fAuPetZQnhS3hnajCf9CsWesghLQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18.0.0" + }, + "peerDependencies": { + "zod": "^3.25.0 || ^4.0.0" + } + }, "node_modules/eslint-plugin-react-naming-convention": { "version": "1.52.6", "dev": true, @@ -21099,13 +21097,6 @@ "node": ">=0.10.0" } }, - "node_modules/react-compiler-runtime": { - "version": "19.1.0-rc.2", - "license": "MIT", - "peerDependencies": { - "react": "^17.0.0 || ^18.0.0 || ^19.0.0 || ^0.0.0-experimental" - } - }, "node_modules/react-docgen": { "version": "8.0.0", "dev": true, @@ -27264,7 +27255,7 @@ "hsluv": "1.0.1", "lodash.isempty": "^4.4.0", "lodash.isobject": "^3.0.2", - "react-compiler-runtime": "^19.1.0-rc.2", + "react-compiler-runtime": "^1.0.0", "react-intersection-observer": "^9.16.0" }, "devDependencies": { @@ -27315,7 +27306,7 @@ "babel-plugin-dev-expression": "0.2.3", "babel-plugin-macros": "3.1.0", "babel-plugin-open-source": "1.3.4", - "babel-plugin-react-compiler": "^19.1.0-rc.3", + "babel-plugin-react-compiler": "^1.0.0", "babel-plugin-transform-replace-expressions": "0.2.0", "babel-polyfill": "6.26.0", "chalk": "^5.4.1", @@ -27647,6 +27638,15 @@ "url": "https://github.com/sponsors/wooorm" } }, + "packages/react/node_modules/react-compiler-runtime": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/react-compiler-runtime/-/react-compiler-runtime-1.0.0.tgz", + "integrity": "sha512-rRfjYv66HlG8896yPUDONgKzG5BxZD1nV9U6rkm+7VCuvQc903C4MjcoZR4zPw53IKSOX9wMQVpA1IAbRtzQ7w==", + "license": "MIT", + "peerDependencies": { + "react": "^17.0.0 || ^18.0.0 || ^19.0.0 || ^0.0.0-experimental" + } + }, "packages/react/node_modules/tsconfig-paths": { "version": "4.2.0", "dev": true, diff --git a/package.json b/package.json index 0b8d9d0539a..7b40c2e6430 100644 --- a/package.json +++ b/package.json @@ -62,6 +62,7 @@ "@vitest/browser": "^4.0.3", "@vitest/browser-playwright": "^4.0.3", "@vitest/eslint-plugin": "^1.3.24", + "babel-plugin-react-compiler": "^1.0.0", "eslint": "^9.35.0", "eslint-import-resolver-typescript": "3.7.0", "eslint-plugin-clsx": "^0.0.10", @@ -72,8 +73,7 @@ "eslint-plugin-prettier": "^5.5.4", "eslint-plugin-primer-react": "^8.2.0", "eslint-plugin-react": "^7.35.5", - "eslint-plugin-react-compiler": "^19.1.0-rc.2", - "eslint-plugin-react-hooks": "^5.2.0", + "eslint-plugin-react-hooks": "^7.0.1", "eslint-plugin-ssr-friendly": "1.3.0", "eslint-plugin-storybook": "^9.1.5", "eslint-plugin-testing-library": "^7.7.0", diff --git a/packages/react/package.json b/packages/react/package.json index 38d92136030..c6f7589dc3f 100644 --- a/packages/react/package.json +++ b/packages/react/package.json @@ -90,7 +90,7 @@ "hsluv": "1.0.1", "lodash.isempty": "^4.4.0", "lodash.isobject": "^3.0.2", - "react-compiler-runtime": "^19.1.0-rc.2", + "react-compiler-runtime": "^1.0.0", "react-intersection-observer": "^9.16.0" }, "devDependencies": { @@ -141,7 +141,7 @@ "babel-plugin-dev-expression": "0.2.3", "babel-plugin-macros": "3.1.0", "babel-plugin-open-source": "1.3.4", - "babel-plugin-react-compiler": "^19.1.0-rc.3", + "babel-plugin-react-compiler": "^1.0.0", "babel-plugin-transform-replace-expressions": "0.2.0", "babel-polyfill": "6.26.0", "chalk": "^5.4.1", diff --git a/packages/react/script/react-compiler.mjs b/packages/react/script/react-compiler.mjs index d868c9a1b0d..b365d389ed2 100644 --- a/packages/react/script/react-compiler.mjs +++ b/packages/react/script/react-compiler.mjs @@ -23,6 +23,7 @@ const unsupported = new Set( 'src/SelectPanel/**/*.tsx', 'src/SideNav.tsx', 'src/internal/components/CheckboxOrRadioGroup/**/*.tsx', + 'src/TooltipV2/**/*.tsx', ].flatMap(pattern => { if (glob.isDynamicPattern(pattern)) { const matches = glob.sync(pattern, {cwd: PACKAGE_DIR}) diff --git a/packages/react/src/ActionList/ActionList.examples.stories.tsx b/packages/react/src/ActionList/ActionList.examples.stories.tsx index 8910f107ee3..1f5cde43966 100644 --- a/packages/react/src/ActionList/ActionList.examples.stories.tsx +++ b/packages/react/src/ActionList/ActionList.examples.stories.tsx @@ -39,6 +39,7 @@ const NextJSLikeLink = forwardRef( ref, href, } + // eslint-disable-next-line react-hooks/refs return <>{React.isValidElement(child) ? React.cloneElement(child, childProps) : null} }, ) diff --git a/packages/react/src/ActionList/ActionList.features.stories.tsx b/packages/react/src/ActionList/ActionList.features.stories.tsx index e7ff8b11f50..b5a5adac7a1 100644 --- a/packages/react/src/ActionList/ActionList.features.stories.tsx +++ b/packages/react/src/ActionList/ActionList.features.stories.tsx @@ -674,10 +674,8 @@ export const ChildWithSideEffects = () => { const [selected, setSelected] = React.useState(true) const SideEffectDescription = () => { - // eslint-disable-next-line react-compiler/react-compiler const [seconds, setSeconds] = React.useState(0) - // eslint-disable-next-line react-compiler/react-compiler React.useEffect(() => { const fn = () => setSeconds(s => s + 1) const interval = window.setInterval(fn, 1000) diff --git a/packages/react/src/ActionMenu/ActionMenu.examples.stories.tsx b/packages/react/src/ActionMenu/ActionMenu.examples.stories.tsx index 3f2095e8b79..36f6481dd40 100644 --- a/packages/react/src/ActionMenu/ActionMenu.examples.stories.tsx +++ b/packages/react/src/ActionMenu/ActionMenu.examples.stories.tsx @@ -195,6 +195,9 @@ export const ControlledMenu = () => { } export const ShortcutMenu = () => { + const [open, setOpen] = React.useState(false) + const triggerRef = React.useRef(null) + React.useEffect(() => { const onKeyDown = (event: KeyboardEvent) => { if (event.shiftKey && (event.key === 'c' || event.key === 'C')) { @@ -205,9 +208,6 @@ export const ShortcutMenu = () => { return () => window.removeEventListener('keydown', onKeyDown) }, []) - const [open, setOpen] = React.useState(false) - const triggerRef = React.useRef(null) - return ( <>

Shortcut Menu

@@ -270,9 +270,7 @@ export const ContextMenu = () => { setOpen(true) } - // eslint-disable-next-line react-compiler/react-compiler const [open, setOpen] = React.useState(false) - // eslint-disable-next-line react-compiler/react-compiler const triggerRef = React.useRef(null) return ( diff --git a/packages/react/src/ActionMenu/ActionMenu.tsx b/packages/react/src/ActionMenu/ActionMenu.tsx index c2c722cb895..d159f98a329 100644 --- a/packages/react/src/ActionMenu/ActionMenu.tsx +++ b/packages/react/src/ActionMenu/ActionMenu.tsx @@ -120,7 +120,7 @@ const Menu: FCWithSlotMarker> = ({ // tooltip trigger const anchorChildren = child.props.children if (anchorChildren.type === MenuButton || isSlot(anchorChildren, MenuButton)) { - // eslint-disable-next-line react-compiler/react-compiler + // eslint-disable-next-line react-hooks/immutability renderAnchor = anchorProps => { // We need to attach the anchor props to the tooltip trigger (ActionMenu.Button's grandchild) not the tooltip itself. const triggerButton = React.cloneElement( diff --git a/packages/react/src/Autocomplete/Autocomplete.features.stories.tsx b/packages/react/src/Autocomplete/Autocomplete.features.stories.tsx index 5caa78482e3..55fa35d8389 100644 --- a/packages/react/src/Autocomplete/Autocomplete.features.stories.tsx +++ b/packages/react/src/Autocomplete/Autocomplete.features.stories.tsx @@ -546,6 +546,7 @@ export const InADialog = () => { useEffect(() => { if (outerContainerRef.current instanceof HTMLElement) { registerPortalRoot(outerContainerRef.current, 'outerContainer') + // eslint-disable-next-line react-hooks/set-state-in-effect setMounted(true) } }, [isDialogOpen]) diff --git a/packages/react/src/Autocomplete/AutocompleteInput.tsx b/packages/react/src/Autocomplete/AutocompleteInput.tsx index f95c4e7f7c2..4b0314884cc 100644 --- a/packages/react/src/Autocomplete/AutocompleteInput.tsx +++ b/packages/react/src/Autocomplete/AutocompleteInput.tsx @@ -153,7 +153,6 @@ const AutocompleteInput = React.forwardRef( } // calling this useEffect when `highlightRemainingText` changes breaks backspace functionality - // eslint-disable-next-line react-compiler/react-compiler // eslint-disable-next-line react-hooks/exhaustive-deps }, [autocompleteSuggestion, inputValue, inputRef, isMenuDirectlyActivated]) diff --git a/packages/react/src/Autocomplete/AutocompleteMenu.tsx b/packages/react/src/Autocomplete/AutocompleteMenu.tsx index 69918c48e99..12a9fab533d 100644 --- a/packages/react/src/Autocomplete/AutocompleteMenu.tsx +++ b/packages/react/src/Autocomplete/AutocompleteMenu.tsx @@ -288,7 +288,6 @@ function AutocompleteMenu(props: AutocompleteMe }, activeDescendantFocus: inputRef, onActiveDescendantChanged: (current, _previous, directlyActivated) => { - // eslint-disable-next-line react-compiler/react-compiler activeDescendantRef.current = current || null if (current) { const selectedItem = allItemsToRenderRef.current.find(item => { @@ -326,6 +325,7 @@ function AutocompleteMenu(props: AutocompleteMe itemIdSortResult.every((element, index) => element === sortedItemIds[index]) if (showMenu === false && !sortResultMatchesState) { + // eslint-disable-next-line react-hooks/set-state-in-effect setSortedItemIds(itemIdSortResult) } diff --git a/packages/react/src/Banner/Banner.tsx b/packages/react/src/Banner/Banner.tsx index 81d04875cf6..52bcec33ad4 100644 --- a/packages/react/src/Banner/Banner.tsx +++ b/packages/react/src/Banner/Banner.tsx @@ -119,7 +119,6 @@ export const Banner = React.forwardRef(function Banner if (__DEV__) { // This hook is called consistently depending on the environment - // eslint-disable-next-line react-compiler/react-compiler // eslint-disable-next-line react-hooks/rules-of-hooks useEffect(() => { if (title) { diff --git a/packages/react/src/Breadcrumbs/Breadcrumbs.tsx b/packages/react/src/Breadcrumbs/Breadcrumbs.tsx index 6e69095ca79..f917d3c1ca0 100644 --- a/packages/react/src/Breadcrumbs/Breadcrumbs.tsx +++ b/packages/react/src/Breadcrumbs/Breadcrumbs.tsx @@ -154,6 +154,7 @@ function Breadcrumbs({className, children, style, overflow = 'wrap', variant = ' const iconButtonElement = element.querySelector('button[data-component="IconButton"]') if (iconButtonElement) { const measuredWidth = (iconButtonElement as HTMLElement).offsetWidth + // eslint-disable-next-line react-hooks/immutability setMenuButtonWidth(measuredWidth) } } diff --git a/packages/react/src/Button/ButtonBase.tsx b/packages/react/src/Button/ButtonBase.tsx index 97f3564e35c..056b1020793 100644 --- a/packages/react/src/Button/ButtonBase.tsx +++ b/packages/react/src/Button/ButtonBase.tsx @@ -62,7 +62,6 @@ const ButtonBase = forwardRef(({children, as: Component = 'button', ...props}, f * this is safe, and ensures the entire effect is kept out of prod builds * shaving precious bytes from the output, and avoiding mounting a noop effect */ - // eslint-disable-next-line react-compiler/react-compiler // eslint-disable-next-line react-hooks/rules-of-hooks React.useEffect(() => { if ( diff --git a/packages/react/src/Checkbox/Checkbox.tsx b/packages/react/src/Checkbox/Checkbox.tsx index fe593f0ac45..d54c372cd80 100644 --- a/packages/react/src/Checkbox/Checkbox.tsx +++ b/packages/react/src/Checkbox/Checkbox.tsx @@ -67,7 +67,6 @@ const Checkbox = React.forwardRef( useLayoutEffect(() => { if (checkboxRef.current) { - // eslint-disable-next-line react-compiler/react-compiler checkboxRef.current.indeterminate = indeterminate || false } }, [indeterminate, checked, checkboxRef]) diff --git a/packages/react/src/Dialog/Dialog.tsx b/packages/react/src/Dialog/Dialog.tsx index f646770a29f..301bc80304c 100644 --- a/packages/react/src/Dialog/Dialog.tsx +++ b/packages/react/src/Dialog/Dialog.tsx @@ -250,7 +250,7 @@ const _Dialog = React.forwardRef(null) for (const footerButton of footerButtons) { if (footerButton.autoFocus) { - // eslint-disable-next-line react-compiler/react-compiler + // eslint-disable-next-line react-hooks/immutability footerButton.ref = autoFocusedFooterButtonRef } } diff --git a/packages/react/src/FilteredActionList/FilteredActionListLoaders.tsx b/packages/react/src/FilteredActionList/FilteredActionListLoaders.tsx index bbd4d134a59..8d2486bd4ab 100644 --- a/packages/react/src/FilteredActionList/FilteredActionListLoaders.tsx +++ b/packages/react/src/FilteredActionList/FilteredActionListLoaders.tsx @@ -56,6 +56,7 @@ function LoadingSkeleton({rows = 10, ...props}: {rows: number}): JSX.Element { {Array.from({length: rows}, (_, i) => ( + {/* eslint-disable-next-line react-hooks/purity */} ))} diff --git a/packages/react/src/FilteredActionList/useAnnouncements.tsx b/packages/react/src/FilteredActionList/useAnnouncements.tsx index 0bf43b92ee5..697b1232e4e 100644 --- a/packages/react/src/FilteredActionList/useAnnouncements.tsx +++ b/packages/react/src/FilteredActionList/useAnnouncements.tsx @@ -15,6 +15,7 @@ const useFirstRender = () => { useEffect(() => { firstRender.current = false }, []) + // eslint-disable-next-line react-hooks/refs return firstRender.current } diff --git a/packages/react/src/Heading/Heading.tsx b/packages/react/src/Heading/Heading.tsx index 56c7c7ed149..474a49ede24 100644 --- a/packages/react/src/Heading/Heading.tsx +++ b/packages/react/src/Heading/Heading.tsx @@ -23,7 +23,6 @@ const Heading = forwardRef(({as: Component = 'h2', className, variant, ...props} * this is safe, and ensures the entire effect is kept out of prod builds * shaving precious bytes from the output, and avoiding mounting a noop effect */ - // eslint-disable-next-line react-compiler/react-compiler // eslint-disable-next-line react-hooks/rules-of-hooks useEffect(() => { if (innerRef.current && !(innerRef.current instanceof HTMLHeadingElement)) { diff --git a/packages/react/src/LabelGroup/LabelGroup.tsx b/packages/react/src/LabelGroup/LabelGroup.tsx index 42a01a4c0f6..2c59e38b841 100644 --- a/packages/react/src/LabelGroup/LabelGroup.tsx +++ b/packages/react/src/LabelGroup/LabelGroup.tsx @@ -151,6 +151,7 @@ const LabelGroup: React.FC> = ({ } // @ts-ignore you can set `.current` on ref objects or ref callbacks in React + // eslint-disable-next-line react-hooks/immutability expandButtonRef.current = node } }, diff --git a/packages/react/src/Link/Link.tsx b/packages/react/src/Link/Link.tsx index 59d218173c1..4a1867cd0b6 100644 --- a/packages/react/src/Link/Link.tsx +++ b/packages/react/src/Link/Link.tsx @@ -31,7 +31,6 @@ export const UnwrappedLink = ( * this is safe, and ensures the entire effect is kept out of prod builds * shaving precious bytes from the output, and avoiding mounting a noop effect */ - // eslint-disable-next-line react-compiler/react-compiler // eslint-disable-next-line react-hooks/rules-of-hooks useEffect(() => { if ( diff --git a/packages/react/src/NavList/NavList.features.stories.tsx b/packages/react/src/NavList/NavList.features.stories.tsx index 218d1135b1e..5501546cb19 100644 --- a/packages/react/src/NavList/NavList.features.stories.tsx +++ b/packages/react/src/NavList/NavList.features.stories.tsx @@ -124,6 +124,7 @@ const NextJSLikeLink = React.forwardRef( ref, href, } + // eslint-disable-next-line react-hooks/refs return <>{React.isValidElement(child) ? React.cloneElement(child, childProps) : null} }, ) diff --git a/packages/react/src/NavList/NavList.test.tsx b/packages/react/src/NavList/NavList.test.tsx index b81e336d204..3965a1f987e 100644 --- a/packages/react/src/NavList/NavList.test.tsx +++ b/packages/react/src/NavList/NavList.test.tsx @@ -14,6 +14,7 @@ const NextJSLikeLink = React.forwardRef( ref, href, } + // eslint-disable-next-line react-hooks/refs return <>{React.isValidElement(child) ? React.cloneElement(child, childProps) : null} }, ) diff --git a/packages/react/src/Portal/Portal.features.stories.tsx b/packages/react/src/Portal/Portal.features.stories.tsx index 4a91b0cad4d..0c45f6ec8bb 100644 --- a/packages/react/src/Portal/Portal.features.stories.tsx +++ b/packages/react/src/Portal/Portal.features.stories.tsx @@ -90,6 +90,7 @@ export const WithPortalContext = () => { if (customContainerRef.current instanceof HTMLElement && overrideContainerRef.current instanceof HTMLElement) { registerPortalRoot(customContainerRef.current, 'custom-portal') registerPortalRoot(overrideContainerRef.current, 'override-portal') + // eslint-disable-next-line react-hooks/set-state-in-effect setMounted(true) } }, []) diff --git a/packages/react/src/Portal/Portal.tsx b/packages/react/src/Portal/Portal.tsx index 816b4c8437d..68797db5a15 100644 --- a/packages/react/src/Portal/Portal.tsx +++ b/packages/react/src/Portal/Portal.tsx @@ -107,7 +107,6 @@ export const Portal: React.FC> = ({ return () => { parentElement.removeChild(element) } - // eslint-disable-next-line react-compiler/react-compiler // eslint-disable-next-line react-hooks/exhaustive-deps }, [element, _containerName, portalContainerName]) diff --git a/packages/react/src/ProgressBar/ProgressBar.stories.tsx b/packages/react/src/ProgressBar/ProgressBar.stories.tsx index 19291d4528b..eeb1ffb40d0 100644 --- a/packages/react/src/ProgressBar/ProgressBar.stories.tsx +++ b/packages/react/src/ProgressBar/ProgressBar.stories.tsx @@ -1,4 +1,4 @@ -import React, {useEffect} from 'react' +import React from 'react' import type {Meta} from '@storybook/react-vite' import {ProgressBar, type ProgressBarProps} from '..' @@ -19,13 +19,10 @@ export default { export const Default = () => export const Playground = ({sections, ...args}: ProgressBarProps & {sections: number}) => { - const [sectionColors, setSectionColors] = React.useState(sectionColorsDefault) - - useEffect(() => { - if (args.bg && args.bg !== '') { - setSectionColors([args.bg, ...sectionColorsDefault]) - } - }, [args.bg]) + let sectionColors = sectionColorsDefault + if (args.bg && args.bg !== '') { + sectionColors = [args.bg, ...sectionColorsDefault] + } if (sections === 1) { return diff --git a/packages/react/src/SelectPanel/SelectPanel.examples.stories.tsx b/packages/react/src/SelectPanel/SelectPanel.examples.stories.tsx index 00b57ebcba3..3141591f221 100644 --- a/packages/react/src/SelectPanel/SelectPanel.examples.stories.tsx +++ b/packages/react/src/SelectPanel/SelectPanel.examples.stories.tsx @@ -362,7 +362,6 @@ export const RepositionAfterLoading = () => { setLoading(false) } }, 2000) - // eslint-disable-next-line react-compiler/react-compiler // eslint-disable-next-line react-hooks/exhaustive-deps }, [open]) @@ -370,7 +369,6 @@ export const RepositionAfterLoading = () => { if (!loading) { setFilteredItems(items.filter(item => item.text.toLowerCase().startsWith(filter.toLowerCase()))) } - // eslint-disable-next-line react-compiler/react-compiler // eslint-disable-next-line react-hooks/exhaustive-deps }, [filter]) @@ -411,7 +409,6 @@ export const SelectPanelRepositionInsideDialog = () => { setLoading(false) } }, 2000) - // eslint-disable-next-line react-compiler/react-compiler // eslint-disable-next-line react-hooks/exhaustive-deps }, [open]) @@ -419,7 +416,6 @@ export const SelectPanelRepositionInsideDialog = () => { if (!loading) { setFilteredItems(items.filter(item => item.text.toLowerCase().startsWith(filter.toLowerCase()))) } - // eslint-disable-next-line react-compiler/react-compiler // eslint-disable-next-line react-hooks/exhaustive-deps }, [filter]) diff --git a/packages/react/src/SelectPanel/SelectPanel.features.stories.tsx b/packages/react/src/SelectPanel/SelectPanel.features.stories.tsx index dd1fa062d03..448dcfc8f74 100644 --- a/packages/react/src/SelectPanel/SelectPanel.features.stories.tsx +++ b/packages/react/src/SelectPanel/SelectPanel.features.stories.tsx @@ -939,6 +939,7 @@ export const WithMessage = () => { const filteredItems = itemsToShow.filter(item => item.text.toLowerCase().startsWith(filter.toLowerCase())) useEffect(() => { + // eslint-disable-next-line react-hooks/set-state-in-effect setFilter('') }, [messageVariant]) diff --git a/packages/react/src/SelectPanel/SelectPanel.tsx b/packages/react/src/SelectPanel/SelectPanel.tsx index 7aa5fef65ce..603a81dc741 100644 --- a/packages/react/src/SelectPanel/SelectPanel.tsx +++ b/packages/react/src/SelectPanel/SelectPanel.tsx @@ -374,7 +374,6 @@ function Panel({ } // Only fire this effect if items have changed - // eslint-disable-next-line react-compiler/react-compiler // eslint-disable-next-line react-hooks/exhaustive-deps }, [items]) diff --git a/packages/react/src/ThemeProvider.tsx b/packages/react/src/ThemeProvider.tsx index c3f74c373a8..1fc1fb5e067 100644 --- a/packages/react/src/ThemeProvider.tsx +++ b/packages/react/src/ThemeProvider.tsx @@ -69,6 +69,7 @@ export const ThemeProvider: React.FC const [dayScheme, setDayScheme] = useSyncedState(props.dayScheme ?? fallbackDayScheme ?? defaultDayScheme) const [nightScheme, setNightScheme] = useSyncedState(props.nightScheme ?? fallbackNightScheme ?? defaultNightScheme) const systemColorMode = useSystemColorMode() + // eslint-disable-next-line react-hooks/refs const resolvedColorMode = resolvedColorModePassthrough.current || resolveColorMode(colorMode, systemColorMode) const colorScheme = chooseColorScheme(resolvedColorMode, dayScheme, nightScheme) const {resolvedTheme, resolvedColorScheme} = React.useMemo( diff --git a/packages/react/src/ToggleSwitch/ToggleSwitch.tsx b/packages/react/src/ToggleSwitch/ToggleSwitch.tsx index 5d151a05f33..f36c21dccb4 100644 --- a/packages/react/src/ToggleSwitch/ToggleSwitch.tsx +++ b/packages/react/src/ToggleSwitch/ToggleSwitch.tsx @@ -125,6 +125,7 @@ const ToggleSwitch = React.forwardRef(func useEffect(() => { if (!loading && isLoadingLabelVisible) { + // eslint-disable-next-line react-hooks/set-state-in-effect setIsLoadingLabelVisible(false) } else if (loading && !isLoadingLabelVisible) { safeSetTimeout(() => { diff --git a/packages/react/src/Token/_RemoveTokenButton.tsx b/packages/react/src/Token/_RemoveTokenButton.tsx index 442db921912..262bd342aac 100644 --- a/packages/react/src/Token/_RemoveTokenButton.tsx +++ b/packages/react/src/Token/_RemoveTokenButton.tsx @@ -21,10 +21,9 @@ const RemoveTokenButton = ({ className, borderOffset = 0, as: _as, + children: _children, ...rest }: React.PropsWithChildren) => { - // eslint-disable-next-line react-compiler/react-compiler - delete rest.children if (isParentInteractive) { return ( } type="button" > diff --git a/packages/react/src/TooltipV2/Tooltip.tsx b/packages/react/src/TooltipV2/Tooltip.tsx index cd4411a0dd9..21a9d4d52c1 100644 --- a/packages/react/src/TooltipV2/Tooltip.tsx +++ b/packages/react/src/TooltipV2/Tooltip.tsx @@ -265,6 +265,7 @@ export const Tooltip: ForwardRefExoticComponent< <> {React.isValidElement(child) && + // eslint-disable-next-line react-hooks/refs React.cloneElement(child as React.ReactElement, { ref: triggerRef, // If it is a type description, we use tooltip to describe the trigger diff --git a/packages/react/src/TreeView/TreeView.tsx b/packages/react/src/TreeView/TreeView.tsx index f1cc0b21cf5..86100c9cbce 100644 --- a/packages/react/src/TreeView/TreeView.tsx +++ b/packages/react/src/TreeView/TreeView.tsx @@ -233,6 +233,7 @@ const Item = React.forwardRef( // Set the expanded state and cache it const setIsExpandedWithCache = React.useCallback( + // eslint-disable-next-line react-hooks/preserve-manual-memoization (newIsExpanded: boolean) => { setIsExpanded(newIsExpanded) expandedStateCache.current?.set(itemId, newIsExpanded) @@ -584,6 +585,7 @@ function usePreviousValue(value: T): T { ref.current = value }, [value]) + // eslint-disable-next-line react-hooks/refs return ref.current } diff --git a/packages/react/src/UnderlineNav/UnderlineNav.tsx b/packages/react/src/UnderlineNav/UnderlineNav.tsx index c72f9c57577..2f6386c9a47 100644 --- a/packages/react/src/UnderlineNav/UnderlineNav.tsx +++ b/packages/react/src/UnderlineNav/UnderlineNav.tsx @@ -185,7 +185,6 @@ export const UnderlineNav = forwardRef( if (__DEV__) { // Practically, this is not a conditional hook, it is just making sure this hook runs only on DEV not PROD. - // eslint-disable-next-line react-compiler/react-compiler // eslint-disable-next-line react-hooks/rules-of-hooks useEffect(() => { // Address illegal state where there are multiple items that have `aria-current='page'` attribute diff --git a/packages/react/src/deprecated/utils/create-slots.tsx b/packages/react/src/deprecated/utils/create-slots.tsx index a86abcef0b9..42cca3abef2 100644 --- a/packages/react/src/deprecated/utils/create-slots.tsx +++ b/packages/react/src/deprecated/utils/create-slots.tsx @@ -76,6 +76,7 @@ const createSlots = (slotNames: SlotNames[]) => { * Slots uses a render prop API so abstract the * implementation detail of using a context provider. */ + // eslint-disable-next-line react-hooks/refs const slots = slotsRef.current return ( diff --git a/packages/react/src/experimental/SelectPanel2/SelectPanel.tsx b/packages/react/src/experimental/SelectPanel2/SelectPanel.tsx index 04667c2b5d2..f1fd2fcc16b 100644 --- a/packages/react/src/experimental/SelectPanel2/SelectPanel.tsx +++ b/packages/react/src/experimental/SelectPanel2/SelectPanel.tsx @@ -126,7 +126,7 @@ const Panel: React.FC = ({ const contents = React.Children.map(props.children, child => { if (React.isValidElement(child) && (child.type === SelectPanelButton || isSlot(child, SelectPanelButton))) { - // eslint-disable-next-line react-compiler/react-compiler + // eslint-disable-next-line react-hooks/immutability Anchor = React.cloneElement(child, { // @ts-ignore TODO ref: anchorRef, @@ -333,6 +333,7 @@ const SelectPanelButton = React.forwardRef((prop return (