diff --git a/src/dev-app/google-map/google-map-demo.html b/src/dev-app/google-map/google-map-demo.html index 610b1141132f..b5e37311ade8 100644 --- a/src/dev-app/google-map/google-map-demo.html +++ b/src/dev-app/google-map/google-map-demo.html @@ -20,6 +20,13 @@ (mapClick)="clickMarker(marker)"> } + Testing 1 2 3 @if (isPolylineDisplayed) { diff --git a/src/dev-app/google-map/google-map-demo.ts b/src/dev-app/google-map/google-map-demo.ts index 3803163aa723..d351b0f893dc 100644 --- a/src/dev-app/google-map/google-map-demo.ts +++ b/src/dev-app/google-map/google-map-demo.ts @@ -25,6 +25,7 @@ import { MapRectangle, MapTrafficLayer, MapTransitLayer, + MapAdvancedMarker, } from '@angular/google-maps'; const POLYLINE_PATH: google.maps.LatLngLiteral[] = [ @@ -72,6 +73,7 @@ let apiLoadingPromise: Promise | null = null; MapKmlLayer, MapMarker, MapMarkerClusterer, + MapAdvancedMarker, MapPolygon, MapPolyline, MapRectangle, @@ -87,6 +89,7 @@ export class GoogleMapDemo { @ViewChild(MapCircle) circle: MapCircle; center = {lat: 24, lng: 12}; + mapAdvancedMarkerPosition = {lat: 24, lng: 16}; markerOptions = {draggable: false}; markerPositions: google.maps.LatLngLiteral[] = []; zoom = 4; @@ -173,6 +176,13 @@ export class GoogleMapDemo { this.infoWindow.open(marker); } + clickAdvancedMarker(advancedMarker: MapAdvancedMarker) { + this.infoWindow.openAdvancedMarkerElement( + advancedMarker.advancedMarker, + advancedMarker.advancedMarker.title, + ); + } + handleRightclick() { this.markerPositions.pop(); } diff --git a/src/google-maps/google-map/google-map.spec.ts b/src/google-maps/google-map/google-map.spec.ts index 51203384f363..270327ef522c 100644 --- a/src/google-maps/google-map/google-map.spec.ts +++ b/src/google-maps/google-map/google-map.spec.ts @@ -114,7 +114,11 @@ describe('GoogleMap', () => { }); it('sets center and zoom of the map', () => { - const options = {center: {lat: 3, lng: 5}, zoom: 7, mapTypeId: DEFAULT_OPTIONS.mapTypeId}; + const options = { + center: {lat: 3, lng: 5}, + zoom: 7, + mapTypeId: DEFAULT_OPTIONS.mapTypeId, + }; mapSpy = createMapSpy(options); mapConstructorSpy = createMapConstructorSpy(mapSpy); @@ -140,6 +144,7 @@ describe('GoogleMap', () => { zoom: 7, draggable: false, mapTypeId: DEFAULT_OPTIONS.mapTypeId, + mapId: '123', }; mapSpy = createMapSpy(options); mapConstructorSpy = createMapConstructorSpy(mapSpy); @@ -194,12 +199,13 @@ describe('GoogleMap', () => { }); it('gives precedence to center and zoom over options', () => { - const inputOptions = {center: {lat: 3, lng: 5}, zoom: 7, heading: 170}; + const inputOptions = {center: {lat: 3, lng: 5}, zoom: 7, heading: 170, mapId: '123'}; const correctedOptions = { center: {lat: 12, lng: 15}, zoom: 5, heading: 170, mapTypeId: DEFAULT_OPTIONS.mapTypeId, + mapId: '123', }; mapSpy = createMapSpy(correctedOptions); mapConstructorSpy = createMapConstructorSpy(mapSpy); diff --git a/src/google-maps/google-map/google-map.ts b/src/google-maps/google-map/google-map.ts index 848917c80cf8..387257b6d5f3 100644 --- a/src/google-maps/google-map/google-map.ts +++ b/src/google-maps/google-map/google-map.ts @@ -83,6 +83,12 @@ export class GoogleMap implements OnChanges, OnInit, OnDestroy { /** Width of the map. Set this to `null` if you'd like to control the width through CSS. */ @Input() width: string | number | null = DEFAULT_WIDTH; + /** + * The Map ID of the map. This parameter cannot be set or changed after a map is instantiated. + * See: https://developers.google.com/maps/documentation/javascript/reference/map#MapOptions.mapId + */ + @Input() mapId: string | undefined; + /** * Type of map that should be rendered. E.g. hybrid map, terrain map etc. * See: https://developers.google.com/maps/documentation/javascript/reference/map#MapTypeId diff --git a/src/google-maps/google-maps-module.ts b/src/google-maps/google-maps-module.ts index 266e583b1d26..621a13c00667 100644 --- a/src/google-maps/google-maps-module.ts +++ b/src/google-maps/google-maps-module.ts @@ -24,6 +24,7 @@ import {MapRectangle} from './map-rectangle/map-rectangle'; import {MapTrafficLayer} from './map-traffic-layer/map-traffic-layer'; import {MapTransitLayer} from './map-transit-layer/map-transit-layer'; import {MapHeatmapLayer} from './map-heatmap-layer/map-heatmap-layer'; +import {MapAdvancedMarker} from './map-advanced-marker/map-advanced-marker'; const COMPONENTS = [ GoogleMap, @@ -36,6 +37,7 @@ const COMPONENTS = [ MapInfoWindow, MapKmlLayer, MapMarker, + MapAdvancedMarker, MapMarkerClusterer, MapPolygon, MapPolyline, diff --git a/src/google-maps/map-advanced-marker/map-advanced-marker.spec.ts b/src/google-maps/map-advanced-marker/map-advanced-marker.spec.ts new file mode 100644 index 000000000000..c35ef1d92853 --- /dev/null +++ b/src/google-maps/map-advanced-marker/map-advanced-marker.spec.ts @@ -0,0 +1,182 @@ +import {Component, ViewChild} from '@angular/core'; +import {TestBed, fakeAsync, flush} from '@angular/core/testing'; + +import {DEFAULT_OPTIONS, GoogleMap} from '../google-map/google-map'; +import { + createAdvancedMarkerConstructorSpy, + createAdvancedMarkerSpy, + createMapConstructorSpy, + createMapSpy, +} from '../testing/fake-google-map-utils'; +import {DEFAULT_MARKER_OPTIONS, MapAdvancedMarker} from './map-advanced-marker'; + +describe('MapAdvancedMarker', () => { + let mapSpy: jasmine.SpyObj; + + beforeEach(() => { + mapSpy = createMapSpy(DEFAULT_OPTIONS); + createMapConstructorSpy(mapSpy); + }); + + afterEach(() => { + (window.google as any) = undefined; + }); + + it('initializes a Google Map advanced marker', fakeAsync(() => { + const advancedMarkerSpy = createAdvancedMarkerSpy(DEFAULT_MARKER_OPTIONS); + const advancedMarkerConstructorSpy = createAdvancedMarkerConstructorSpy(advancedMarkerSpy); + + const fixture = TestBed.createComponent(TestApp); + fixture.detectChanges(); + flush(); + expect(advancedMarkerConstructorSpy).toHaveBeenCalledWith({ + ...DEFAULT_MARKER_OPTIONS, + title: undefined, + content: undefined, + gmpDraggable: undefined, + zIndex: undefined, + map: mapSpy, + }); + })); + + it('sets advanced marker inputs', fakeAsync(() => { + const options: google.maps.marker.AdvancedMarkerElementOptions = { + position: {lat: 3, lng: 5}, + title: 'marker title', + map: mapSpy, + content: undefined, + gmpDraggable: true, + zIndex: 1, + }; + const advancedMarkerSpy = createAdvancedMarkerSpy(options); + const advancedMarkerConstructorSpy = createAdvancedMarkerConstructorSpy(advancedMarkerSpy); + + const fixture = TestBed.createComponent(TestApp); + fixture.componentInstance.position = options.position; + fixture.componentInstance.title = options.title; + fixture.componentInstance.content = options.content; + fixture.componentInstance.gmpDraggable = options.gmpDraggable; + fixture.componentInstance.zIndex = options.zIndex; + + fixture.detectChanges(); + flush(); + + expect(advancedMarkerConstructorSpy).toHaveBeenCalledWith(options); + })); + + it('sets marker options, ignoring map', fakeAsync(() => { + const options: google.maps.marker.AdvancedMarkerElementOptions = { + position: {lat: 3, lng: 5}, + title: 'marker title', + content: undefined, + gmpDraggable: true, + zIndex: 1, + }; + const advancedMarkerSpy = createAdvancedMarkerSpy(options); + const advancedMarkerConstructorSpy = createAdvancedMarkerConstructorSpy(advancedMarkerSpy); + + const fixture = TestBed.createComponent(TestApp); + fixture.componentInstance.options = options; + fixture.detectChanges(); + flush(); + + expect(advancedMarkerConstructorSpy).toHaveBeenCalledWith({...options, map: mapSpy}); + })); + + it('gives precedence to specific inputs over options', fakeAsync(() => { + const options: google.maps.marker.AdvancedMarkerElementOptions = { + position: {lat: 3, lng: 5}, + title: 'marker title', + content: undefined, + gmpDraggable: true, + zIndex: 1, + }; + + const expectedOptions: google.maps.marker.AdvancedMarkerElementOptions = { + position: {lat: 4, lng: 6}, + title: 'marker title 2', + content: undefined, + gmpDraggable: false, + zIndex: 999, + map: mapSpy, + }; + const advancedMarkerSpy = createAdvancedMarkerSpy(options); + const advancedMarkerConstructorSpy = createAdvancedMarkerConstructorSpy(advancedMarkerSpy); + + const fixture = TestBed.createComponent(TestApp); + fixture.componentInstance.position = expectedOptions.position; + fixture.componentInstance.title = expectedOptions.title; + fixture.componentInstance.content = expectedOptions.content; + fixture.componentInstance.gmpDraggable = expectedOptions.gmpDraggable; + fixture.componentInstance.zIndex = expectedOptions.zIndex; + fixture.componentInstance.options = options; + + fixture.detectChanges(); + flush(); + + expect(advancedMarkerConstructorSpy).toHaveBeenCalledWith(expectedOptions); + })); + + it('initializes marker event handlers', fakeAsync(() => { + const advancedMarkerSpy = createAdvancedMarkerSpy(DEFAULT_MARKER_OPTIONS); + createAdvancedMarkerConstructorSpy(advancedMarkerSpy); + + const addSpy = advancedMarkerSpy.addListener; + const fixture = TestBed.createComponent(TestApp); + fixture.detectChanges(); + flush(); + + expect(addSpy).toHaveBeenCalledWith('click', jasmine.any(Function)); + expect(addSpy).not.toHaveBeenCalledWith('drag', jasmine.any(Function)); + expect(addSpy).not.toHaveBeenCalledWith('dragend', jasmine.any(Function)); + expect(addSpy).not.toHaveBeenCalledWith('dragstart', jasmine.any(Function)); + })); + + it('should be able to add an event listener after init', fakeAsync(() => { + const advancedMarkerSpy = createAdvancedMarkerSpy(DEFAULT_MARKER_OPTIONS); + createAdvancedMarkerConstructorSpy(advancedMarkerSpy); + + const addSpy = advancedMarkerSpy.addListener; + const fixture = TestBed.createComponent(TestApp); + fixture.detectChanges(); + flush(); + + expect(addSpy).not.toHaveBeenCalledWith('drag', jasmine.any(Function)); + + // Pick an event that isn't bound in the template. + const subscription = fixture.componentInstance.advancedMarker.mapDrag.subscribe(); + fixture.detectChanges(); + + expect(addSpy).toHaveBeenCalledWith('drag', jasmine.any(Function)); + subscription.unsubscribe(); + })); +}); + +@Component({ + selector: 'test-app', + template: ` + + + + `, + standalone: true, + imports: [GoogleMap, MapAdvancedMarker], +}) +class TestApp { + @ViewChild(MapAdvancedMarker) advancedMarker: MapAdvancedMarker; + title?: string | null; + position?: google.maps.LatLng | google.maps.LatLngLiteral | null; + content?: Node | google.maps.marker.PinElement | null; + gmpDraggable?: boolean | null; + zIndex?: number | null; + options: google.maps.marker.AdvancedMarkerElementOptions; + + handleClick() {} +} diff --git a/src/google-maps/map-advanced-marker/map-advanced-marker.ts b/src/google-maps/map-advanced-marker/map-advanced-marker.ts new file mode 100644 index 000000000000..b3d72bc03a39 --- /dev/null +++ b/src/google-maps/map-advanced-marker/map-advanced-marker.ts @@ -0,0 +1,255 @@ +/** + * @license + * Copyright Google LLC All Rights Reserved. + * + * Use of this source code is governed by an MIT-style license that can be + * found in the LICENSE file at https://angular.io/license + */ + +// Workaround for: https://github.com/bazelbuild/rules_nodejs/issues/1265 +/// + +import { + Input, + OnDestroy, + OnInit, + Output, + NgZone, + Directive, + OnChanges, + SimpleChanges, + inject, + EventEmitter, +} from '@angular/core'; + +import {GoogleMap} from '../google-map/google-map'; +import {MapEventManager} from '../map-event-manager'; +import {Observable} from 'rxjs'; + +/** + * Default options for the Google Maps marker component. Displays a marker + * at the Googleplex. + */ +export const DEFAULT_MARKER_OPTIONS = { + position: {lat: 37.221995, lng: -122.184092}, +}; + +/** + * Angular component that renders a Google Maps marker via the Google Maps JavaScript API. + * + * See developers.google.com/maps/documentation/javascript/reference/marker + */ +@Directive({ + selector: 'map-advanced-marker', + exportAs: 'mapAdvancedMarker', + standalone: true, +}) +export class MapAdvancedMarker implements OnInit, OnChanges, OnDestroy { + private _eventManager = new MapEventManager(inject(NgZone)); + + /** + * Rollover text. If provided, an accessibility text (e.g. for use with screen readers) will be added to the AdvancedMarkerElement with the provided value. + * See: https://developers.google.com/maps/documentation/javascript/reference/advanced-markers#AdvancedMarkerElementOptions.title + */ + @Input() + set title(title: string) { + this._title = title; + } + private _title: string; + + /** + * Sets the AdvancedMarkerElement's position. An AdvancedMarkerElement may be constructed without a position, but will not be displayed until its position is provided - for example, by a user's actions or choices. An AdvancedMarkerElement's position can be provided by setting AdvancedMarkerElement.position if not provided at the construction. + * Note: AdvancedMarkerElement with altitude is only supported on vector maps. + * https://developers.google.com/maps/documentation/javascript/reference/advanced-markers#AdvancedMarkerElementOptions.position + */ + @Input() + set position( + position: + | google.maps.LatLngLiteral + | google.maps.LatLng + | google.maps.LatLngAltitude + | google.maps.LatLngAltitudeLiteral, + ) { + this._position = position; + } + private _position: google.maps.LatLngLiteral | google.maps.LatLng; + + /** + * The DOM Element backing the visual of an AdvancedMarkerElement. + * Note: AdvancedMarkerElement does not clone the passed-in DOM element. Once the DOM element is passed to an AdvancedMarkerElement, passing the same DOM element to another AdvancedMarkerElement will move the DOM element and cause the previous AdvancedMarkerElement to look empty. + * See: https://developers.google.com/maps/documentation/javascript/reference/advanced-markers#AdvancedMarkerElementOptions.content + */ + @Input() + set content(content: Node | google.maps.marker.PinElement) { + this._content = content; + } + private _content: Node; + + /** + * If true, the AdvancedMarkerElement can be dragged. + * Note: AdvancedMarkerElement with altitude is not draggable. + * https://developers.google.com/maps/documentation/javascript/reference/advanced-markers#AdvancedMarkerElementOptions.gmpDraggable + */ + @Input() + set gmpDraggable(draggable: boolean) { + this._draggable = draggable; + } + private _draggable: boolean; + + /** + * Options for constructing an AdvancedMarkerElement. + * https://developers.google.com/maps/documentation/javascript/reference/advanced-markers#AdvancedMarkerElementOptions + */ + @Input() + set options(options: google.maps.marker.AdvancedMarkerElementOptions) { + this._options = options; + } + private _options: google.maps.marker.AdvancedMarkerElementOptions; + + /** + * AdvancedMarkerElements on the map are prioritized by zIndex, with higher values indicating higher display. + * https://developers.google.com/maps/documentation/javascript/reference/advanced-markers#AdvancedMarkerElementOptions.zIndex + */ + @Input() + set zIndex(zIndex: number) { + this._zIndex = zIndex; + } + private _zIndex: number; + + /** + * This event is fired when the AdvancedMarkerElement element is clicked. + * https://developers.google.com/maps/documentation/javascript/reference/advanced-markers#AdvancedMarkerElement.click + */ + @Output() readonly mapClick: Observable = + this._eventManager.getLazyEmitter('click'); + + /** + * This event is repeatedly fired while the user drags the AdvancedMarkerElement. + * https://developers.google.com/maps/documentation/javascript/reference/advanced-markers#AdvancedMarkerElement.drag + */ + @Output() readonly mapDrag: Observable = + this._eventManager.getLazyEmitter('drag'); + + /** + * This event is fired when the user stops dragging the AdvancedMarkerElement. + * https://developers.google.com/maps/documentation/javascript/reference/advanced-markers#AdvancedMarkerElement.dragend + */ + @Output() readonly mapDragend: Observable = + this._eventManager.getLazyEmitter('dragend'); + + /** + * This event is fired when the user starts dragging the AdvancedMarkerElement. + * https://developers.google.com/maps/documentation/javascript/reference/advanced-markers#AdvancedMarkerElement.dragstart + */ + @Output() readonly mapDragstart: Observable = + this._eventManager.getLazyEmitter('dragstart'); + + /** Event emitted when the marker is initialized. */ + @Output() readonly markerInitialized: EventEmitter = + new EventEmitter(); + + /** + * The underlying google.maps.marker.AdvancedMarkerElement object. + * + * See developers.google.com/maps/documentation/javascript/reference/advanced-markers#AdvancedMarkerElement + */ + advancedMarker: google.maps.marker.AdvancedMarkerElement; + + constructor( + private readonly _googleMap: GoogleMap, + private _ngZone: NgZone, + ) {} + + ngOnInit() { + if (!this._googleMap._isBrowser) { + return; + } + if (google.maps.marker?.AdvancedMarkerElement && this._googleMap.googleMap) { + this._initialize(this._googleMap.googleMap, google.maps.marker.AdvancedMarkerElement); + } else { + this._ngZone.runOutsideAngular(() => { + Promise.all([this._googleMap._resolveMap(), google.maps.importLibrary('marker')]).then( + ([map, lib]) => { + this._initialize(map, (lib as google.maps.MarkerLibrary).AdvancedMarkerElement); + }, + ); + }); + } + } + + private _initialize( + map: google.maps.Map, + advancedMarkerConstructor: typeof google.maps.marker.AdvancedMarkerElement, + ) { + // Create the object outside the zone so its events don't trigger change detection. + // We'll bring it back in inside the `MapEventManager` only for the events that the + // user has subscribed to. + this._ngZone.runOutsideAngular(() => { + this.advancedMarker = new advancedMarkerConstructor(this._combineOptions()); + this._assertInitialized(); + this.advancedMarker.map = map; + this._eventManager.setTarget(this.advancedMarker); + this.markerInitialized.next(this.advancedMarker); + }); + } + + ngOnChanges(changes: SimpleChanges) { + const {advancedMarker, _content, _position, _title, _draggable, _zIndex} = this; + if (advancedMarker) { + if (changes['title']) { + advancedMarker.title = _title; + } + + if (changes['content']) { + advancedMarker.content = _content; + } + + if (changes['gmpDraggable']) { + advancedMarker.gmpDraggable = _draggable; + } + + if (changes['content']) { + advancedMarker.content = _content; + } + + if (changes['position']) { + advancedMarker.position = _position; + } + + if (changes['zIndex']) { + advancedMarker.zIndex = _zIndex; + } + } + } + + ngOnDestroy() { + this.markerInitialized.complete(); + this._eventManager.destroy(); + } + + /** Creates a combined options object using the passed-in options and the individual inputs. */ + private _combineOptions(): google.maps.marker.AdvancedMarkerElementOptions { + const options = this._options || DEFAULT_MARKER_OPTIONS; + return { + ...options, + title: this._title || options.title, + position: this._position || options.position, + content: this._content || options.content, + zIndex: this._zIndex ?? options.zIndex, + gmpDraggable: this._draggable ?? options.gmpDraggable, + map: this._googleMap.googleMap, + }; + } + + /** Asserts that the map has been initialized. */ + private _assertInitialized(): asserts this is {marker: google.maps.marker.AdvancedMarkerElement} { + if (typeof ngDevMode === 'undefined' || ngDevMode) { + if (!this.advancedMarker) { + throw Error( + 'Cannot interact with a Google Map Marker before it has been ' + + 'initialized. Please wait for the Marker to load before trying to interact with it.', + ); + } + } + } +} diff --git a/src/google-maps/map-info-window/map-info-window.ts b/src/google-maps/map-info-window/map-info-window.ts index 7df31252414c..1a9f6981a79b 100644 --- a/src/google-maps/map-info-window/map-info-window.ts +++ b/src/google-maps/map-info-window/map-info-window.ts @@ -193,6 +193,25 @@ export class MapInfoWindow implements OnInit, OnDestroy { return this.infoWindow.getZIndex(); } + /** + * Opens the MapInfoWindow using the provided AdvancedMarkerElement. + */ + openAdvancedMarkerElement( + advancedMarkerElement: google.maps.marker.AdvancedMarkerElement, + content?: string | Element | Text, + ): void { + this._assertInitialized(); + if (!advancedMarkerElement) { + return; + } + + this.infoWindow.close(); + if (content) { + this.infoWindow.setContent(content); + } + this.infoWindow.open(this._googleMap.googleMap, advancedMarkerElement); + } + /** * Opens the MapInfoWindow using the provided anchor. If the anchor is not set, * then the position property of the options input is used instead. diff --git a/src/google-maps/public-api.ts b/src/google-maps/public-api.ts index 07266ec3ee9a..ed4a5a3251b3 100644 --- a/src/google-maps/public-api.ts +++ b/src/google-maps/public-api.ts @@ -21,6 +21,7 @@ export {MapGroundOverlay} from './map-ground-overlay/map-ground-overlay'; export {MapInfoWindow} from './map-info-window/map-info-window'; export {MapKmlLayer} from './map-kml-layer/map-kml-layer'; export {MapMarker} from './map-marker/map-marker'; +export {MapAdvancedMarker} from './map-advanced-marker/map-advanced-marker'; export {MapMarkerClusterer} from './map-marker-clusterer/map-marker-clusterer'; export {MapPolygon} from './map-polygon/map-polygon'; export {MapPolyline} from './map-polyline/map-polyline'; diff --git a/src/google-maps/testing/fake-google-map-utils.ts b/src/google-maps/testing/fake-google-map-utils.ts index 1c56ec6b320f..fd408581756a 100644 --- a/src/google-maps/testing/fake-google-map-utils.ts +++ b/src/google-maps/testing/fake-google-map-utils.ts @@ -36,6 +36,9 @@ export interface TestingWindow extends Window { visualization?: { HeatmapLayer?: jasmine.Spy; }; + marker?: { + AdvancedMarkerElement?: jasmine.Spy; + }; Geocoder?: jasmine.Spy; }; }; @@ -139,6 +142,45 @@ export function createMarkerConstructorSpy( return markerConstructorSpy; } +/** Creates a jasmine.SpyObj for a google.maps.marker.AdvancedMarkerElement */ +export function createAdvancedMarkerSpy( + options: google.maps.marker.AdvancedMarkerElementOptions, +): jasmine.SpyObj { + const advancedMarkerSpy = jasmine.createSpyObj('google.maps.marker.AdvancedMarkerElement', [ + 'addListener', + ]); + advancedMarkerSpy.addListener.and.returnValue({remove: () => {}}); + return advancedMarkerSpy; +} + +/** Creates a jasmine.Spy to watch for the constructor of a google.maps.marker.AdvancedMarkerElement */ +export function createAdvancedMarkerConstructorSpy( + advancedMarkerSpy: jasmine.SpyObj, +): jasmine.Spy { + // The spy target function cannot be an arrow-function as this breaks when created through `new`. + const advancedMarkerConstructorSpy = jasmine + .createSpy('Advanced Marker constructor', function () { + return advancedMarkerSpy; + }) + .and.callThrough(); + const testingWindow: TestingWindow = window; + if (testingWindow.google && testingWindow.google.maps) { + testingWindow.google.maps.marker = { + 'AdvancedMarkerElement': advancedMarkerConstructorSpy, + }; + } else { + testingWindow.google = { + maps: { + marker: { + 'AdvancedMarkerElement': advancedMarkerConstructorSpy, + }, + }, + }; + } + + return advancedMarkerConstructorSpy; +} + /** Creates a jasmine.SpyObj for a google.maps.InfoWindow */ export function createInfoWindowSpy( options: google.maps.InfoWindowOptions, diff --git a/tools/public_api_guard/google-maps/google-maps.md b/tools/public_api_guard/google-maps/google-maps.md index 892c09c3ec6a..1f71a6f4a183 100644 --- a/tools/public_api_guard/google-maps/google-maps.md +++ b/tools/public_api_guard/google-maps/google-maps.md @@ -86,6 +86,7 @@ export class GoogleMap implements OnChanges, OnInit, OnDestroy { readonly mapDrag: Observable; readonly mapDragend: Observable; readonly mapDragstart: Observable; + mapId: string | undefined; readonly mapInitialized: EventEmitter; readonly mapMousemove: Observable; readonly mapMouseout: Observable; @@ -115,7 +116,7 @@ export class GoogleMap implements OnChanges, OnInit, OnDestroy { set zoom(zoom: number); readonly zoomChanged: Observable; // (undocumented) - static ɵcmp: i0.ɵɵComponentDeclaration; + static ɵcmp: i0.ɵɵComponentDeclaration; // (undocumented) static ɵfac: i0.ɵɵFactoryDeclaration; } @@ -127,12 +128,39 @@ export class GoogleMapsModule { // (undocumented) static ɵinj: i0.ɵɵInjectorDeclaration; // (undocumented) - static ɵmod: i0.ɵɵNgModuleDeclaration; + static ɵmod: i0.ɵɵNgModuleDeclaration; } // @public export type HeatmapData = google.maps.MVCArray | (google.maps.LatLng | google.maps.visualization.WeightedLocation | google.maps.LatLngLiteral)[]; +// @public +export class MapAdvancedMarker implements OnInit, OnChanges, OnDestroy { + constructor(_googleMap: GoogleMap, _ngZone: NgZone); + advancedMarker: google.maps.marker.AdvancedMarkerElement; + set content(content: Node | google.maps.marker.PinElement); + set gmpDraggable(draggable: boolean); + readonly mapClick: Observable; + readonly mapDrag: Observable; + readonly mapDragend: Observable; + readonly mapDragstart: Observable; + readonly markerInitialized: EventEmitter; + // (undocumented) + ngOnChanges(changes: SimpleChanges): void; + // (undocumented) + ngOnDestroy(): void; + // (undocumented) + ngOnInit(): void; + set options(options: google.maps.marker.AdvancedMarkerElementOptions); + set position(position: google.maps.LatLngLiteral | google.maps.LatLng | google.maps.LatLngAltitude | google.maps.LatLngAltitudeLiteral); + set title(title: string); + set zIndex(zIndex: number); + // (undocumented) + static ɵdir: i0.ɵɵDirectiveDeclaration; + // (undocumented) + static ɵfac: i0.ɵɵFactoryDeclaration; +} + // @public export interface MapAnchorPoint { // (undocumented) @@ -364,6 +392,7 @@ export class MapInfoWindow implements OnInit, OnDestroy { // (undocumented) ngOnInit(): void; open(anchor?: MapAnchorPoint, shouldFocus?: boolean): void; + openAdvancedMarkerElement(advancedMarkerElement: google.maps.marker.AdvancedMarkerElement, content?: string | Element | Text): void; // (undocumented) set options(options: google.maps.InfoWindowOptions); // (undocumented)