@@ -3,6 +3,7 @@ import { Controller } from '@hotwired/stimulus';
33export type Point = { lat : number ; lng : number } ;
44
55export type MarkerDefinition < MarkerOptions , InfoWindowOptions > = {
6+ '@id' : string ;
67 position : Point ;
78 title : string | null ;
89 infoWindow ?: Omit < InfoWindowDefinition < InfoWindowOptions > , 'position' > ;
@@ -20,6 +21,7 @@ export type MarkerDefinition<MarkerOptions, InfoWindowOptions> = {
2021} ;
2122
2223export type PolygonDefinition < PolygonOptions , InfoWindowOptions > = {
24+ '@id' : string ;
2325 infoWindow ?: Omit < InfoWindowDefinition < InfoWindowOptions > , 'position' > ;
2426 points : Array < Point > ;
2527 title : string | null ;
@@ -59,7 +61,12 @@ export default abstract class<
5961> extends Controller < HTMLElement > {
6062 static values = {
6163 providerOptions : Object ,
62- view : Object ,
64+ center : Object ,
65+ zoom : Number ,
66+ fitBoundsToMarkers : Boolean ,
67+ markers : Array ,
68+ polygons : Array ,
69+ options : Object ,
6370 } ;
6471
6572 declare centerValue : Point | null ;
@@ -70,9 +77,9 @@ export default abstract class<
7077 declare optionsValue: MapOptions ;
7178
7279 protected map : Map ;
73- protected markers : Array < Marker > = [ ] ;
80+ protected markers = new Map < Marker > ( ) ;
7481 protected infoWindows: Array < InfoWindow > = [ ] ;
75- protected polygons : Array < Polygon > = [ ] ;
82+ protected polygons = new Map < Polygon > ( ) ;
7683
7784 connect ( ) {
7885 const options = this . optionsValue ;
@@ -91,8 +98,8 @@ export default abstract class<
9198
9299 this . dispatchEvent ( 'connect' , {
93100 map : this . map ,
94- markers : this . markers ,
95- polygons : this . polygons ,
101+ markers : [ ... this . markers . values ( ) ] ,
102+ polygons : [ ... this . polygons . values ( ) ] ,
96103 infoWindows : this . infoWindows ,
97104 } ) ;
98105 }
@@ -112,20 +119,29 @@ export default abstract class<
112119 const marker = this . doCreateMarker ( definition ) ;
113120 this . dispatchEvent ( 'marker:after-create' , { marker } ) ;
114121
115- this . markers . push ( marker ) ;
122+ marker [ '@id' ] = definition [ '@id' ] ;
123+
124+ this . markers . set ( definition [ '@id' ] , marker ) ;
116125
117126 return marker ;
118127 }
119128
120- createPolygon ( definition : PolygonDefinition < PolygonOptions , InfoWindowOptions > ) : Polygon {
129+ protected abstract removeMarker ( marker : Marker ) : void ;
130+
131+ protected abstract doCreateMarker ( definition : MarkerDefinition < MarkerOptions , InfoWindowOptions > ) : Marker ;
132+
133+ public createPolygon ( definition : PolygonDefinition < PolygonOptions , InfoWindowOptions > ) : Polygon {
121134 this . dispatchEvent ( 'polygon:before-create' , { definition } ) ;
122135 const polygon = this . doCreatePolygon ( definition ) ;
123136 this . dispatchEvent ( 'polygon:after-create' , { polygon } ) ;
124- this . polygons . push ( polygon ) ;
137+
138+ polygon [ '@id' ] = definition [ '@id' ] ;
139+
140+ this . polygons . set ( definition [ '@id' ] , polygon ) ;
141+
125142 return polygon ;
126143 }
127144
128- protected abstract doCreateMarker ( definition : MarkerDefinition < MarkerOptions , InfoWindowOptions > ) : Marker ;
129145 protected abstract doCreatePolygon ( definition : PolygonDefinition < PolygonOptions , InfoWindowOptions > ) : Polygon ;
130146
131147 protected createInfoWindow ( {
@@ -162,4 +178,50 @@ export default abstract class<
162178 protected abstract doFitBoundsToMarkers ( ) : void ;
163179
164180 protected abstract dispatchEvent ( name : string , payload : Record < string , unknown > ) : void ;
181+
182+ public abstract centerValueChanged ( ) : void ;
183+
184+ public abstract zoomValueChanged ( ) : void ;
185+
186+ public markersValueChanged ( ) : void {
187+ if ( this . map ) {
188+ // Remove markers that are not in the new list
189+ this . markers . forEach ( ( marker ) => {
190+ if ( ! this . markersValue . find ( ( m ) => m [ '@id' ] === marker [ '@id' ] ) ) {
191+ this . removeMarker ( marker ) ;
192+ this . markers . delete ( marker [ '@id' ] ) ;
193+ }
194+ } ) ;
195+
196+ // Add new markers
197+ this . markersValue . forEach ( ( marker ) => {
198+ if ( ! this . markers . has ( marker [ '@id' ] ) ) {
199+ this . createMarker ( marker ) ;
200+ }
201+ } ) ;
202+
203+ if ( this . fitBoundsToMarkersValue ) {
204+ this . doFitBoundsToMarkers ( ) ;
205+ }
206+ }
207+ }
208+
209+ public polygonsValueChanged ( ) : void {
210+ if ( this . map ) {
211+ // Remove polygons that are not in the new list
212+ this . polygons . forEach ( ( polygon ) => {
213+ if ( ! this . polygonsValue . find ( ( p ) => p [ '@id' ] === polygon [ '@id' ] ) ) {
214+ polygon . remove ( ) ;
215+ this . polygons . delete ( polygon [ '@id' ] ) ;
216+ }
217+ } ) ;
218+
219+ // Add new polygons
220+ this . polygonsValue . forEach ( ( polygon ) => {
221+ if ( ! this . polygons . has ( polygon [ '@id' ] ) ) {
222+ this . createPolygon ( polygon ) ;
223+ }
224+ } ) ;
225+ }
226+ }
165227}
0 commit comments