Skip to content

Commit 1b80c5a

Browse files
ESC key resets map zoom on /map and /communities (#477)
Pressing Escape now does the same thing as the reset-view button on both maps. Ignored while typing in a form field. Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
1 parent d493440 commit 1b80c5a

2 files changed

Lines changed: 50 additions & 11 deletions

File tree

src/app/communities/CommunitiesMap.tsx

Lines changed: 29 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,17 @@ export default function CommunitiesMap({ communities }: CommunitiesMapProps) {
107107
const resizeObserver = new ResizeObserver(() => map.resize())
108108
resizeObserver.observe(mapContainer)
109109

110+
const resetMapView = () => {
111+
map.flyTo({
112+
center: initialCenter,
113+
zoom: initialZoom,
114+
bearing: 0,
115+
pitch: 0,
116+
duration: 500,
117+
essential: true,
118+
})
119+
}
120+
110121
// Repurpose Mapbox's compass button as a "reset map view" button.
111122
// addControl synchronously inserts the compass into the DOM, so this
112123
// runs reliably without depending on the map 'load' event or pin image
@@ -131,14 +142,7 @@ export default function CommunitiesMap({ communities }: CommunitiesMapProps) {
131142
ev => {
132143
ev.preventDefault()
133144
ev.stopPropagation()
134-
map.flyTo({
135-
center: initialCenter,
136-
zoom: initialZoom,
137-
bearing: 0,
138-
pitch: 0,
139-
duration: 500,
140-
essential: true,
141-
})
145+
resetMapView()
142146
},
143147
true
144148
)
@@ -527,15 +531,32 @@ export default function CommunitiesMap({ communities }: CommunitiesMapProps) {
527531
}
528532
}
529533

534+
// ESC resets the view, same as the reset button. Skip while typing in
535+
// a form field — ESC there shouldn't yank the map.
536+
const handleEscKey = function (e: KeyboardEvent) {
537+
if (e.key !== 'Escape') return
538+
const target = e.target as HTMLElement | null
539+
if (
540+
target &&
541+
(target.tagName === 'INPUT' ||
542+
target.tagName === 'TEXTAREA' ||
543+
target.isContentEditable)
544+
)
545+
return
546+
resetMapView()
547+
}
548+
530549
tooltip.addEventListener('click', handleTooltipClick)
531550
document.addEventListener('click', handleDocumentClick)
551+
document.addEventListener('keydown', handleEscKey)
532552

533553
// Store cleanup function for useEffect teardown
534554
cleanupRef.current = () => {
535555
// A pending hover dwell must not fire after unmount.
536556
cancelHoverTimer()
537557
tooltip.removeEventListener('click', handleTooltipClick)
538558
document.removeEventListener('click', handleDocumentClick)
559+
document.removeEventListener('keydown', handleEscKey)
539560
resizeObserver.disconnect()
540561
}
541562
})

src/app/map/D3Map.tsx

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -497,11 +497,28 @@ export default function D3Map({ orgs }: D3MapProps) {
497497
svg.transition().duration(300).call(zoom.scaleBy, 0.75)
498498
}
499499
}
500+
const resetView = () => {
501+
svg.transition().duration(500).call(zoom.transform, d3.zoomIdentity)
502+
}
500503
if (recenter) {
501-
recenter.onclick = () => {
502-
svg.transition().duration(500).call(zoom.transform, d3.zoomIdentity)
503-
}
504+
recenter.onclick = resetView
505+
}
506+
507+
// ESC resets the view, same as the recenter button. Skip while typing in
508+
// a form field — ESC there shouldn't yank the map.
509+
const handleEscKey = (e: KeyboardEvent) => {
510+
if (e.key !== 'Escape') return
511+
const target = e.target as HTMLElement | null
512+
if (
513+
target &&
514+
(target.tagName === 'INPUT' ||
515+
target.tagName === 'TEXTAREA' ||
516+
target.isContentEditable)
517+
)
518+
return
519+
resetView()
504520
}
521+
document.addEventListener('keydown', handleEscKey)
505522

506523
// Mobile: tapping the tooltip opens the stashed link in a new tab.
507524
const handleTooltipClick = (e: MouseEvent) => {
@@ -548,6 +565,7 @@ export default function D3Map({ orgs }: D3MapProps) {
548565
svgNode.removeEventListener('wheel', preventPageZoom)
549566
if (tooltipEl) tooltipEl.removeEventListener('click', handleTooltipClick)
550567
document.removeEventListener('click', handleDocumentClick)
568+
document.removeEventListener('keydown', handleEscKey)
551569
if (container) {
552570
d3.select(container).select('svg').remove()
553571
}

0 commit comments

Comments
 (0)