feat(google-map): add @c2n/google-map — map, markers, A→B route, Street View

Merged
CO
1mo ago
+2587-0

What

A new package, @c2n/google-map, that wraps the Google Maps JavaScript API:

ElementWhat it does
c2-google-mapThe map: center, zoom, map-id, map-type, gesture-handling, disable-default-ui, an options escape hatch, and .map (the google.maps.Map) for everything else. Events: map-ready, map-click, view-change, map-error.
c2-google-map-markerChild of the map. An Advanced Marker with position, label, glyph, draggable, z-index; pin colours come from --c2-google-map-marker__*. Events: marker-click, marker-drag-end.
c2-google-map-routeChild of the map. Draws the road route from origin to destination (a coordinate or an address, with optional waypoints and a travel-mode) using the Routes API, and adds A/B markers and zooms to fit it. route-change reports distanceMeters, durationMillis and Google's formatted text (e.g. "5.1 km · 16 mins").
c2-google-street-viewA Street View panorama at a position with a heading/pitch, or — with for="<map id>" — the panorama that map's pegman opens.

Google already ships <gmp-map> and <gmp-advanced-marker>, but it has no 2D route element and no Street View element; those two gaps are the main reason for this package.

API key

The Maps JavaScript API runs in the browser, so its key is always visible to the page and no server is needed to hide it. You protect it by restricting it in the Google Cloud console instead (allowed referrers, allowed APIs, quotas). The API loads once per page, from configureGoogleMaps({ apiKey }) or from an element's api-key. Elements that rendered before a key was set retry once it arrives. A missing or rejected key shows a message where the map would be and fires map-error, rather than leaving an empty box.

Docs site

  • New doc page, a 4-card gallery, and a landing preview.
  • The site reads PUBLIC_GOOGLE_MAPS_API_KEY at build time. deploy.yml passes it from a new GOOGLE_MAPS_API_KEY repository secret (still to be added). Without the secret, the examples say a key is needed.

Testing

  • 21 Playwright tests run against test/fake-google.ts, a stand-in for the Maps API that draws real DOM, so they need no key or network. They cover the loader (including a real script-tag load served by the test), clicks, pan/zoom, markers, routes (the request sent, the drawn lines, refetch on change, errors, removal), Street View, and axe checks.
  • Also run by hand against the live API with a demo key. That run found three bugs, all fixed in this PR:
    • The marker used the deprecated PinElement.element.
    • Street View handed a NaN zoom back to Google.
    • The map collapsed to zero width inside a flex container.
  • Lint, format, test:type-check, docs:check, check:dogfood and build:tools all pass.
  • The full Astro site builds, but I couldn't run the whole npm run ui:build in the dev container: its Node 22 is too old for the Angular example app. CI uses Node 24.

Follow-ups

  • Add the GOOGLE_MAPS_API_KEY secret. The key's Google Cloud project needs billing enabled, or Google shows its "For development purposes only" watermark.
  • For production, use your own map-id instead of the default DEMO_MAP_ID.

🤖 Generated with Claude Code

https://claude.ai/code/session_01YMpZxvVixvFSms1qzUmPQM


Generated by Claude Code