Use "mantine/hooks"
This commit is contained in:
@@ -42,6 +42,7 @@
|
|||||||
"@fontsource/roboto": "5.2.5",
|
"@fontsource/roboto": "5.2.5",
|
||||||
"@juggle/resize-observer": "3.4.0",
|
"@juggle/resize-observer": "3.4.0",
|
||||||
"@loadable/component": "5.16.4",
|
"@loadable/component": "5.16.4",
|
||||||
|
"@mantine/hooks": "^7.17.5",
|
||||||
"@mui/icons-material": "7.0.2",
|
"@mui/icons-material": "7.0.2",
|
||||||
"@mui/material": "7.0.2",
|
"@mui/material": "7.0.2",
|
||||||
"@mui/system": "7.0.2",
|
"@mui/system": "7.0.2",
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { useEffect, useLayoutEffect, useState } from 'react';
|
import { useEffect, useLayoutEffect, useRef, useState } from 'react';
|
||||||
import List from '@mui/material/List';
|
import List from '@mui/material/List';
|
||||||
import ListItemText from '@mui/material/ListItemText';
|
import ListItemText from '@mui/material/ListItemText';
|
||||||
import { fromEvent } from 'file-selector';
|
import { fromEvent } from 'file-selector';
|
||||||
@@ -23,6 +23,7 @@ import Button from '@mui/material/Button';
|
|||||||
import ListItem from '@mui/material/ListItem';
|
import ListItem from '@mui/material/ListItem';
|
||||||
import { Link } from 'react-router-dom';
|
import { Link } from 'react-router-dom';
|
||||||
import Stack from '@mui/material/Stack';
|
import Stack from '@mui/material/Stack';
|
||||||
|
import { useEventListener, useMergedRef, useWindowEvent } from '@mantine/hooks';
|
||||||
import { requestManager } from '@/lib/requests/RequestManager.ts';
|
import { requestManager } from '@/lib/requests/RequestManager.ts';
|
||||||
import { makeToast } from '@/modules/core/utils/Toast.ts';
|
import { makeToast } from '@/modules/core/utils/Toast.ts';
|
||||||
import { BackupRestoreState, ValidateBackupQuery } from '@/lib/graphql/generated/graphql.ts';
|
import { BackupRestoreState, ValidateBackupQuery } from '@/lib/graphql/generated/graphql.ts';
|
||||||
@@ -89,6 +90,8 @@ export function Backup() {
|
|||||||
|
|
||||||
const [, setTriggerReRender] = useState(0);
|
const [, setTriggerReRender] = useState(0);
|
||||||
|
|
||||||
|
const inputRef = useRef<HTMLInputElement>(null);
|
||||||
|
|
||||||
const restoreProgress = (() => {
|
const restoreProgress = (() => {
|
||||||
if (!data?.restoreStatus) {
|
if (!data?.restoreStatus) {
|
||||||
return 0;
|
return 0;
|
||||||
@@ -193,40 +196,25 @@ export function Backup() {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const dropHandler = async (e: Event) => {
|
|
||||||
e.preventDefault();
|
|
||||||
const files = await fromEvent(e);
|
|
||||||
|
|
||||||
submitBackup(files[0] as File);
|
|
||||||
};
|
|
||||||
|
|
||||||
const dragOverHandler = (e: Event) => {
|
|
||||||
e.preventDefault();
|
|
||||||
};
|
|
||||||
|
|
||||||
const closeInvalidBackupDialog = () => {
|
const closeInvalidBackupDialog = () => {
|
||||||
setIsInvalidBackupDialogOpen(false);
|
setIsInvalidBackupDialogOpen(false);
|
||||||
resetBackupState();
|
resetBackupState();
|
||||||
};
|
};
|
||||||
|
|
||||||
useEffect(() => {
|
useWindowEvent('drop', async (e) => {
|
||||||
document.addEventListener('drop', dropHandler);
|
e.preventDefault();
|
||||||
document.addEventListener('dragover', dragOverHandler);
|
const files = await fromEvent(e);
|
||||||
|
|
||||||
const handleFileSelection = async (event: Event) => {
|
submitBackup(files[0] as File);
|
||||||
const files = await fromEvent(event);
|
});
|
||||||
submitBackup(files[0] as File);
|
useWindowEvent('dragover', (e) => {
|
||||||
};
|
e.preventDefault();
|
||||||
|
});
|
||||||
const input = document.getElementById('backup-file');
|
const inputEventListenerRef = useEventListener('change', async (event) => {
|
||||||
input?.addEventListener('change', handleFileSelection);
|
const files = await fromEvent(event);
|
||||||
|
submitBackup(files[0] as File);
|
||||||
return () => {
|
});
|
||||||
document.removeEventListener('drop', dropHandler);
|
const mergedInputRef = useMergedRef(inputRef, inputEventListenerRef);
|
||||||
document.removeEventListener('dragover', dragOverHandler);
|
|
||||||
input?.removeEventListener('change', handleFileSelection);
|
|
||||||
};
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
if (loading) {
|
if (loading) {
|
||||||
return <LoadingPlaceholder />;
|
return <LoadingPlaceholder />;
|
||||||
@@ -253,10 +241,7 @@ export function Backup() {
|
|||||||
secondary={t('settings.backup.action.create.label.description')}
|
secondary={t('settings.backup.action.create.label.description')}
|
||||||
/>
|
/>
|
||||||
</ListItemButton>
|
</ListItemButton>
|
||||||
<ListItemButton
|
<ListItemButton onClick={() => inputRef.current?.click()} disabled={!!backupRestoreId}>
|
||||||
onClick={() => document.getElementById('backup-file')?.click()}
|
|
||||||
disabled={!!backupRestoreId}
|
|
||||||
>
|
|
||||||
<ListItemText
|
<ListItemText
|
||||||
primary={t('settings.backup.action.restore.label.title')}
|
primary={t('settings.backup.action.restore.label.title')}
|
||||||
secondary={t('settings.backup.action.restore.label.description')}
|
secondary={t('settings.backup.action.restore.label.description')}
|
||||||
@@ -318,7 +303,7 @@ export function Backup() {
|
|||||||
/>
|
/>
|
||||||
</List>
|
</List>
|
||||||
</List>
|
</List>
|
||||||
<input type="file" id="backup-file" style={{ display: 'none' }} />
|
<input ref={mergedInputRef} type="file" style={{ display: 'none' }} />
|
||||||
<Dialog open={isInvalidBackupDialogOpen}>
|
<Dialog open={isInvalidBackupDialogOpen}>
|
||||||
<DialogTitle>{t('settings.backup.action.validate.dialog.title')}</DialogTitle>
|
<DialogTitle>{t('settings.backup.action.validate.dialog.title')}</DialogTitle>
|
||||||
<DialogContent dividers>
|
<DialogContent dividers>
|
||||||
|
|||||||
@@ -6,13 +6,14 @@
|
|||||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import React, { useState, useEffect } from 'react';
|
import React, { useState } from 'react';
|
||||||
import SearchIcon from '@mui/icons-material/Search';
|
import SearchIcon from '@mui/icons-material/Search';
|
||||||
import IconButton from '@mui/material/IconButton';
|
import IconButton from '@mui/material/IconButton';
|
||||||
import { useQueryParam, StringParam } from 'use-query-params';
|
import { useQueryParam, StringParam } from 'use-query-params';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
import { useLocation } from 'react-router-dom';
|
import { useLocation } from 'react-router-dom';
|
||||||
import { useTheme } from '@mui/material/styles';
|
import { useTheme } from '@mui/material/styles';
|
||||||
|
import { useHotkeys } from 'react-hotkeys-hook';
|
||||||
import { CustomTooltip } from '@/modules/core/components/CustomTooltip.tsx';
|
import { CustomTooltip } from '@/modules/core/components/CustomTooltip.tsx';
|
||||||
import { SearchTextField } from '@/modules/core/components/inputs/SearchTextField.tsx';
|
import { SearchTextField } from '@/modules/core/components/inputs/SearchTextField.tsx';
|
||||||
|
|
||||||
@@ -75,20 +76,13 @@ export const AppbarSearch: React.FunctionComponent<IProps> = (props) => {
|
|||||||
if (!searchString) updateSearchOpenState(false);
|
if (!searchString) updateSearchOpenState(false);
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleKeyboardEvent = (e: KeyboardEvent) => {
|
useHotkeys(
|
||||||
if (e.key === 'F3' || (e.ctrlKey && e.key === 'f')) {
|
'ctrl+f, F3',
|
||||||
e.preventDefault();
|
() => {
|
||||||
updateSearchOpenState(true);
|
updateSearchOpenState(true);
|
||||||
}
|
},
|
||||||
};
|
{ preventDefault: true },
|
||||||
|
);
|
||||||
useEffect(() => {
|
|
||||||
window.addEventListener('keydown', handleKeyboardEvent);
|
|
||||||
|
|
||||||
return () => {
|
|
||||||
window.removeEventListener('keydown', handleKeyboardEvent);
|
|
||||||
};
|
|
||||||
}, [handleKeyboardEvent]);
|
|
||||||
|
|
||||||
if (isOpen) {
|
if (isOpen) {
|
||||||
return (
|
return (
|
||||||
|
|||||||
@@ -23,10 +23,8 @@ import {
|
|||||||
MouseEvent,
|
MouseEvent,
|
||||||
ReactNode,
|
ReactNode,
|
||||||
RefAttributes,
|
RefAttributes,
|
||||||
useImperativeHandle,
|
|
||||||
useRef,
|
useRef,
|
||||||
useState,
|
useState,
|
||||||
Ref,
|
|
||||||
} from 'react';
|
} from 'react';
|
||||||
import ChevronRightIcon from '@mui/icons-material/ChevronRight';
|
import ChevronRightIcon from '@mui/icons-material/ChevronRight';
|
||||||
import ChevronLeftIcon from '@mui/icons-material/ChevronLeft';
|
import ChevronLeftIcon from '@mui/icons-material/ChevronLeft';
|
||||||
@@ -34,6 +32,7 @@ import Box from '@mui/material/Box';
|
|||||||
|
|
||||||
import { OverridableComponent } from '@mui/material/OverridableComponent';
|
import { OverridableComponent } from '@mui/material/OverridableComponent';
|
||||||
import { SvgIconTypeMap } from '@mui/material/SvgIcon';
|
import { SvgIconTypeMap } from '@mui/material/SvgIcon';
|
||||||
|
import { useMergedRef } from '@mantine/hooks';
|
||||||
import { IconMenuItem } from '@/modules/core/components/menu/IconMenuItem.tsx';
|
import { IconMenuItem } from '@/modules/core/components/menu/IconMenuItem.tsx';
|
||||||
import { getOptionForDirection } from '@/modules/theme/services/ThemeCreator.ts';
|
import { getOptionForDirection } from '@/modules/theme/services/ThemeCreator.ts';
|
||||||
import { MediaQuery } from '@/modules/core/utils/MediaQuery.tsx';
|
import { MediaQuery } from '@/modules/core/utils/MediaQuery.tsx';
|
||||||
@@ -74,10 +73,10 @@ const NestedMenuItem = forwardRef<HTMLLIElement | null, NestedMenuItemProps>((pr
|
|||||||
const { ref: containerRefProp, ...ContainerProps } = ContainerPropsProp;
|
const { ref: containerRefProp, ...ContainerProps } = ContainerPropsProp;
|
||||||
|
|
||||||
const menuItemRef = useRef<HTMLLIElement | null>(null);
|
const menuItemRef = useRef<HTMLLIElement | null>(null);
|
||||||
useImperativeHandle(ref, () => menuItemRef.current!);
|
const mergedMenuItemRef = useMergedRef(ref, menuItemRef);
|
||||||
|
|
||||||
const containerRef = useRef<HTMLElement>(null);
|
const containerRef = useRef<HTMLElement>(null);
|
||||||
useImperativeHandle(containerRefProp as Ref<HTMLElement | null>, () => containerRef.current as HTMLElement);
|
const mergedContainerRef = useMergedRef(containerRefProp, containerRef);
|
||||||
|
|
||||||
const menuContainerRef = useRef<HTMLDivElement | null>(null);
|
const menuContainerRef = useRef<HTMLDivElement | null>(null);
|
||||||
|
|
||||||
@@ -184,7 +183,7 @@ const NestedMenuItem = forwardRef<HTMLLIElement | null, NestedMenuItemProps>((pr
|
|||||||
return (
|
return (
|
||||||
<Box
|
<Box
|
||||||
{...ContainerProps}
|
{...ContainerProps}
|
||||||
ref={containerRef}
|
ref={mergedContainerRef}
|
||||||
onFocus={handleFocus}
|
onFocus={handleFocus}
|
||||||
onClick={handleClick}
|
onClick={handleClick}
|
||||||
tabIndex={tabIndex}
|
tabIndex={tabIndex}
|
||||||
@@ -195,7 +194,7 @@ const NestedMenuItem = forwardRef<HTMLLIElement | null, NestedMenuItemProps>((pr
|
|||||||
<IconMenuItem
|
<IconMenuItem
|
||||||
MenuItemProps={MenuItemProps}
|
MenuItemProps={MenuItemProps}
|
||||||
className={className}
|
className={className}
|
||||||
ref={menuItemRef}
|
ref={mergedMenuItemRef}
|
||||||
LeftIcon={LeftIcon}
|
LeftIcon={LeftIcon}
|
||||||
RightIcon={RightIcon}
|
RightIcon={RightIcon}
|
||||||
label={label}
|
label={label}
|
||||||
|
|||||||
@@ -10,12 +10,13 @@ import PauseIcon from '@mui/icons-material/Pause';
|
|||||||
import PlayArrowIcon from '@mui/icons-material/PlayArrow';
|
import PlayArrowIcon from '@mui/icons-material/PlayArrow';
|
||||||
import Box from '@mui/material/Box';
|
import Box from '@mui/material/Box';
|
||||||
import IconButton from '@mui/material/IconButton';
|
import IconButton from '@mui/material/IconButton';
|
||||||
import React, { useEffect, useLayoutEffect, useMemo, useState } from 'react';
|
import React, { useLayoutEffect, useMemo, useState } from 'react';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
import DeleteSweepIcon from '@mui/icons-material/DeleteSweep';
|
import DeleteSweepIcon from '@mui/icons-material/DeleteSweep';
|
||||||
import { Virtuoso } from 'react-virtuoso';
|
import { Virtuoso } from 'react-virtuoso';
|
||||||
import { closestCenter, DndContext, DragEndEvent } from '@dnd-kit/core';
|
import { closestCenter, DndContext, DragEndEvent } from '@dnd-kit/core';
|
||||||
import { SortableContext, verticalListSortingStrategy } from '@dnd-kit/sortable';
|
import { SortableContext, verticalListSortingStrategy } from '@dnd-kit/sortable';
|
||||||
|
import { useWindowEvent } from '@mantine/hooks';
|
||||||
import { CustomTooltip } from '@/modules/core/components/CustomTooltip.tsx';
|
import { CustomTooltip } from '@/modules/core/components/CustomTooltip.tsx';
|
||||||
import { requestManager } from '@/lib/requests/RequestManager.ts';
|
import { requestManager } from '@/lib/requests/RequestManager.ts';
|
||||||
import { makeToast } from '@/modules/core/utils/Toast.ts';
|
import { makeToast } from '@/modules/core/utils/Toast.ts';
|
||||||
@@ -122,22 +123,16 @@ export const DownloadQueue: React.FC = () => {
|
|||||||
};
|
};
|
||||||
}, [t, status, isQueueEmpty]);
|
}, [t, status, isQueueEmpty]);
|
||||||
|
|
||||||
useEffect(() => {
|
// Virtuoso's resize observer can throw this error,
|
||||||
const ignoreError = (e: WindowEventMap['error']) => {
|
// which is caught by DnD and aborts dragging.
|
||||||
if (
|
useWindowEvent('error', (e) => {
|
||||||
e.message === 'ResizeObserver loop completed with undelivered notifications.' ||
|
if (
|
||||||
e.message === 'ResizeObserver loop limit exceeded'
|
e.message === 'ResizeObserver loop completed with undelivered notifications.' ||
|
||||||
) {
|
e.message === 'ResizeObserver loop limit exceeded'
|
||||||
e.stopImmediatePropagation();
|
) {
|
||||||
}
|
e.stopImmediatePropagation();
|
||||||
};
|
}
|
||||||
|
});
|
||||||
// Virtuoso's resize observer can throw this error,
|
|
||||||
// which is caught by DnD and aborts dragging.
|
|
||||||
window.addEventListener('error', ignoreError);
|
|
||||||
|
|
||||||
return () => window.removeEventListener('error', ignoreError);
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
if (isLoading) {
|
if (isLoading) {
|
||||||
return <LoadingPlaceholder />;
|
return <LoadingPlaceholder />;
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ import Stack from '@mui/material/Stack';
|
|||||||
import Typography from '@mui/material/Typography';
|
import Typography from '@mui/material/Typography';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
import { Link, useLocation, useNavigate } from 'react-router-dom';
|
import { Link, useLocation, useNavigate } from 'react-router-dom';
|
||||||
|
import { useWindowEvent } from '@mantine/hooks';
|
||||||
import { CustomTooltip } from '@/modules/core/components/CustomTooltip.tsx';
|
import { CustomTooltip } from '@/modules/core/components/CustomTooltip.tsx';
|
||||||
import { requestManager } from '@/lib/requests/RequestManager.ts';
|
import { requestManager } from '@/lib/requests/RequestManager.ts';
|
||||||
import { AppbarSearch } from '@/modules/core/components/AppbarSearch.tsx';
|
import { AppbarSearch } from '@/modules/core/components/AppbarSearch.tsx';
|
||||||
@@ -242,25 +243,14 @@ export function Extensions({ tabsMenuHeight }: { tabsMenuHeight: number }) {
|
|||||||
};
|
};
|
||||||
}, [t, shownLangs, allLangs]);
|
}, [t, shownLangs, allLangs]);
|
||||||
|
|
||||||
useEffect(() => {
|
useWindowEvent('drop', async (e) => {
|
||||||
const dropHandler = async (e: Event) => {
|
e.preventDefault();
|
||||||
e.preventDefault();
|
const files = await fromEvent(e);
|
||||||
const files = await fromEvent(e);
|
submitExternalExtension(files[0] as File);
|
||||||
submitExternalExtension(files[0] as File);
|
});
|
||||||
};
|
useWindowEvent('dragover', (e) => {
|
||||||
|
e.preventDefault();
|
||||||
const dragOverHandler = (e: Event) => {
|
});
|
||||||
e.preventDefault();
|
|
||||||
};
|
|
||||||
|
|
||||||
document.addEventListener('drop', dropHandler);
|
|
||||||
document.addEventListener('dragover', dragOverHandler);
|
|
||||||
|
|
||||||
return () => {
|
|
||||||
document.removeEventListener('drop', dropHandler);
|
|
||||||
document.removeEventListener('dragover', dragOverHandler);
|
|
||||||
};
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
if (isLoading) {
|
if (isLoading) {
|
||||||
return <LoadingPlaceholder />;
|
return <LoadingPlaceholder />;
|
||||||
|
|||||||
@@ -12,7 +12,6 @@ import {
|
|||||||
memo,
|
memo,
|
||||||
useCallback,
|
useCallback,
|
||||||
useEffect,
|
useEffect,
|
||||||
useImperativeHandle,
|
|
||||||
useLayoutEffect,
|
useLayoutEffect,
|
||||||
useMemo,
|
useMemo,
|
||||||
useRef,
|
useRef,
|
||||||
@@ -21,6 +20,7 @@ import {
|
|||||||
import Stack from '@mui/material/Stack';
|
import Stack from '@mui/material/Stack';
|
||||||
import { useTheme } from '@mui/material/styles';
|
import { useTheme } from '@mui/material/styles';
|
||||||
import { useLocation } from 'react-router-dom';
|
import { useLocation } from 'react-router-dom';
|
||||||
|
import { useMergedRef } from '@mantine/hooks';
|
||||||
import { ReaderService } from '@/modules/reader/services/ReaderService.ts';
|
import { ReaderService } from '@/modules/reader/services/ReaderService.ts';
|
||||||
import {
|
import {
|
||||||
IReaderSettings,
|
IReaderSettings,
|
||||||
@@ -168,7 +168,7 @@ const BaseReaderViewer = forwardRef(
|
|||||||
};
|
};
|
||||||
|
|
||||||
const scrollElementRef = useRef<HTMLDivElement | null>(null);
|
const scrollElementRef = useRef<HTMLDivElement | null>(null);
|
||||||
useImperativeHandle(ref, () => scrollElementRef.current!);
|
const mergedRef = useMergedRef(ref, scrollElementRef);
|
||||||
|
|
||||||
const isContinuousVerticalReadingModeActive = isContinuousVerticalReadingMode(readingMode);
|
const isContinuousVerticalReadingModeActive = isContinuousVerticalReadingMode(readingMode);
|
||||||
const isContinuousReadingModeActive = isContinuousReadingMode(readingMode);
|
const isContinuousReadingModeActive = isContinuousReadingMode(readingMode);
|
||||||
@@ -310,7 +310,7 @@ const BaseReaderViewer = forwardRef(
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<Stack
|
<Stack
|
||||||
ref={scrollElementRef}
|
ref={mergedRef}
|
||||||
sx={{
|
sx={{
|
||||||
width: '100%',
|
width: '100%',
|
||||||
height: '100%',
|
height: '100%',
|
||||||
|
|||||||
@@ -6,7 +6,8 @@
|
|||||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { RefObject, useEffect, useLayoutEffect, useRef } from 'react';
|
import { RefObject, useCallback, useEffect, useLayoutEffect, useRef } from 'react';
|
||||||
|
import { useWindowEvent } from '@mantine/hooks';
|
||||||
import {
|
import {
|
||||||
ReaderPageScaleMode,
|
ReaderPageScaleMode,
|
||||||
ReaderStateChapters,
|
ReaderStateChapters,
|
||||||
@@ -64,21 +65,18 @@ const usePreserveOnWindowResize = (
|
|||||||
) => {
|
) => {
|
||||||
const previousDimensionsRef = useRef({ width: window.innerWidth, height: window.innerHeight });
|
const previousDimensionsRef = useRef({ width: window.innerWidth, height: window.innerHeight });
|
||||||
|
|
||||||
useEffect(() => {
|
const handleResize = useCallback(() => {
|
||||||
const handleResize = () => {
|
const { width, height } = previousDimensionsRef.current;
|
||||||
const { width, height } = previousDimensionsRef.current;
|
previousDimensionsRef.current = { width: window.innerWidth, height: window.innerHeight };
|
||||||
previousDimensionsRef.current = { width: window.innerWidth, height: window.innerHeight };
|
|
||||||
|
|
||||||
if (!shouldPreserveOnResizeChange(readingMode, pageScaleMode, width, height)) {
|
if (!shouldPreserveOnResizeChange(readingMode, pageScaleMode, width, height)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
setPageToScrollToIndex(pageIndex);
|
setPageToScrollToIndex(pageIndex);
|
||||||
};
|
|
||||||
|
|
||||||
window.addEventListener('resize', handleResize);
|
|
||||||
return () => window.removeEventListener('resize', handleResize);
|
|
||||||
}, [readingMode, pageScaleMode, pageIndex]);
|
}, [readingMode, pageScaleMode, pageIndex]);
|
||||||
|
|
||||||
|
useWindowEvent('resize', handleResize);
|
||||||
};
|
};
|
||||||
|
|
||||||
interface ScrollPreservationInfo {
|
interface ScrollPreservationInfo {
|
||||||
|
|||||||
@@ -2564,6 +2564,11 @@
|
|||||||
hoist-non-react-statics "^3.3.1"
|
hoist-non-react-statics "^3.3.1"
|
||||||
react-is "^16.12.0"
|
react-is "^16.12.0"
|
||||||
|
|
||||||
|
"@mantine/hooks@^7.17.5":
|
||||||
|
version "7.17.5"
|
||||||
|
resolved "https://registry.yarnpkg.com/@mantine/hooks/-/hooks-7.17.5.tgz#ae3c270161c4a156e3ca8dff1c7a73c4a3710c48"
|
||||||
|
integrity sha512-Q/3AHI1fjl+W7xQ3jEoMmSoTxLqxMI2gPfxIjd73OPmRpPenYWR1zk/diirXXm2t7JOrAbmpA3/O1gzmgqzc/Q==
|
||||||
|
|
||||||
"@mui/core-downloads-tracker@^7.0.2":
|
"@mui/core-downloads-tracker@^7.0.2":
|
||||||
version "7.0.2"
|
version "7.0.2"
|
||||||
resolved "https://registry.yarnpkg.com/@mui/core-downloads-tracker/-/core-downloads-tracker-7.0.2.tgz#2e6dcaf5027a3957d37797b8dce5c15c78fd4b82"
|
resolved "https://registry.yarnpkg.com/@mui/core-downloads-tracker/-/core-downloads-tracker-7.0.2.tgz#2e6dcaf5027a3957d37797b8dce5c15c78fd4b82"
|
||||||
|
|||||||
Reference in New Issue
Block a user