⬆️(frontend) upgrade frontend to ESLint 9

Manually upgrade the frontend codebase to ESLint 9.

Update the linting configuration and related code where required to
maintain compatibility with the new major version.
This commit is contained in:
lebaudantoine
2026-06-03 17:39:51 +02:00
committed by aleb_the_flash
parent 73a7841b96
commit 6ccc9ef0bf
18 changed files with 1696 additions and 775 deletions
-21
View File
@@ -1,21 +0,0 @@
module.exports = {
root: true,
env: { browser: true, es2020: true },
extends: [
'eslint:recommended',
'plugin:@typescript-eslint/recommended',
'plugin:react-hooks/recommended',
'plugin:@tanstack/eslint-plugin-query/recommended',
'plugin:jsx-a11y/recommended',
'prettier'
],
ignorePatterns: ['dist', '.eslintrc.cjs', 'styled-system'],
parser: '@typescript-eslint/parser',
plugins: ['react-refresh'],
rules: {
'react-refresh/only-export-components': [
'warn',
{ allowConstantExport: true },
],
},
}
+78
View File
@@ -0,0 +1,78 @@
// src/frontend/eslint.config.js
import js from '@eslint/js'
import tseslint from 'typescript-eslint'
import reactPlugin from 'eslint-plugin-react'
import reactHooks from 'eslint-plugin-react-hooks'
import reactRefresh from 'eslint-plugin-react-refresh'
import jsxA11y from 'eslint-plugin-jsx-a11y'
import globals from 'globals'
export default tseslint.config(
// Global ignores (replaces .eslintignore)
{
ignores: [
'dist/**',
'node_modules/**',
'coverage/**',
'src/styled-system/**',
],
},
// Base JS recommended rules
js.configs.recommended,
// TypeScript recommended rules (parser + rules bundled together)
...tseslint.configs.recommended,
// React-specific config
{
files: ['**/*.{ts,tsx}'],
plugins: {
react: reactPlugin,
'react-hooks': reactHooks,
'react-refresh': reactRefresh,
'jsx-a11y': jsxA11y,
},
languageOptions: {
globals: {
...globals.browser,
},
parserOptions: {
ecmaFeatures: { jsx: true },
},
},
settings: {
react: { version: 'detect' },
},
rules: {
// React rules
...reactPlugin.configs.recommended.rules,
...reactHooks.configs.recommended.rules,
'react/react-in-jsx-scope': 'off', // not needed with React 17+
'react-refresh/only-export-components': [
'warn',
{ allowConstantExport: true },
],
// jsx-a11y recommended rules
...jsxA11y.configs.recommended.rules,
// TypeScript rules you may want to adjust
'@typescript-eslint/no-unused-vars': [
'error',
{ argsIgnorePattern: '^_' },
],
'@typescript-eslint/no-explicit-any': 'warn',
},
},
// CJS and root-level JS config files (postcss.config.js, etc.)
{
files: ['**/*.cjs', '*.config.js'],
languageOptions: {
globals: {
...globals.node,
},
},
}
)
+1594 -736
View File
File diff suppressed because it is too large Load Diff
+6 -3
View File
@@ -8,6 +8,7 @@
"build": "panda codegen && tsc -b && vite build",
"build:debug": "VITE_ANALYZE=true npm run build -- --debug",
"lint": "eslint . --ext ts,tsx --report-unused-disable-directives --max-warnings 0",
"lint:fix": "eslint . --fix",
"preview": "vite preview",
"i18n:extract": "npx i18next -c i18next-parser.config.json",
"format": "prettier --write ./src",
@@ -45,6 +46,7 @@
"wouter": "3.9.0"
},
"devDependencies": {
"@eslint/js": "9.39.4",
"@pandacss/dev": "1.11.1",
"@tanstack/eslint-plugin-query": "5.91.4",
"@tanstack/react-query-devtools": "5.91.3",
@@ -52,18 +54,19 @@
"@types/node": "22.16.0",
"@types/react": "18.3.12",
"@types/react-dom": "18.3.1",
"@typescript-eslint/eslint-plugin": "8.35.1",
"@typescript-eslint/parser": "8.35.1",
"@vitejs/plugin-react": "5.1.4",
"eslint": "8.57.0",
"eslint": "9.39.4",
"eslint-config-prettier": "10.1.5",
"eslint-plugin-jsx-a11y": "6.10.2",
"eslint-plugin-react": "7.37.5",
"eslint-plugin-react-hooks": "5.2.0",
"eslint-plugin-react-refresh": "0.4.20",
"globals": "17.6.0",
"postcss": "8.5.14",
"prettier": "3.8.1",
"rollup-plugin-visualizer": "7.0.1",
"typescript": "5.8.3",
"typescript-eslint": "8.60.1",
"vite": "7.3.2",
"vite-plugin-svgr": "5.2.0",
"vite-tsconfig-paths": "6.1.1"
@@ -29,7 +29,6 @@ export const useUser = (
}, [data, opts, isConfigLoading])
const query = useQuery({
// eslint-disable-next-line @tanstack/query/exhaustive-deps
queryKey: [keys.user],
queryFn: () => fetchUser(options),
staleTime: Infinity,
@@ -116,7 +116,7 @@ export const PipOptionsMenu = ({ overflowControls }: PipOptionsMenuProps) => {
zIndex: 10,
})}
>
{/* eslint-disable-next-line jsx-a11y/no-autofocus */}
{/* eslint-disable-next-line jsx-a11y/no-autofocus*/}
<FocusScope autoFocus>
<Box size="sm" type="popover" variant="dark">
<PipOptionsMenuItems overflowControls={overflowControls} />
@@ -12,7 +12,9 @@ export const useLowerHandParticipants = () => {
return Promise.all(promises)
} catch (error) {
console.error('An error occurred while lowering hands :', error)
throw new Error('An error occurred while lowering hands.')
throw new Error('An error occurred while lowering hands.', {
cause: error,
})
}
}
return { lowerHandParticipants }
@@ -12,7 +12,9 @@ export const useMuteParticipants = () => {
return Promise.all(promises)
} catch (error) {
console.error('An error occurred while muting participants :', error)
throw new Error('An error occurred while muting participants.')
throw new Error('An error occurred while muting participants.', {
cause: error,
})
}
}
return { muteParticipants }
@@ -16,7 +16,9 @@ export const useUpdateParticipantsPermissions = () => {
return Promise.all(promises)
} catch (error) {
console.error('An error occurred while updating permissions :', error)
throw new Error('An error occurred while updating permissions.')
throw new Error('An error occurred while updating permissions.', {
cause: error,
})
}
}
return { updateParticipantsPermissions }
@@ -72,7 +72,6 @@ export const Conference = ({
isError: isFetchError,
data,
} = useQuery({
/* eslint-disable @tanstack/query/exhaustive-deps */
queryKey: fetchKey,
staleTime: 6 * 60 * 60 * 1000, // By default, LiveKit access tokens expire 6 hours after generation
initialData: initialRoomData,
@@ -301,7 +301,6 @@ export const Join = ({
isError,
refetch: refetchRoom,
} = useQuery({
/* eslint-disable @tanstack/query/exhaustive-deps */
queryKey: [keys.room, roomId],
queryFn: () => fetchRoom({ roomId, username }),
staleTime: 6 * 60 * 60 * 1000, // By default, LiveKit access tokens expire 6 hours after generation
@@ -582,7 +581,7 @@ export const Join = ({
transform: 'scale(1.02)',
})}
>
{/* eslint-disable-next-line jsx-a11y/media-has-caption */}
{/* eslint-disable jsx-a11y/media-has-caption */}
<video
ref={videoEl}
width="1280"
@@ -37,7 +37,6 @@ export const useLobby = ({
}, [clearWaitingTimeout])
const { data: waitingData } = useQuery({
/* eslint-disable @tanstack/query/exhaustive-deps */
queryKey: [keys.requestEntry, roomId],
queryFn: async () => {
const response = await requestEntry({
@@ -23,7 +23,6 @@ export const useVideoResolutionSubscription = () => {
if (!room) return
const handleTrackPublished = (
publication: RemoteTrackPublication,
// eslint-disable-next-line @typescript-eslint/no-unused-vars
_participant: RemoteParticipant
) => {
// By default, the maximum quality is set to high
@@ -24,7 +24,7 @@ export const SettingsDialog = (props: SettingsDialogProps) => {
<Trans
i18nKey="settings:account.currentlyLoggedAs"
values={{ user: userDisplay }}
components={[<Badge />]}
components={[<Badge key="user-badge" />]}
/>
</P>
<P>
@@ -61,7 +61,7 @@ export const AccountTab = ({ id, onOpenChange }: AccountTabProps) => {
<Trans
i18nKey="settings:account.currentlyLoggedAs"
values={{ user: userDisplay }}
components={[<Badge />]}
components={[<Badge key="user-badge" />]}
/>
</P>
<P>
@@ -180,7 +180,7 @@ export const VideoTab = ({ id }: VideoTabProps) => {
>
{localParticipant.isCameraEnabled ? (
<>
{/* eslint-disable-next-line jsx-a11y/media-has-caption */}
{/* eslint-disable jsx-a11y/media-has-caption */}
<video
ref={videoCallbackRef}
width="160px"
+2
View File
@@ -38,3 +38,5 @@ export const Button = forwardRef<HTMLButtonElement, ButtonProps>(
)
}
)
Button.displayName = 'Button'
+2 -2
View File
@@ -2,9 +2,9 @@
"compilerOptions": {
"composite": true,
"tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo",
"target": "ES2020",
"target": "ES2022",
"useDefineForClassFields": true,
"lib": ["ES2020", "DOM", "DOM.Iterable"],
"lib": ["ES2022", "DOM", "DOM.Iterable"],
"module": "ESNext",
"skipLibCheck": true,