@@ -371,6 +371,9 @@ interface BreadcrumbLocationPopoverProps {
371371 veilBoundaryRef : React . RefObject < HTMLDivElement | null >
372372}
373373
374+ /** How long the reopen latch is held after a click-to-navigate, covering the route swap. */
375+ const NAVIGATE_LATCH_MS = 250
376+
374377function BreadcrumbLocationPopover ( {
375378 icon : Icon ,
376379 breadcrumbs,
@@ -386,11 +389,14 @@ function BreadcrumbLocationPopover({
386389 * veil and popover content would snap away instead of fading — a visible
387390 * flash. {@link navigateAndClose} closes the popover before running the
388391 * crumb's handler and latches this so the pointer still resting on the
389- * trigger can't re-fire `openPopover` mid-navigation. It is cleared on the
390- * next pointer/focus exit so the popover keeps working when the handler does
391- * not actually navigate (e.g. an unsaved-changes guard that opens a modal).
392+ * trigger can't re-fire `openPopover` mid-navigation. The latch is held by a
393+ * short timer (not cleared on the next pointer exit, which fires immediately
394+ * and would let the popover flash back open before the route swaps); the
395+ * timer releases it so the popover keeps working when the handler does not
396+ * actually navigate (e.g. an unsaved-changes guard that opens a modal).
392397 */
393398 const navigatingRef = useRef ( false )
399+ const navigateLatchRef = useRef < ReturnType < typeof setTimeout > | null > ( null )
394400 const rootBreadcrumb = breadcrumbs [ 0 ]
395401
396402 const clearCloseTimeout = ( ) => {
@@ -407,7 +413,6 @@ function BreadcrumbLocationPopover({
407413 }
408414
409415 const scheduleClose = ( ) => {
410- navigatingRef . current = false
411416 clearCloseTimeout ( )
412417 closeTimeoutRef . current = setTimeout ( ( ) => {
413418 setOpen ( false )
@@ -421,11 +426,17 @@ function BreadcrumbLocationPopover({
421426 clearCloseTimeout ( )
422427 setOpen ( false )
423428 onClick ( )
429+ if ( navigateLatchRef . current ) clearTimeout ( navigateLatchRef . current )
430+ navigateLatchRef . current = setTimeout ( ( ) => {
431+ navigatingRef . current = false
432+ navigateLatchRef . current = null
433+ } , NAVIGATE_LATCH_MS )
424434 }
425435
426436 useEffect ( ( ) => {
427437 return ( ) => {
428438 if ( closeTimeoutRef . current ) clearTimeout ( closeTimeoutRef . current )
439+ if ( navigateLatchRef . current ) clearTimeout ( navigateLatchRef . current )
429440 }
430441 } , [ ] )
431442
0 commit comments