-
Notifications
You must be signed in to change notification settings - Fork 3.3k
feat(ui): enhance LeaveWithoutSaving component with popstate navigation handling #15074
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -43,12 +43,14 @@ export const LeaveWithoutSaving: React.FC<LeaveWithoutSavingProps> = ({ | |||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
| const handleAccept = useCallback(() => { | ||||||||||||||||||||||||||||||
| closeModal(modalSlug) | ||||||||||||||||||||||||||||||
| setHasAccepted(false) | ||||||||||||||||||||||||||||||
| }, [closeModal, modalSlug]) | ||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
| usePreventLeave({ hasAccepted, onAccept: handleAccept, onPrevent: handlePrevent, prevent }) | ||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
| const onCancel: OnCancel = useCallback(() => { | ||||||||||||||||||||||||||||||
| closeModal(modalSlug) | ||||||||||||||||||||||||||||||
| setHasAccepted(false) | ||||||||||||||||||||||||||||||
|
Comment on lines
+46
to
+53
|
||||||||||||||||||||||||||||||
| setHasAccepted(false) | |
| }, [closeModal, modalSlug]) | |
| usePreventLeave({ hasAccepted, onAccept: handleAccept, onPrevent: handlePrevent, prevent }) | |
| const onCancel: OnCancel = useCallback(() => { | |
| closeModal(modalSlug) | |
| setHasAccepted(false) | |
| }, [closeModal, modalSlug]) | |
| usePreventLeave({ hasAccepted, onAccept: handleAccept, onPrevent: handlePrevent, prevent }) | |
| const onCancel: OnCancel = useCallback(() => { | |
| closeModal(modalSlug) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same as above.
| Original file line number | Diff line number | Diff line change | ||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -78,6 +78,8 @@ export const usePreventLeave = ({ | |||||||||||
|
|
||||||||||||
| const router = useRouter() | ||||||||||||
| const cancelledURL = useRef<string>('') | ||||||||||||
| // Track if we're handling a popstate (back/forward) navigation | ||||||||||||
| const isPopstateNavigation = useRef<boolean>(false) | ||||||||||||
|
|
||||||||||||
| // check when page is about to be changed | ||||||||||||
| useEffect(() => { | ||||||||||||
|
|
@@ -128,6 +130,7 @@ export const usePreventLeave = ({ | |||||||||||
| if (isPageLeaving && prevent && (!onPrevent ? !window.confirm(message) : true)) { | ||||||||||||
| // Keep a reference of the href | ||||||||||||
| cancelledURL.current = newUrl | ||||||||||||
| isPopstateNavigation.current = false | ||||||||||||
|
|
||||||||||||
| // Cancel the route change | ||||||||||||
| event.preventDefault() | ||||||||||||
|
|
@@ -153,14 +156,63 @@ export const usePreventLeave = ({ | |||||||||||
| document.removeEventListener('click', handleClick, true) | ||||||||||||
| } | ||||||||||||
| }, [onPrevent, prevent, message]) | ||||||||||||
| // Handle browser back/forward button navigation (popstate events) | ||||||||||||
| useEffect(() => { | ||||||||||||
| if (!prevent) return | ||||||||||||
|
|
||||||||||||
| // This prevents creating a fake back button when user landed directly on this page | ||||||||||||
| const hasBackHistory = window.history.length > 1 | ||||||||||||
|
|
||||||||||||
| if (!hasBackHistory) return | ||||||||||||
|
|
||||||||||||
|
Comment on lines
+163
to
+167
|
||||||||||||
| // This prevents creating a fake back button when user landed directly on this page | |
| const hasBackHistory = window.history.length > 1 | |
| if (!hasBackHistory) return | |
| // Set up a fake history entry so we can intercept back/forward navigation |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you confirm @sohamingle?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Resetting hasAccepted to false in both handleAccept and onCancel prevents the usePreventLeave hook from completing its navigation logic. The hasAccepted state is used in the useEffect at line 200-217 to trigger navigation, and resetting it here will cause that effect to not run or to run with false, skipping the navigation.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Interesting, can you confirm @sohamingle?