Skip to content

feat(google-maps): add #renderer slot to ScriptGoogleMapsMarkerClusterer#675

Merged
harlan-zw merged 4 commits intomainfrom
feat/clusterer-renderer-slot
Mar 26, 2026
Merged

feat(google-maps): add #renderer slot to ScriptGoogleMapsMarkerClusterer#675
harlan-zw merged 4 commits intomainfrom
feat/clusterer-renderer-slot

Conversation

@harlan-zw
Copy link
Copy Markdown
Collaborator

🔗 Linked issue

Resolves #674

❓ Type of change

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

📚 Description

Adds a #renderer scoped slot to ScriptGoogleMapsMarkerClusterer that lets users customize cluster visuals with Vue templates instead of writing imperative JS with document.createElement. The slot receives { cluster, stats, map } and renders each cluster as an AdvancedMarkerElement with the slot content as its visual.

The slot name #renderer aligns with the @googlemaps/markerclusterer library's renderer option. When the slot is provided, it overrides any renderer passed via options.

<ScriptGoogleMapsMarkerClusterer>
  <template #renderer="{ cluster }">
    <div class="cluster-badge">{{ cluster.count }}</div>
  </template>
  <ScriptGoogleMapsMarker v-for="loc in locations" :key="loc.id" :position="loc.position" />
</ScriptGoogleMapsMarkerClusterer>

@vercel
Copy link
Copy Markdown
Contributor

vercel bot commented Mar 26, 2026

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

Project Deployment Actions Updated (UTC)
scripts-playground Ready Ready Preview, Comment Mar 26, 2026 10:25am

@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Mar 26, 2026

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: 43f27be3-4fc6-45d1-ac8b-090aff7d915c

📥 Commits

Reviewing files that changed from the base of the PR and between 0a42467 and 99e8cd7.

📒 Files selected for processing (2)
  • docs/content/scripts/google-maps/2.api/4.marker-clusterer.md
  • packages/script/src/runtime/components/GoogleMaps/ScriptGoogleMapsMarkerClusterer.vue

📝 Walkthrough

Walkthrough

Adds slot-based cluster rendering to ScriptGoogleMapsMarkerClusterer: a new #renderer slot is supported and, when present, the component imports the Google Maps marker library, renders slot VNodes into DOM containers, and creates an AdvancedMarkerElement per cluster using that rendered content. It introduces Cluster and ClusterStats interfaces, updates the resource factory create signature to receive { map, mapsApi }, implements explicit lifecycle cleanup for rendered containers, updates docs, and adds unit tests for renderer behavior, import, and cleanup.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and concisely describes the main feature: adding a #renderer slot to ScriptGoogleMapsMarkerClusterer component.
Description check ✅ Passed The description is well-related to the changeset, explaining the purpose of the #renderer slot, its parameters, and providing a practical usage example.
Linked Issues check ✅ Passed The PR successfully implements all core requirements from issue #674: adds a #renderer scoped slot, exposes cluster/stats/map data, enables Vue template-based composition, and aligns with the markerclusterer library's renderer option.
Out of Scope Changes check ✅ Passed All changes are directly related to implementing the #renderer slot feature [#674]: component implementation, API documentation updates, guide documentation, and unit tests for the new functionality.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

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

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/clusterer-renderer-slot

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

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

Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 3

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@docs/content/scripts/google-maps/2.api/4.marker-clusterer.md`:
- Around line 100-103: Update the "Custom Cluster Renderer" docs to mention the
additional `map` slot prop: note that the renderer slot receives `cluster` (with
`count`, `position`, `markers`), `stats`, and `map`; reference the component
forwarding call `slots.renderer({ cluster, stats, map })` and the
MarkerClusterer renderer contract so consumers know `map` (the Google Map
instance) is available to renderer templates.

In
`@packages/script/src/runtime/components/GoogleMaps/ScriptGoogleMapsMarkerClusterer.vue`:
- Around line 30-33: Update the ClusterStats interface to match
`@googlemaps/markerclusterer` v2.6.2: replace the current clusters and markers
arrays with the library contract so ClusterStats has clusters: { count: number;
markers: { min: number; max: number; mean: number; sum: number } } and markers:
{ sum: number }; locate and update the ClusterStats declaration (export
interface ClusterStats) and any dependent usages expecting the old shape (e.g.,
code referencing stats.clusters or stats.markers) to the new property
names/types.
- Around line 106-109: The current render function calls slots.renderer(...) and
mounts a fresh vueRender root, which breaks provide/inject and freezes the
vnode; change it to defer calling slots.renderer until actual render by creating
a wrapper vnode whose render function invokes slots.renderer({ cluster, stats,
map }) at mount time, assign the component's appContext to that wrapper vnode
(e.g., vnode.appContext = instance.appContext or
getCurrentInstance().appContext) before calling vueRender, and remove the
precomputed vnodes variable so injected keys like MARKER_CLUSTERER_INJECTION_KEY
and MAP_INJECTION_KEY are available inside the slot.
🪄 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: 7759fb2e-3c29-4386-998c-27fda162eb1b

📥 Commits

Reviewing files that changed from the base of the PR and between 7a6c2f8 and 0a42467.

📒 Files selected for processing (4)
  • docs/content/scripts/google-maps/1.guides/6.marker-clustering.md
  • docs/content/scripts/google-maps/2.api/4.marker-clusterer.md
  • packages/script/src/runtime/components/GoogleMaps/ScriptGoogleMapsMarkerClusterer.vue
  • test/unit/google-maps-components.test.ts

- Fix ClusterStats interface to match @googlemaps/markerclusterer v2.6.2
- Propagate appContext to slot render root so provide/inject works
- Defer slot invocation to render time
- Document `map` slot prop
@harlan-zw harlan-zw merged commit 4679886 into main Mar 26, 2026
11 of 12 checks passed
@harlan-zw harlan-zw deleted the feat/clusterer-renderer-slot branch March 26, 2026 12:00
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.

Define marker clusterer's renderer in a slot

1 participant