From c86f1d74e1801bbc11f232afbbc8b2a9cf1b89b4 Mon Sep 17 00:00:00 2001 From: Matt Brophy Date: Wed, 18 Jan 2023 11:27:08 -0500 Subject: [PATCH 1/4] Add unstable_usePrompt --- packages/react-router-dom/index.tsx | 36 +++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/packages/react-router-dom/index.tsx b/packages/react-router-dom/index.tsx index e64685216d..65d30919c2 100644 --- a/packages/react-router-dom/index.tsx +++ b/packages/react-router-dom/index.tsx @@ -18,6 +18,7 @@ import { useNavigate, useNavigation, useResolvedPath, + unstable_useBlocker as useBlocker, UNSAFE_DataRouterContext as DataRouterContext, UNSAFE_DataRouterStateContext as DataRouterStateContext, UNSAFE_NavigationContext as NavigationContext, @@ -1210,6 +1211,41 @@ export function useBeforeUnload( }; }, [callback, capture]); } + +/** + * Wrapper around useBlocker to show a window.confirm prompt to users instead + * of building a custom UI with useBlocker. + * + * Warning: This has *a lot of rough edges* and behaves very differently (and + * very incorrectly in some cases) across browsers if user click addition + * back/forward navigations while the confirm is open. Use at your own risk. + */ +function usePrompt({ when, message }: { when: boolean; message: string }) { + let blocker = useBlocker(when); + + React.useEffect(() => { + if (blocker.state === "blocked" && !when) { + blocker.reset(); + } + }, [blocker, when]); + + React.useEffect(() => { + if (blocker.state === "blocked") { + console.log("calling window.confirm"); + let proceed = window.confirm(message); + if (proceed) { + console.log("calling setTimeout before proceed"); + setTimeout(blocker.proceed, 0); + } else { + console.log("resetting"); + blocker.reset(); + } + } + }, [blocker, message]); +} + +export { usePrompt as unstable_usePrompt }; + //#endregion //////////////////////////////////////////////////////////////////////////////// From 864ca1f95a331f93e843edd45af9cf7db3b4a6fd Mon Sep 17 00:00:00 2001 From: Matt Brophy Date: Wed, 18 Jan 2023 11:33:00 -0500 Subject: [PATCH 2/4] add changeset --- .changeset/spicy-nails-compete.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/spicy-nails-compete.md diff --git a/.changeset/spicy-nails-compete.md b/.changeset/spicy-nails-compete.md new file mode 100644 index 0000000000..6ce558c255 --- /dev/null +++ b/.changeset/spicy-nails-compete.md @@ -0,0 +1,5 @@ +--- +"react-router-dom": patch +--- + +Add `unstable_usePrompt` From 807964aa1204fe3ce4e9b89f8295521e03fd277e Mon Sep 17 00:00:00 2001 From: Matt Brophy Date: Wed, 18 Jan 2023 11:33:29 -0500 Subject: [PATCH 3/4] Remove consoles --- packages/react-router-dom/index.tsx | 3 --- 1 file changed, 3 deletions(-) diff --git a/packages/react-router-dom/index.tsx b/packages/react-router-dom/index.tsx index 65d30919c2..520905d4d7 100644 --- a/packages/react-router-dom/index.tsx +++ b/packages/react-router-dom/index.tsx @@ -1231,13 +1231,10 @@ function usePrompt({ when, message }: { when: boolean; message: string }) { React.useEffect(() => { if (blocker.state === "blocked") { - console.log("calling window.confirm"); let proceed = window.confirm(message); if (proceed) { - console.log("calling setTimeout before proceed"); setTimeout(blocker.proceed, 0); } else { - console.log("resetting"); blocker.reset(); } } From 9ffa1090d9cdc3b8975e71431c7b25cff3b34eba Mon Sep 17 00:00:00 2001 From: Matt Brophy Date: Wed, 18 Jan 2023 11:34:53 -0500 Subject: [PATCH 4/4] bump bundle --- package.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index 3cb029f761..fdb6937435 100644 --- a/package.json +++ b/package.json @@ -118,10 +118,10 @@ "none": "15 kB" }, "packages/react-router-dom/dist/react-router-dom.production.min.js": { - "none": "11 kB" + "none": "11.5 kB" }, "packages/react-router-dom/dist/umd/react-router-dom.production.min.js": { - "none": "16.5 kB" + "none": "17 kB" } } }