Skip to content

fix(google-maps): persist user pan and re-emit ready on color-mode re-init - #730

Closed
harlan-zw wants to merge 2 commits into
mainfrom
fix/google-maps-imperative-pin-persistence
Closed

fix(google-maps): persist user pan and re-emit ready on color-mode re-init#730
harlan-zw wants to merge 2 commits into
mainfrom
fix/google-maps-imperative-pin-persistence

Conversation

@harlan-zw

Copy link
Copy Markdown
Collaborator

🔗 Linked issue

Related to #727

❓ Type of change

  • 📖 Documentation
  • 🐞 Bug fix
  • 👌 Enhancement
  • ✨ New feature
  • 🧹 Chore
  • ⚠️ Breaking change

📚 Description

Two regressions surfaced after the cloud-styled mapId fix in #727:

  1. User pan discarded on color-mode toggle. The recreate watcher captured the live center before teardown, but the standalone center watcher then re-fired against the new map instance and called setCenter(propsInitialCenter). Persist the captured center into centerOverride so the recomputed options.value.center matches the new map's actual center; the watcher's lat/lng comparison guard then short-circuits.

  2. Imperative resources silently dropped. Pins (or any objects) created off the exposed map ref outside declarative children disappeared after re-init with no signal to re-attach them. Re-emit ready after constructing the new Map instance so consumers can re-bind, and document the contract in the map-styling guide.

Adds regression tests covering both behaviours.

…-init

Two regressions surfaced after the cloud-styled mapId fix (#727):

1. Toggling color mode discarded the user's panned position. The recreate
   watcher captured the live center before teardown, but the standalone
   center watcher then re-fired against the new map instance and called
   `setCenter(propsInitialCenter)`. Persist the captured center into
   `centerOverride` so the recomputed `options.value.center` matches the
   new map's actual center; the watcher's lat/lng comparison guard then
   short-circuits.

2. Imperative resources created off the exposed `map` ref (e.g. pins
   added outside declarative children) silently disappeared after re-init
   with no signal to re-attach. Re-emit `ready` after constructing the
   new Map instance so consumers can re-bind, and document the contract
   in the map-styling guide.
@vercel

vercel Bot commented Apr 28, 2026

Copy link
Copy Markdown
Contributor

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
scripts-playground Ready Ready Preview, Comment Apr 29, 2026 0:02am

@pkg-pr-new

pkg-pr-new Bot commented Apr 28, 2026

Copy link
Copy Markdown

Open in StackBlitz

npm i https://pkg.pr.new/@nuxt/scripts@730

commit: 131de29

@coderabbitai

coderabbitai Bot commented Apr 28, 2026

Copy link
Copy Markdown

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 32ed01b3-d3b4-4f4c-8ae1-7019d87009d0

📥 Commits

Reviewing files that changed from the base of the PR and between f804d19 and 131de29.

📒 Files selected for processing (2)
  • packages/script/src/runtime/components/GoogleMaps/ScriptGoogleMaps.vue
  • test/unit/google-maps-regressions.test.ts
🚧 Files skipped from review as they are similar to previous changes (2)
  • test/unit/google-maps-regressions.test.ts
  • packages/script/src/runtime/components/GoogleMaps/ScriptGoogleMaps.vue

📝 Walkthrough

Walkthrough

The Vue Google Maps component now preserves user pan during map re-initialization by capturing the current map center into a runtime centerOverride that takes precedence over prop-derived centers; centerOverride is cleared when external props.center changes. On re-init the component reconstructs the map instance and re-emits ready with the same exposed object. Documentation clarifies that mapId and colorScheme are init-only and advises using @ready for imperative resource setup. Four regression unit tests were added covering center/zoom preservation, watcher guards, re-init option propagation, and treating zoom = 0 as valid.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~22 minutes

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately summarizes the main changes: persisting user pan on color-mode re-initialization and re-emitting the ready event.
Description check ✅ Passed The description is directly related to the changeset, explaining the two regressions being fixed, the solutions implemented, and mentioning added regression tests.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/google-maps-imperative-pin-persistence

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share
Review rate limit: 2/8 reviews remaining, refill in 38 minutes and 13 seconds.

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (1)
test/unit/google-maps-regressions.test.ts (1)

624-656: Strengthen this regression to assert runtime behavior, not just value precedence.

This currently validates centerOverride || propsCenter, but it doesn’t assert that the re-assigned map path actually skips setCenter in the watcher flow. Consider asserting the watcher guard path directly (including a post-reinit explicit prop center change case).

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@test/unit/google-maps-regressions.test.ts` around lines 624 - 656, Update the
test to assert runtime behavior of the watcher guard: use the mock map's
setCenter mock (from createMockMap / map.setCenter) to verify that when you
simulate re-init with centerOverride present the watcher does not call setCenter
(expect setCenter not toHaveBeenCalled), then simulate a later prop-derived
center change (e.g., change propsCenter to a different lat/lng and recompute
optionsCenter or trigger the same watcher flow) and assert setCenter is called
with the new coordinates; reference the existing mocks and variables
(createMockMap, map.getCenter, map.setCenter, centerOverride, optionsCenter,
propsCenter) to locate where to add these assertions.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@packages/script/src/runtime/components/GoogleMaps/ScriptGoogleMaps.vue`:
- Around line 412-420: The current code writes the map's captured lat/lng into
centerOverride.value which then always wins in the defu merge and blocks later
external center updates; change the logic so centerOverride only temporarily
preserves the user's pan: assign centerOverride.value = { lat: ..., lng: ... }
right before teardown/re-init but immediately clear it (e.g.,
centerOverride.value = null or undefined) once the new map is initialized or
whenever props.center / mapOptions.center changes (add/extend the watcher that
handles external center updates to reset centerOverride), and ensure
centerOverride's type accepts null so external updates can again take precedence
in options.value.center.

---

Nitpick comments:
In `@test/unit/google-maps-regressions.test.ts`:
- Around line 624-656: Update the test to assert runtime behavior of the watcher
guard: use the mock map's setCenter mock (from createMockMap / map.setCenter) to
verify that when you simulate re-init with centerOverride present the watcher
does not call setCenter (expect setCenter not toHaveBeenCalled), then simulate a
later prop-derived center change (e.g., change propsCenter to a different
lat/lng and recompute optionsCenter or trigger the same watcher flow) and assert
setCenter is called with the new coordinates; reference the existing mocks and
variables (createMockMap, map.getCenter, map.setCenter, centerOverride,
optionsCenter, propsCenter) to locate where to add these assertions.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 47a2a39e-466b-4fe4-9b8e-594b7bdf3ce1

📥 Commits

Reviewing files that changed from the base of the PR and between 2cebce3 and f804d19.

📒 Files selected for processing (3)
  • docs/content/scripts/google-maps/1.guides/2.map-styling.md
  • packages/script/src/runtime/components/GoogleMaps/ScriptGoogleMaps.vue
  • test/unit/google-maps-regressions.test.ts

…center

Persisting the user-panned center into `centerOverride` made the override
sticky in `defu` precedence: any later `props.center` or
`props.mapOptions.center` updates would silently fail to propagate
because `options.value.center` kept returning the stored override.

Add a watcher on the requested center that clears the override whenever
the caller changes it. Strengthen the regression test to assert the
watcher's setCenter call is actually skipped on re-init, and add a new
test covering the post-reinit external center update path.
@harlan-zw

Copy link
Copy Markdown
Collaborator Author

Duplicate of #731 (same fix, less complete). Closing in favor of #731.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant