0
Fork 0
mirror of https://github.com/logto-io/logto.git synced 2024-12-16 20:26:19 -05:00

chore(deps): update dependency react-router-dom to v6.10.0 (#3238)

* chore(deps): update dependency react-router-dom to v6.10.0

* fix: lockfile

* fix: react router

* chore: add annotations about the type definition file

* fix: bump version number for ui package

---------

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: Charles Zhao <charleszhao@silverhand.io>
This commit is contained in:
renovate[bot] 2023-04-19 18:05:57 +08:00 committed by GitHub
parent 4b6ad4c8c5
commit e97fe2e1f3
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 96 additions and 124 deletions

View file

@ -93,7 +93,7 @@
"react-markdown": "^8.0.0", "react-markdown": "^8.0.0",
"react-modal": "^3.15.1", "react-modal": "^3.15.1",
"react-paginate": "^8.1.3", "react-paginate": "^8.1.3",
"react-router-dom": "6.3.0", "react-router-dom": "^6.10.0",
"react-syntax-highlighter": "^15.5.0", "react-syntax-highlighter": "^15.5.0",
"react-timer-hook": "^3.0.5", "react-timer-hook": "^3.0.5",
"recharts": "^2.1.13", "recharts": "^2.1.13",

View file

@ -1,97 +1,42 @@
import type { Blocker, Transition } from 'history'; import { useEffect } from 'react';
import { useCallback, useContext, useLayoutEffect, useState } from 'react';
import { useTranslation } from 'react-i18next'; import { useTranslation } from 'react-i18next';
import type { Navigator } from 'react-router-dom'; import { unstable_useBlocker as useBlocker, useLocation } from 'react-router-dom';
import { UNSAFE_NavigationContext } from 'react-router-dom';
import ConfirmModal from '../ConfirmModal'; import ConfirmModal from '../ConfirmModal';
/**
* The `usePrompt` and `useBlock` hooks are removed from react-router v6, as the developers think
* they are not ready to be shipped in v6. Reference: https://github.com/remix-run/react-router/issues/8139
* Therefore we have to implement our own workaround to provide the same functionality, through `UNSAFE_NavigationContext`.
*/
type BlockFunction = (blocker: Blocker) => () => void;
type BlockerNavigator = Navigator & {
location: Location;
block: BlockFunction;
};
type Props = { type Props = {
hasUnsavedChanges: boolean; hasUnsavedChanges: boolean;
parentPath?: string; parentPath?: string;
}; };
function UnsavedChangesAlertModal({ hasUnsavedChanges, parentPath }: Props) { function UnsavedChangesAlertModal({ hasUnsavedChanges, parentPath }: Props) {
const { navigator } = useContext(UNSAFE_NavigationContext);
/**
* Props `block` and `location` are removed from `Navigator` type in react-router, for the same reason as above.
* So we have to define our own type `BlockerNavigator` to acquire these props that actually exist in `navigator` object.
*/
// eslint-disable-next-line no-restricted-syntax
const { block, location } = navigator as BlockerNavigator;
const [displayAlert, setDisplayAlert] = useState(false);
const [transition, setTransition] = useState<Transition>();
const { t } = useTranslation(undefined, { keyPrefix: 'admin_console' }); const { t } = useTranslation(undefined, { keyPrefix: 'admin_console' });
const { pathname } = useLocation();
const blocker = useBlocker(hasUnsavedChanges);
useLayoutEffect(() => { // Reset the blocker if the conditions are met.
if (!hasUnsavedChanges) { useEffect(() => {
if (blocker.state !== 'blocked') {
return; return;
} }
const { pathname } = location; const targetPathname = blocker.location.pathname;
if (!hasUnsavedChanges || targetPathname === pathname) {
const unblock = block((transition) => { blocker.reset();
const {
location: { pathname: targetPathname },
} = transition;
// Note: We don't want to show the alert if the user is navigating to the same page.
if (targetPathname === pathname) {
return; return;
} }
if (parentPath && targetPathname.startsWith(parentPath)) { if (parentPath && targetPathname.startsWith(parentPath)) {
unblock(); blocker.proceed();
transition.retry();
return;
} }
}, [blocker, pathname, hasUnsavedChanges, parentPath]);
setDisplayAlert(true);
setTransition({
...transition,
retry() {
unblock();
transition.retry();
},
});
});
return unblock;
}, [navigator, hasUnsavedChanges, location, block, parentPath]);
const leavePage = useCallback(() => {
transition?.retry();
setDisplayAlert(false);
}, [transition]);
const stayOnPage = useCallback(() => {
setDisplayAlert(false);
}, [setDisplayAlert]);
return ( return (
<ConfirmModal <ConfirmModal
isOpen={displayAlert} isOpen={blocker.state === 'blocked'}
confirmButtonText="general.leave_page" confirmButtonText="general.leave_page"
cancelButtonText="general.stay_on_page" cancelButtonText="general.stay_on_page"
onCancel={stayOnPage} onCancel={blocker.reset}
onConfirm={leavePage} onConfirm={blocker.proceed}
> >
{t('general.unsaved_changes_warning')} {t('general.unsaved_changes_warning')}
</ConfirmModal> </ConfirmModal>

View file

@ -0,0 +1,16 @@
/**
* This type definition file is a workaround for the fact that react-router-dom
* declares location status type as `any` instead of `unknown`, which ends up
* causing issues with strict type narrowing in TypeScript.
*
* Reference: https://github.com/remix-run/react-router/issues/10241
*/
// eslint-disable-next-line import/no-unassigned-import
import 'react-router-dom';
declare module 'react-router-dom' {
import { type Location } from 'react-router-dom';
function useLocation(): Omit<Location, 'state'> & { state: unknown };
}

View file

@ -1,4 +1,9 @@
import { BrowserRouter, Route, Routes } from 'react-router-dom'; import {
Route,
RouterProvider,
createBrowserRouter,
createRoutesFromElements,
} from 'react-router-dom';
import { SWRConfig } from 'swr'; import { SWRConfig } from 'swr';
import Toast from '@/components/Toast'; import Toast from '@/components/Toast';
@ -14,23 +19,27 @@ import HandleSocialCallback from '../Profile/containers/HandleSocialCallback';
function Main() { function Main() {
const swrOptions = useSwrOptions(); const swrOptions = useSwrOptions();
const router = createBrowserRouter(
return ( createRoutesFromElements(
<BrowserRouter basename={getBasename()}> <>
<SWRConfig value={swrOptions}>
<AppBoundary>
<Toast />
<Routes>
<Route path="callback" element={<Callback />} /> <Route path="callback" element={<Callback />} />
<Route path="welcome" element={<Welcome />} /> <Route path="welcome" element={<Welcome />} />
<Route path="handle-social" element={<HandleSocialCallback />} /> <Route path="handle-social" element={<HandleSocialCallback />} />
<Route element={<AppContent />}> <Route element={<AppContent />}>
<Route path="/*" element={<ConsoleContent />} /> <Route path="/*" element={<ConsoleContent />} />
</Route> </Route>
</Routes> </>
),
{ basename: getBasename() }
);
return (
<SWRConfig value={swrOptions}>
<AppBoundary>
<Toast />
<RouterProvider router={router} />
</AppBoundary> </AppBoundary>
</SWRConfig> </SWRConfig>
</BrowserRouter>
); );
} }

View file

@ -77,7 +77,7 @@
"react-hook-form": "^7.34.0", "react-hook-form": "^7.34.0",
"react-i18next": "^11.18.3", "react-i18next": "^11.18.3",
"react-modal": "^3.15.1", "react-modal": "^3.15.1",
"react-router-dom": "^6.2.2", "react-router-dom": "^6.10.0",
"react-string-replace": "^1.0.0", "react-string-replace": "^1.0.0",
"react-timer-hook": "^3.0.5", "react-timer-hook": "^3.0.5",
"react-top-loading-bar": "^2.3.1", "react-top-loading-bar": "^2.3.1",

View file

@ -0,0 +1,16 @@
/**
* This type definition file is a workaround for the fact that react-router-dom
* declares location status type as `any` instead of `unknown`, which ends up
* causing issues with strict type narrowing in TypeScript.
*
* Reference: https://github.com/remix-run/react-router/issues/10241
*/
// eslint-disable-next-line import/no-unassigned-import
import 'react-router-dom';
declare module 'react-router-dom' {
import { type Location } from 'react-router-dom';
function useLocation(): Omit<Location, 'state'> & { state: unknown };
}

View file

@ -2970,8 +2970,8 @@ importers:
specifier: ^8.1.3 specifier: ^8.1.3
version: 8.1.3(react@18.2.0) version: 8.1.3(react@18.2.0)
react-router-dom: react-router-dom:
specifier: 6.3.0 specifier: ^6.10.0
version: 6.3.0(react-dom@18.2.0)(react@18.2.0) version: 6.10.0(react-dom@18.2.0)(react@18.2.0)
react-syntax-highlighter: react-syntax-highlighter:
specifier: ^15.5.0 specifier: ^15.5.0
version: 15.5.0(react@18.2.0) version: 15.5.0(react@18.2.0)
@ -3952,8 +3952,8 @@ importers:
specifier: ^3.15.1 specifier: ^3.15.1
version: 3.15.1(react-dom@18.2.0)(react@18.2.0) version: 3.15.1(react-dom@18.2.0)(react@18.2.0)
react-router-dom: react-router-dom:
specifier: ^6.2.2 specifier: ^6.10.0
version: 6.2.2(react-dom@18.2.0)(react@18.2.0) version: 6.10.0(react-dom@18.2.0)(react@18.2.0)
react-string-replace: react-string-replace:
specifier: ^1.0.0 specifier: ^1.0.0
version: 1.0.0 version: 1.0.0
@ -7464,6 +7464,11 @@ packages:
'@redis/client': 1.5.6 '@redis/client': 1.5.6
dev: false dev: false
/@remix-run/router@1.5.0:
resolution: {integrity: sha512-bkUDCp8o1MvFO+qxkODcbhSqRa6P2GXgrGZVpt0dCXNW2HCSCqYI0ZoAqEOSAjRWmmlKcYgFvN4B4S+zo/f8kg==}
engines: {node: '>=14'}
dev: true
/@rollup/plugin-commonjs@24.0.0(rollup@3.8.0): /@rollup/plugin-commonjs@24.0.0(rollup@3.8.0):
resolution: {integrity: sha512-0w0wyykzdyRRPHOb0cQt14mIBLujfAv6GgP6g8nvg/iBxEm112t3YPPq+Buqe2+imvElTka+bjNlJ/gB56TD8g==} resolution: {integrity: sha512-0w0wyykzdyRRPHOb0cQt14mIBLujfAv6GgP6g8nvg/iBxEm112t3YPPq+Buqe2+imvElTka+bjNlJ/gB56TD8g==}
engines: {node: '>=14.0.0'} engines: {node: '>=14.0.0'}
@ -16577,45 +16582,26 @@ packages:
react-dom: 18.2.0(react@18.2.0) react-dom: 18.2.0(react@18.2.0)
dev: true dev: true
/react-router-dom@6.2.2(react-dom@18.2.0)(react@18.2.0): /react-router-dom@6.10.0(react-dom@18.2.0)(react@18.2.0):
resolution: {integrity: sha512-AtYEsAST7bDD4dLSQHDnk/qxWLJdad5t1HFa1qJyUrCeGgEuCSw0VB/27ARbF9Fi/W5598ujvJOm3ujUCVzuYQ==} resolution: {integrity: sha512-E5dfxRPuXKJqzwSe/qGcqdwa18QiWC6f3H3cWXM24qj4N0/beCIf/CWTipop2xm7mR0RCS99NnaqPNjHtrAzCg==}
engines: {node: '>=14'}
peerDependencies: peerDependencies:
react: '>=16.8 || ^18.0.0' react: '>=16.8 || ^18.0.0'
react-dom: '>=16.8' react-dom: '>=16.8'
dependencies: dependencies:
history: 5.3.0 '@remix-run/router': 1.5.0
react: 18.2.0 react: 18.2.0
react-dom: 18.2.0(react@18.2.0) react-dom: 18.2.0(react@18.2.0)
react-router: 6.2.2(react@18.2.0) react-router: 6.10.0(react@18.2.0)
dev: true dev: true
/react-router-dom@6.3.0(react-dom@18.2.0)(react@18.2.0): /react-router@6.10.0(react@18.2.0):
resolution: {integrity: sha512-uaJj7LKytRxZNQV8+RbzJWnJ8K2nPsOOEuX7aQstlMZKQT0164C+X2w6bnkqU3sjtLvpd5ojrezAyfZ1+0sStw==} resolution: {integrity: sha512-Nrg0BWpQqrC3ZFFkyewrflCud9dio9ME3ojHCF/WLsprJVzkq3q3UeEhMCAW1dobjeGbWgjNn/PVF6m46ANxXQ==}
peerDependencies: engines: {node: '>=14'}
react: '>=16.8 || ^18.0.0'
react-dom: '>=16.8'
dependencies:
history: 5.3.0
react: 18.2.0
react-dom: 18.2.0(react@18.2.0)
react-router: 6.3.0(react@18.2.0)
dev: true
/react-router@6.2.2(react@18.2.0):
resolution: {integrity: sha512-/MbxyLzd7Q7amp4gDOGaYvXwhEojkJD5BtExkuKmj39VEE0m3l/zipf6h2WIB2jyAO0lI6NGETh4RDcktRm4AQ==}
peerDependencies: peerDependencies:
react: '>=16.8 || ^18.0.0' react: '>=16.8 || ^18.0.0'
dependencies: dependencies:
history: 5.3.0 '@remix-run/router': 1.5.0
react: 18.2.0
dev: true
/react-router@6.3.0(react@18.2.0):
resolution: {integrity: sha512-7Wh1DzVQ+tlFjkeo+ujvjSqSJmkt1+8JO+T5xklPlgrh70y7ogx75ODRW0ThWhY7S+6yEDks8TYrtQe/aoboBQ==}
peerDependencies:
react: '>=16.8 || ^18.0.0'
dependencies:
history: 5.3.0
react: 18.2.0 react: 18.2.0
dev: true dev: true