@vis.gl/react-google-maps 1.9.0 rewires AdvancedMarker's onClick in a way that breaks f3-map at runtime. The Renovate PR bumping 1.8.3 → 1.9.0 surfaced this as 5 typecheck errors. The version is currently held at ~1.8.3 so the rest of that dependency update could land; this issue tracks doing the migration properly.
What changed upstream
visgl/react-google-maps#997 — "use correct pointer events behaviour for advanced markers", fixes visgl/react-google-maps#990 — rewired AdvancedMarker's onClick:
|
1.8.3 |
1.9.0 |
| Wiring |
useMapsEventListener(marker, "click", …) |
useDomEventListener(marker, "gmp-click", …) |
| Event type |
google.maps.MapMouseEvent |
google.maps.marker.AdvancedMarkerClickEvent |
Has .latLng / .stop() |
yes |
no — it's a plain DOM Event |
It shipped as a fix in a minor release with no migration note, which is why Renovate proposed it as a routine non-major update.
Why the type errors are true positives
Per Google's docs, AdvancedMarkerClickEvent extends Event — no latLng, no stop(). Suppressing the errors with a cast or ts-ignore would convert compile errors into runtime breakage:
e.stop() → TypeError: e.stop is not a function on every marker click
e.latLng → undefined → the existing throw new Error("No latLng") fires
Affected call sites
All three are AdvancedMarker onClick:
apps/map/src/app/_components/map/group-marker.tsx:133 — e.stop()
apps/map/src/app/_components/map/update-pane.tsx:27,32,33 — e.latLng
apps/map/src/app/_components/marker-clusters/features-cluster-marker.tsx:37 — e.stop()
onDragEnd in update-pane.tsx still receives a real MapMouseEvent and needs no change.
Proposed fix
1. e.latLng in update-pane.tsx — straightforward
That marker already has position={updateLocation}, so the click's latLng is updateLocation. The event round-trip was always redundant. Read the store value directly and drop the latLng guard:
<AdvancedMarker
draggable
onClick={() => {
openModal(ModalType.UPDATE_LOCATION, {
requestType: "create_location",
...eventDefaults,
...locationDefaults,
lat: updateLocation.lat,
lng: updateLocation.lng,
});
}}
onDragEnd={/* unchanged — still a MapMouseEvent */}
position={updateLocation}
>
(Google documents event.target.position as the general replacement, but here the store value is simpler and already in scope.)
2. e.stop() — needs browser verification before picking an implementation
This is the risky half and the reason this is a standalone issue rather than a fix on the Renovate branch.
stop() is load-bearing. apps/map/src/app/_components/map/google-map.tsx:117 has a map-level onClick that clears the selection (and in edit mode drops an updateLocation pin). stop() is what kept a marker click from bubbling up into "deselect everything" — hence the existing // Must call stop to prevent the map from being clicked comments.
Two possibilities, which reading the source alone does not resolve:
stop() is now unnecessary — delete it. 1.9.0 sets marker.content.style.pointerEvents = gmpClickable ? 'all' : 'none' (advanced-marker.tsx:327). That is the actual subject of PR #997, and it may already stop the map from seeing the click.
- Something else is needed.
gmp-click is a synthetic DOM event dispatched by Google, so e.stopPropagation() on it would not stop the original underlying click from bubbling to the map container.
Verification steps (must be done in a browser — CI cannot catch a regression here):
- Click a group marker → selection sticks, no immediate deselect
- Click a cluster marker (
FeaturesClusterMarker) → cluster zoom/expand works, panel doesn't close unexpectedly
- In edit mode, click a group marker → no stray
updateLocation pin is dropped at the click point
- Click empty map → deselect still works (i.e. we didn't over-correct and kill the map handler)
If (1) holds, the fix is deleting the two e.stop() calls and their comments. If (2) holds, the likely shape is having the map's onClick ignore clicks originating from a marker, rather than trying to suppress from the marker side.
3. Release the hold
- Remove the
@vis.gl/react-google-maps rule from renovate.json
- Move the catalog entry in
pnpm-workspace.yaml from ~1.8.3 back to ^1.9.x
Current hold (for context)
To keep the Renovate PR mergeable, the version is pinned in two places — both are needed, they do different jobs:
pnpm-workspace.yaml: ~1.8.3 (not ^1.8.3 — a caret range still permits 1.9.0, so it would not actually hold)
renovate.json: a packageRule with allowedVersions: "<1.9.0", which stops Renovate re-proposing the bump but has no effect on what pnpm resolves
Done when
🤖 Filed by Claude Code while triaging a Renovate dependency-update typecheck failure.
@vis.gl/react-google-maps1.9.0 rewiresAdvancedMarker'sonClickin a way that breaksf3-mapat runtime. The Renovate PR bumping 1.8.3 → 1.9.0 surfaced this as 5 typecheck errors. The version is currently held at~1.8.3so the rest of that dependency update could land; this issue tracks doing the migration properly.What changed upstream
visgl/react-google-maps#997 — "use correct pointer events behaviour for advanced markers", fixes visgl/react-google-maps#990 — rewired
AdvancedMarker'sonClick:useMapsEventListener(marker, "click", …)useDomEventListener(marker, "gmp-click", …)google.maps.MapMouseEventgoogle.maps.marker.AdvancedMarkerClickEvent.latLng/.stop()EventIt shipped as a
fixin a minor release with no migration note, which is why Renovate proposed it as a routine non-major update.Why the type errors are true positives
Per Google's docs,
AdvancedMarkerClickEvent extends Event— nolatLng, nostop(). Suppressing the errors with a cast orts-ignorewould convert compile errors into runtime breakage:e.stop()→TypeError: e.stop is not a functionon every marker clicke.latLng→undefined→ the existingthrow new Error("No latLng")firesAffected call sites
All three are
AdvancedMarkeronClick:apps/map/src/app/_components/map/group-marker.tsx:133—e.stop()apps/map/src/app/_components/map/update-pane.tsx:27,32,33—e.latLngapps/map/src/app/_components/marker-clusters/features-cluster-marker.tsx:37—e.stop()onDragEndinupdate-pane.tsxstill receives a realMapMouseEventand needs no change.Proposed fix
1.
e.latLnginupdate-pane.tsx— straightforwardThat marker already has
position={updateLocation}, so the click's latLng isupdateLocation. The event round-trip was always redundant. Read the store value directly and drop thelatLngguard:(Google documents
event.target.positionas the general replacement, but here the store value is simpler and already in scope.)2.
e.stop()— needs browser verification before picking an implementationThis is the risky half and the reason this is a standalone issue rather than a fix on the Renovate branch.
stop()is load-bearing.apps/map/src/app/_components/map/google-map.tsx:117has a map-levelonClickthat clears the selection (and in edit mode drops anupdateLocationpin).stop()is what kept a marker click from bubbling up into "deselect everything" — hence the existing// Must call stop to prevent the map from being clickedcomments.Two possibilities, which reading the source alone does not resolve:
stop()is now unnecessary — delete it. 1.9.0 setsmarker.content.style.pointerEvents = gmpClickable ? 'all' : 'none'(advanced-marker.tsx:327). That is the actual subject of PR #997, and it may already stop the map from seeing the click.gmp-clickis a synthetic DOM event dispatched by Google, soe.stopPropagation()on it would not stop the original underlying click from bubbling to the map container.Verification steps (must be done in a browser — CI cannot catch a regression here):
FeaturesClusterMarker) → cluster zoom/expand works, panel doesn't close unexpectedlyupdateLocationpin is dropped at the click pointIf (1) holds, the fix is deleting the two
e.stop()calls and their comments. If (2) holds, the likely shape is having the map'sonClickignore clicks originating from a marker, rather than trying to suppress from the marker side.3. Release the hold
@vis.gl/react-google-mapsrule fromrenovate.jsonpnpm-workspace.yamlfrom~1.8.3back to^1.9.xCurrent hold (for context)
To keep the Renovate PR mergeable, the version is pinned in two places — both are needed, they do different jobs:
pnpm-workspace.yaml:~1.8.3(not^1.8.3— a caret range still permits 1.9.0, so it would not actually hold)renovate.json: apackageRulewithallowedVersions: "<1.9.0", which stops Renovate re-proposing the bump but has no effect on what pnpm resolvesDone when
.stop()/.latLngrenovate.jsonhold rule removed and catalog moved back to^1.9.x🤖 Filed by Claude Code while triaging a Renovate dependency-update typecheck failure.