Skip to content

Commit 30b06d4

Browse files
committed
fix(map): prevent auto-zoom on pin drop, add crosshair cursor
- Map stays at current zoom after each pin drop - Auto-fit bounds only fires after trip is planned - Crosshair cursor when picking mode is active
1 parent 9341d3f commit 30b06d4

1 file changed

Lines changed: 23 additions & 18 deletions

File tree

frontend/src/components/RouteMap.tsx

Lines changed: 23 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -96,11 +96,25 @@ function buildIcon(type: MarkerType) {
9696
});
9797
}
9898

99-
function MapBounds({ points }: { points: [number, number][] }) {
99+
function MapBounds({
100+
points,
101+
enabled,
102+
}: {
103+
points: [number, number][];
104+
enabled: boolean;
105+
}) {
100106
const map = useMap();
101-
if (points.length > 0) {
102-
map.fitBounds(points, { padding: [24, 24] });
103-
}
107+
// Stable string key: changes only when the actual route coordinates change.
108+
// Using an empty string when disabled prevents fitBounds from firing on
109+
// pin drops or picking-mode changes — only a new planned route triggers it.
110+
const routeKey = enabled ? points.map((p) => p.join(",")).join("|") : "";
111+
useEffect(() => {
112+
if (enabled && points.length > 0) {
113+
map.fitBounds(points, { padding: [24, 24] });
114+
}
115+
// routeKey is the stable proxy for points + enabled; map is stable.
116+
// eslint-disable-next-line react-hooks/exhaustive-deps
117+
}, [routeKey, map]);
104118
return null;
105119
}
106120

@@ -169,16 +183,8 @@ export function RouteMap({
169183
[events],
170184
);
171185

172-
const points: [number, number][] = markers.map((m) => [m.lat, m.lng]);
173-
const pickedPoints: [number, number][] = pickedEntries
174-
.filter((entry): entry is [LocationType, PickedLocation] => entry[1] !== undefined)
175-
.map(([, p]) => [p.lat, p.lng]);
176-
const boundsPoints =
177-
routeCoordinates.length > 0
178-
? routeCoordinates
179-
: points.length > 0
180-
? points
181-
: pickedPoints;
186+
// Auto-fit only after a trip is planned. Pin drops must never move the map.
187+
const fitEnabled = events.length > 0;
182188

183189
return (
184190
<div className="rounded-xl bg-white p-4 shadow-lg">
@@ -216,9 +222,8 @@ export function RouteMap({
216222
) : null}
217223

218224
<div
219-
className={`h-96 overflow-hidden rounded-lg border border-gray-200 ${
220-
pickingMode ? "cursor-crosshair" : ""
221-
}`}
225+
className="h-96 overflow-hidden rounded-lg border border-gray-200"
226+
style={{ cursor: pickingMode ? "crosshair" : "default" }}
222227
>
223228
<MapContainer center={[39.5, -98.35]} zoom={4} className="h-full w-full">
224229
<TileLayer
@@ -271,7 +276,7 @@ export function RouteMap({
271276
}}
272277
/>
273278
) : null}
274-
<MapBounds points={boundsPoints} />
279+
<MapBounds points={routeCoordinates} enabled={fitEnabled} />
275280
<ResetView trigger={viewResetKey} />
276281
</MapContainer>
277282
</div>

0 commit comments

Comments
 (0)