diff --git a/package.json b/package.json index 9a413750..590af1c6 100644 --- a/package.json +++ b/package.json @@ -67,8 +67,8 @@ "node-vibrant": "4.0.3", "notistack": "3.0.2", "p-limit": "6.2.0", - "react": "18.3.1", - "react-dom": "18.3.1", + "react": "19.1.0", + "react-dom": "19.1.0", "react-hotkeys-hook": "5.0.1", "react-i18next": "15.4.1", "react-lazily": "0.9.2", @@ -88,9 +88,9 @@ "@graphql-codegen/typescript-operations": "4.6.0", "@types/apollo-upload-client": "18.0.0", "@types/node": "22.14.1", - "@types/react": "18.3.5", + "@types/react": "19.1.2", "@types/react-beautiful-dnd": "13.1.8", - "@types/react-dom": "18.3.0", + "@types/react-dom": "19.1.2", "@types/sanitize-html": "2.15.0", "@types/stylis": "4.2.7", "@types/webfontloader": "1.6.38", diff --git a/src/modules/collection/components/SelectionFAB.tsx b/src/modules/collection/components/SelectionFAB.tsx index 60e7c4db..4cfa8f0e 100644 --- a/src/modules/collection/components/SelectionFAB.tsx +++ b/src/modules/collection/components/SelectionFAB.tsx @@ -10,7 +10,7 @@ import MoreHoriz from '@mui/icons-material/MoreHoriz'; import Fab from '@mui/material/Fab'; import Box from '@mui/material/Box'; import { styled } from '@mui/material/styles'; -import React from 'react'; +import React, { type JSX } from 'react'; import { useTranslation } from 'react-i18next'; import PopupState, { bindMenu, bindTrigger } from 'material-ui-popup-state'; import { DEFAULT_FAB_STYLE } from '@/modules/core/components/buttons/StyledFab.tsx'; diff --git a/src/modules/collection/hooks/useSelectableCollection.ts b/src/modules/collection/hooks/useSelectableCollection.ts index 979f6f03..b066a56a 100644 --- a/src/modules/collection/hooks/useSelectableCollection.ts +++ b/src/modules/collection/hooks/useSelectableCollection.ts @@ -38,7 +38,7 @@ export const useSelectableCollection = => { const [keyToSelectedItemIds, setKeyToSelectedItemIds] = useState>(initialState); - const lastSelectedItemInfoRef = useRef<{ id: Id; key: Key }>(); + const lastSelectedItemInfoRef = useRef<{ id: Id; key: Key }>(undefined); const selectedItemIds = [...new Set(Object.values(keyToSelectedItemIds).flat())]; const areAllItemsSelected = selectedItemIds.length === totalCount; diff --git a/src/modules/core/components/AppbarSearch.tsx b/src/modules/core/components/AppbarSearch.tsx index b3f077b2..c636b464 100644 --- a/src/modules/core/components/AppbarSearch.tsx +++ b/src/modules/core/components/AppbarSearch.tsx @@ -31,7 +31,7 @@ export const AppbarSearch: React.FunctionComponent = (props) => { const [query, setQuery] = useQueryParam('query', StringParam); const [isSearchOpen, setIsSearchOpen] = useState(!isClosable || !!query); - const inputRef = React.useRef(); + const inputRef = React.useRef(undefined); const [searchString, setSearchString] = useState(query ?? ''); diff --git a/src/modules/core/components/menu/IconMenuItem.tsx b/src/modules/core/components/menu/IconMenuItem.tsx index ffee8fba..ad559ad7 100644 --- a/src/modules/core/components/menu/IconMenuItem.tsx +++ b/src/modules/core/components/menu/IconMenuItem.tsx @@ -27,7 +27,7 @@ type IconMenuItemProps = { renderLabel?: () => React.ReactNode; LeftIcon?: OverridableComponent & { muiName: string }; onClick?: (event: React.MouseEvent) => void; - ref?: RefObject; + ref?: RefObject; RightIcon?: OverridableComponent & { muiName: string }; sx?: SxProps; }; diff --git a/src/modules/core/components/menu/Menu.tsx b/src/modules/core/components/menu/Menu.tsx index d3f43961..087d11d7 100644 --- a/src/modules/core/components/menu/Menu.tsx +++ b/src/modules/core/components/menu/Menu.tsx @@ -7,7 +7,7 @@ */ import MuiMenu, { MenuProps } from '@mui/material/Menu'; -import { useState } from 'react'; +import { useState, type JSX } from 'react'; export const Menu = ({ children, diff --git a/src/modules/core/components/placeholder/EmptyView.tsx b/src/modules/core/components/placeholder/EmptyView.tsx index 3ba364ad..c90ff4ae 100644 --- a/src/modules/core/components/placeholder/EmptyView.tsx +++ b/src/modules/core/components/placeholder/EmptyView.tsx @@ -8,7 +8,7 @@ // adopted from: https://github.com/tachiyomiorg/tachiyomi/blob/master/app/src/main/java/eu/kanade/tachiyomi/widget/EmptyView.kt -import { useMemo, useState } from 'react'; +import { useMemo, useState, type JSX } from 'react'; import Typography from '@mui/material/Typography'; import { SxProps, Theme } from '@mui/material/styles'; import { useTranslation } from 'react-i18next'; diff --git a/src/modules/core/components/placeholder/LoadingPlaceholder.tsx b/src/modules/core/components/placeholder/LoadingPlaceholder.tsx index 3da97b1a..6fb40232 100644 --- a/src/modules/core/components/placeholder/LoadingPlaceholder.tsx +++ b/src/modules/core/components/placeholder/LoadingPlaceholder.tsx @@ -6,7 +6,7 @@ * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ -import React from 'react'; +import React, { type JSX } from 'react'; import CircularProgress from '@mui/material/CircularProgress'; import Box from '@mui/material/Box'; diff --git a/src/modules/core/components/settings/MutableListSetting.tsx b/src/modules/core/components/settings/MutableListSetting.tsx index 13afbf49..82f211d4 100644 --- a/src/modules/core/components/settings/MutableListSetting.tsx +++ b/src/modules/core/components/settings/MutableListSetting.tsx @@ -14,7 +14,7 @@ import ListItemButton from '@mui/material/ListItemButton'; import ListItemText from '@mui/material/ListItemText'; import Stack from '@mui/material/Stack'; import Typography from '@mui/material/Typography'; -import { useEffect, useState } from 'react'; +import { useEffect, useState, type JSX } from 'react'; import DialogContent from '@mui/material/DialogContent'; import DialogActions from '@mui/material/DialogActions'; import { useTranslation } from 'react-i18next'; diff --git a/src/modules/core/hooks/useAutomaticScrolling.ts b/src/modules/core/hooks/useAutomaticScrolling.ts index afe0bbf7..cfc64d51 100644 --- a/src/modules/core/hooks/useAutomaticScrolling.ts +++ b/src/modules/core/hooks/useAutomaticScrolling.ts @@ -77,8 +77,8 @@ export const useAutomaticScrolling = ( } => { const isCallback = typeof refOrCallback === 'function'; - const elementStyle = useRef(); - const scrollTriggerTimer = useRef(); + const elementStyle = useRef(undefined); + const scrollTriggerTimer = useRef(undefined); const scrollTriggerAnimationFrameId = useRef(-1); const [isActive, setIsActive] = useState(false); diff --git a/src/modules/core/hooks/useIntersectionObserver.tsx b/src/modules/core/hooks/useIntersectionObserver.tsx index ebf09f16..d17e9feb 100644 --- a/src/modules/core/hooks/useIntersectionObserver.tsx +++ b/src/modules/core/hooks/useIntersectionObserver.tsx @@ -9,7 +9,7 @@ import { RefObject, useLayoutEffect, useState } from 'react'; export const useIntersectionObserver = ( - ref: RefObject | HTMLElement | undefined | null, + ref: RefObject | HTMLElement | undefined | null, callback: IntersectionObserverCallback, { ignoreInitialObserve = false, diff --git a/src/modules/core/hooks/useMouseDragScroll.tsx b/src/modules/core/hooks/useMouseDragScroll.tsx index 4c9d2d62..2f5956bb 100644 --- a/src/modules/core/hooks/useMouseDragScroll.tsx +++ b/src/modules/core/hooks/useMouseDragScroll.tsx @@ -32,12 +32,12 @@ export const useMouseDragScroll = ( ) => { const [isDragging, setIsDragging] = useState(false); - const elementStyle = useRef(); + const elementStyle = useRef(undefined); const previousClickPosX = useRef([0, 0, 0]); const previousClickPosY = useRef([0, 0, 0]); const previousClickTime = useRef([0, 0, 0]); const scrollAtT0 = useRef<[ScrollLeft: number, ScrollTop: number]>([0, 0]); - const inertiaTimeInterval = useRef(); + const inertiaTimeInterval = useRef(undefined); useEffect(() => { const element = ref?.current; diff --git a/src/modules/core/hooks/useResizeObserver.tsx b/src/modules/core/hooks/useResizeObserver.tsx index da3ea04d..da138693 100644 --- a/src/modules/core/hooks/useResizeObserver.tsx +++ b/src/modules/core/hooks/useResizeObserver.tsx @@ -9,7 +9,7 @@ import { RefObject, useLayoutEffect, useState } from 'react'; export const useResizeObserver = ( - ref: RefObject | HTMLElement | undefined | null, + ref: RefObject | HTMLElement | undefined | null, callback: ResizeObserverCallback, ): (() => void) => { const [disconnect, setDisconnect] = useState<() => void>(() => {}); diff --git a/src/modules/manga/Manga.types.ts b/src/modules/manga/Manga.types.ts index 0b6f4567..391ea34c 100644 --- a/src/modules/manga/Manga.types.ts +++ b/src/modules/manga/Manga.types.ts @@ -8,6 +8,7 @@ import { LongPressPointerHandlers, LongPressResult } from 'use-long-press/lib/use-long-press.types'; import { PopupState } from 'material-ui-popup-state/hooks'; +import type { JSX } from 'react'; import { SelectableCollectionReturnType } from '@/modules/collection/hooks/useSelectableCollection.ts'; import { useManageMangaLibraryState } from '@/modules/manga/hooks/useManageMangaLibraryState.tsx'; import { diff --git a/src/modules/manga/components/MangaGrid.tsx b/src/modules/manga/components/MangaGrid.tsx index ce0b80e1..fc50e9e8 100644 --- a/src/modules/manga/components/MangaGrid.tsx +++ b/src/modules/manga/components/MangaGrid.tsx @@ -15,6 +15,7 @@ import React, { useMemo, useRef, useState, + type JSX, } from 'react'; import Grid, { GridTypeMap } from '@mui/material/Grid'; import Box, { BoxProps } from '@mui/material/Box'; @@ -164,7 +165,7 @@ const VerticalGrid = forwardRef( const snapshotSessionKey = getGridSnapshotKey(location); const [snapshot] = useSessionStorage(snapshotSessionKey, undefined); - const persistGridStateTimeout = useRef(); + const persistGridStateTimeout = useRef(undefined); const persistGridState = (gridState: GridStateSnapshot) => { const currentUrl = window.location.href; diff --git a/src/modules/reader/components/overlay/navigation/desktop/quick-settings/ReaderNavBarDesktopAutoScroll.tsx b/src/modules/reader/components/overlay/navigation/desktop/quick-settings/ReaderNavBarDesktopAutoScroll.tsx index 50ebb9bf..08be8ef0 100644 --- a/src/modules/reader/components/overlay/navigation/desktop/quick-settings/ReaderNavBarDesktopAutoScroll.tsx +++ b/src/modules/reader/components/overlay/navigation/desktop/quick-settings/ReaderNavBarDesktopAutoScroll.tsx @@ -28,7 +28,7 @@ export const ReaderNavBarDesktopAutoScroll = ({ const { t } = useTranslation(); const { isActive, toggleActive } = useReaderAutoScrollContext(); - const updateTimeout = useRef(); + const updateTimeout = useRef(undefined); return ( diff --git a/src/modules/reader/components/overlay/progress-bar/ReaderProgressBar.tsx b/src/modules/reader/components/overlay/progress-bar/ReaderProgressBar.tsx index 5ab53a1f..3f63e5ef 100644 --- a/src/modules/reader/components/overlay/progress-bar/ReaderProgressBar.tsx +++ b/src/modules/reader/components/overlay/progress-bar/ReaderProgressBar.tsx @@ -76,7 +76,7 @@ const BaseReaderProgressBar = ({ fullSegmentClicks: boolean; }) => { const progressBarRef = useRef(null); - const draggingDetectionTimeout = useRef(); + const draggingDetectionTimeout = useRef(undefined); const [totalPagesTextWidth, setTotalPagesTextWidth] = useState(0); const totalPagesTextRef = useRef(null); diff --git a/src/modules/reader/hooks/useReaderHideCursorOnInactivity.ts b/src/modules/reader/hooks/useReaderHideCursorOnInactivity.ts index 6654d53f..e7cd9b83 100644 --- a/src/modules/reader/hooks/useReaderHideCursorOnInactivity.ts +++ b/src/modules/reader/hooks/useReaderHideCursorOnInactivity.ts @@ -9,7 +9,7 @@ import { MutableRefObject, useEffect, useRef } from 'react'; export const useReaderHideCursorOnInactivity = (scrollElementRef: MutableRefObject) => { - const mouseInactiveTimeout = useRef(); + const mouseInactiveTimeout = useRef(undefined); useEffect(() => { const setCursorVisibility = (visible: boolean) => { diff --git a/src/modules/reader/hooks/useReaderSetPagesState.ts b/src/modules/reader/hooks/useReaderSetPagesState.ts index acf9aef8..aa8813aa 100644 --- a/src/modules/reader/hooks/useReaderSetPagesState.ts +++ b/src/modules/reader/hooks/useReaderSetPagesState.ts @@ -39,7 +39,7 @@ export const useReaderSetPagesState = ( setPageToScrollToIndex: ReaderStatePages['setPageToScrollToIndex'], setTransitionPageMode: ReaderStatePages['setTransitionPageMode'], ) => { - const previousPageData = useRef(); + const previousPageData = useRef(undefined); useLayoutEffect(() => { const pagesPayload = pagesResponse.data?.fetchChapterPages; diff --git a/src/modules/reader/hooks/useReaderShowSettingPreviewOnChange.ts b/src/modules/reader/hooks/useReaderShowSettingPreviewOnChange.ts index adb806e1..d4773356 100644 --- a/src/modules/reader/hooks/useReaderShowSettingPreviewOnChange.ts +++ b/src/modules/reader/hooks/useReaderShowSettingPreviewOnChange.ts @@ -30,9 +30,9 @@ export const useReaderShowSettingPreviewOnChange = ( const { t } = useTranslation(); // show setting previews on change or when open reader - const previousReadingMode = useRef(); - const previousTapZoneLayout = useRef(); - const previousTapZoneInvertMode = useRef(); + const previousReadingMode = useRef(undefined); + const previousTapZoneLayout = useRef(undefined); + const previousTapZoneInvertMode = useRef(undefined); const isInitialPreview = useRef(true); useEffect(() => { diff --git a/src/modules/reader/utils/ReaderSettings.utils.tsx b/src/modules/reader/utils/ReaderSettings.utils.tsx index 2a93125c..623917b6 100644 --- a/src/modules/reader/utils/ReaderSettings.utils.tsx +++ b/src/modules/reader/utils/ReaderSettings.utils.tsx @@ -6,7 +6,7 @@ * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ -import { ForwardRefExoticComponent, MemoExoticComponent, RefAttributes } from 'react'; +import { NamedExoticComponent, RefAttributes } from 'react'; import { IReaderSettings, IReaderSettingsWithDefaultFlag, @@ -59,7 +59,7 @@ export const isAutoWebtoonMode = ( export const getPagerForReadingMode = ( readingMode: ReadingMode, -): MemoExoticComponent>> => { +): NamedExoticComponent> => { switch (readingMode) { case ReadingMode.SINGLE_PAGE: return ReaderPagedPager; diff --git a/yarn.lock b/yarn.lock index 3f160ee4..eb2ff3da 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2983,12 +2983,10 @@ dependencies: "@types/react" "*" -"@types/react-dom@18.3.0": - version "18.3.0" - resolved "https://registry.yarnpkg.com/@types/react-dom/-/react-dom-18.3.0.tgz#0cbc818755d87066ab6ca74fbedb2547d74a82b0" - integrity sha512-EhwApuTmMBmXuFOikhQLIBUn6uFg81SwLMOAUgodJF14SOBOCMdU04gDoYi0WOJJHD144TL32z4yDqCW3dnkQg== - dependencies: - "@types/react" "*" +"@types/react-dom@19.1.2": + version "19.1.2" + resolved "https://registry.yarnpkg.com/@types/react-dom/-/react-dom-19.1.2.tgz#bd1fe3b8c28a3a2e942f85314dcfb71f531a242f" + integrity sha512-XGJkWF41Qq305SKWEILa1O8vzhb3aOo3ogBlSmiqNko/WmRb6QIaweuZCXjKygVDXpzXb5wyxKTSOsmkuqj+Qw== "@types/react-transition-group@^4.4.12": version "4.4.12" @@ -3003,12 +3001,11 @@ "@types/prop-types" "*" csstype "^3.0.2" -"@types/react@18.3.5": - version "18.3.5" - resolved "https://registry.yarnpkg.com/@types/react/-/react-18.3.5.tgz#5f524c2ad2089c0ff372bbdabc77ca2c4dbadf8f" - integrity sha512-WeqMfGJLGuLCqHGYRGHxnKrXcTitc6L/nBUWfWPcTarG3t9PsquqUMuVeXZeca+mglY4Vo5GZjCi0A3Or2lnxA== +"@types/react@19.1.2": + version "19.1.2" + resolved "https://registry.yarnpkg.com/@types/react/-/react-19.1.2.tgz#11df86f66f188f212c90ecb537327ec68bfd593f" + integrity sha512-oxLPMytKchWGbnQM9O7D67uPa9paTNxO7jVoNMXgkkErULBPhPARCfkKL9ytcIJJRGjbsVwW4ugJzyFFvm/Tiw== dependencies: - "@types/prop-types" "*" csstype "^3.0.2" "@types/sanitize-html@2.15.0": @@ -6395,7 +6392,7 @@ log-update@^6.1.0: strip-ansi "^7.1.0" wrap-ansi "^9.0.0" -loose-envify@^1.0.0, loose-envify@^1.1.0, loose-envify@^1.4.0: +loose-envify@^1.0.0, loose-envify@^1.4.0: version "1.4.0" resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.4.0.tgz#71ee51fa7be4caec1a63839f7e682d8132d30caf" integrity sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q== @@ -7074,13 +7071,12 @@ queue-microtask@^1.2.2: resolved "https://registry.yarnpkg.com/queue-microtask/-/queue-microtask-1.2.3.tgz#4929228bbc724dfac43e0efb058caf7b6cfb6243" integrity sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A== -react-dom@18.3.1: - version "18.3.1" - resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-18.3.1.tgz#c2265d79511b57d479b3dd3fdfa51536494c5cb4" - integrity sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw== +react-dom@19.1.0: + version "19.1.0" + resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-19.1.0.tgz#133558deca37fa1d682708df8904b25186793623" + integrity sha512-Xs1hdnE+DyKgeHJeJznQmYMIBG3TKIHJJT95Q58nHLSrElKlGQqDTR2HQ9fx5CN/Gk6Vh/kupBTDLU11/nDk/g== dependencies: - loose-envify "^1.1.0" - scheduler "^0.23.2" + scheduler "^0.26.0" react-hotkeys-hook@5.0.1: version "5.0.1" @@ -7145,12 +7141,10 @@ react-virtuoso@4.12.6: resolved "https://registry.yarnpkg.com/react-virtuoso/-/react-virtuoso-4.12.6.tgz#20fe374d43cce3c9821e29f4cc4d050596d06d01" integrity sha512-bfvS6aCL1ehXmq39KRiz/vxznGUbtA27I5I24TYCe1DhMf84O3aVNCIwrSjYQjkJGJGzY46ihdN8WkYlemuhMQ== -react@18.3.1: - version "18.3.1" - resolved "https://registry.yarnpkg.com/react/-/react-18.3.1.tgz#49ab892009c53933625bd16b2533fc754cab2891" - integrity sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ== - dependencies: - loose-envify "^1.1.0" +react@19.1.0: + version "19.1.0" + resolved "https://registry.yarnpkg.com/react/-/react-19.1.0.tgz#926864b6c48da7627f004795d6cce50e90793b75" + integrity sha512-FS+XFBNvn3GTAWq26joslQgWNoFu08F4kl0J4CgdNKADkdSGXQyTCnKteIAJy96Br6YbpEU1LSzV5dYtjMkMDg== readable-stream@^3.4.0, readable-stream@^3.6.0: version "3.6.2" @@ -7505,12 +7499,10 @@ sanitize-html@2.16.0: parse-srcset "^1.0.2" postcss "^8.3.11" -scheduler@^0.23.2: - version "0.23.2" - resolved "https://registry.yarnpkg.com/scheduler/-/scheduler-0.23.2.tgz#414ba64a3b282892e944cf2108ecc078d115cdc3" - integrity sha512-UOShsPwz7NrMUqhR6t0hWjFduvOzbtv7toDH1/hIrfRNIDBnnBWd0CwJTGvTpngVlmwGCdP9/Zl/tVrDqcuYzQ== - dependencies: - loose-envify "^1.1.0" +scheduler@^0.26.0: + version "0.26.0" + resolved "https://registry.yarnpkg.com/scheduler/-/scheduler-0.26.0.tgz#4ce8a8c2a2095f13ea11bf9a445be50c555d6337" + integrity sha512-NlHwttCI/l5gCPR3D1nNXtWABUmBwvZpEQiD4IXSbIDq8BzLIK/7Ir5gTFSGZDUu37K5cMNp0hFtzO38sC7gWA== scuid@^1.1.0: version "1.1.0"