diff --git a/.npmrc b/.npmrc new file mode 100644 index 000000000..b5872d0e5 --- /dev/null +++ b/.npmrc @@ -0,0 +1,5 @@ +# eslint-plugin-import, eslint-plugin-react, eslint-plugin-jsx-a11y, and +# eslint-plugin-jest-dom declare peer dependencies up to eslint@^9 but work +# correctly with ESLint 10 via @eslint/compat fixupPluginRules(). +# Remove this once those plugins publish ESLint 10-compatible releases. +legacy-peer-deps=true diff --git a/eslint.config.js b/eslint.config.js index c155a8610..5c12bb1bc 100644 --- a/eslint.config.js +++ b/eslint.config.js @@ -1,5 +1,6 @@ import js from '@eslint/js'; import globals from 'globals'; +import { fixupPluginRules } from '@eslint/compat'; import reactPlugin from 'eslint-plugin-react'; import reactHooksPlugin from 'eslint-plugin-react-hooks'; import jsxA11yPlugin from 'eslint-plugin-jsx-a11y'; @@ -46,10 +47,14 @@ export default [ }, plugins: { - import: importPlugin, - 'jest-dom': jestDomPlugin, - 'jsx-a11y': jsxA11yPlugin, - react: reactPlugin, + // eslint-plugin-import, react, jsx-a11y, and jest-dom still declare ESLint + // peer deps up to ^9; wrap them with fixupPluginRules so their internal use + // of removed context APIs (e.g. getFilename, getSourceCode) keeps working. + import: fixupPluginRules(importPlugin), + 'jest-dom': fixupPluginRules(jestDomPlugin), + 'jsx-a11y': fixupPluginRules(jsxA11yPlugin), + react: fixupPluginRules(reactPlugin), + // react-hooks and testing-library already declare ESLint 10 support 'react-hooks': reactHooksPlugin, 'testing-library': testingLibraryPlugin, }, diff --git a/package.json b/package.json index 41b99d9e9..e55a597a1 100644 --- a/package.json +++ b/package.json @@ -83,8 +83,7 @@ "@emotion/react": "^11.10.6", "@emotion/styled": "^11.10.6", "@eslint/compat": "^2.0.3", - "@eslint/eslintrc": "^3.3.5", - "@eslint/js": "^9.39.4", + "@eslint/js": "^10.0.0", "@mui/material": "^7.x", "@mui/system": "^7.x", "@testing-library/dom": "^10.4.0", @@ -96,7 +95,7 @@ "@vitest/ui": "^4.1.2", "bundlewatch": "^0.4.0", "chalk": "^5.3.0", - "eslint": "^9.39.4", + "eslint": "^10.0.0", "eslint-plugin-import": "^2.32.0", "eslint-plugin-jest-dom": "^5.5.0", "eslint-plugin-jsx-a11y": "^6.10.2", @@ -104,7 +103,7 @@ "eslint-plugin-react-hooks": "^5.2.0", "eslint-plugin-testing-library": "^7.16.2", "glob": "^13.0.6", - "globals": "^15.15.0", + "globals": "^16.0.0", "happy-dom": "^20.0", "react": "^19.0.0", "react-dnd-test-backend": "^16.0.1", diff --git a/src/components/AnnotationsOverlay.jsx b/src/components/AnnotationsOverlay.jsx index 152ddce6a..0ad44412c 100644 --- a/src/components/AnnotationsOverlay.jsx +++ b/src/components/AnnotationsOverlay.jsx @@ -159,9 +159,8 @@ export function AnnotationsOverlay({ }; }; - let annosWithScore = []; let radius = 1; - annosWithScore = sortBy(annos.map(annosWithClickScore(radius)), 'score'); + let annosWithScore = sortBy(annos.map(annosWithClickScore(radius)), 'score'); while (radius < Math.max(canvasWidth, canvasHeight) && annosWithScore[0].score === annosWithScore[1].score) { diff --git a/src/components/ViewerNavigation.jsx b/src/components/ViewerNavigation.jsx index 588a20506..4cb15f8bb 100644 --- a/src/components/ViewerNavigation.jsx +++ b/src/components/ViewerNavigation.jsx @@ -14,8 +14,8 @@ export function ViewerNavigation({ }) { const { t } = useTranslation(); let htmlDir = 'ltr'; - let previousIconStyle = {}; - let nextIconStyle = {}; + let previousIconStyle; + let nextIconStyle; switch (viewingDirection) { case 'top-to-bottom': previousIconStyle = { transform: 'rotate(270deg)' }; diff --git a/src/components/WindowTopBarTitle.jsx b/src/components/WindowTopBarTitle.jsx index d7247a02b..da5d5fdc5 100644 --- a/src/components/WindowTopBarTitle.jsx +++ b/src/components/WindowTopBarTitle.jsx @@ -34,7 +34,7 @@ TitleTypography.propTypes = { export function WindowTopBarTitle({ error = null, hideWindowTitle = false, isFetching = false, manifestTitle = '', }) { - let title = null; + let title; if (isFetching) { title = (