@@ -3,6 +3,7 @@ import { Controller } from '@hotwired/stimulus';
3
3
export type Point = { lat : number ; lng : number } ;
4
4
5
5
export type MarkerDefinition < MarkerOptions , InfoWindowOptions > = {
6
+ '@id' : string ;
6
7
position : Point ;
7
8
title : string | null ;
8
9
infoWindow ?: Omit < InfoWindowDefinition < InfoWindowOptions > , 'position' > ;
@@ -20,6 +21,7 @@ export type MarkerDefinition<MarkerOptions, InfoWindowOptions> = {
20
21
} ;
21
22
22
23
export type PolygonDefinition < PolygonOptions , InfoWindowOptions > = {
24
+ '@id' : string ;
23
25
infoWindow ?: Omit < InfoWindowDefinition < InfoWindowOptions > , 'position' > ;
24
26
points : Array < Point > ;
25
27
title : string | null ;
@@ -59,7 +61,12 @@ export default abstract class<
59
61
> extends Controller < HTMLElement > {
60
62
static values = {
61
63
providerOptions : Object ,
62
- view : Object ,
64
+ center : Object ,
65
+ zoom : Number ,
66
+ fitBoundsToMarkers : Boolean ,
67
+ markers : Array ,
68
+ polygons : Array ,
69
+ options : Object ,
63
70
} ;
64
71
65
72
declare centerValue : Point | null ;
@@ -70,9 +77,9 @@ export default abstract class<
70
77
declare optionsValue: MapOptions ;
71
78
72
79
protected map : Map ;
73
- protected markers : Array < Marker > = [ ] ;
80
+ protected markers = new Map < Marker > ( ) ;
74
81
protected infoWindows: Array < InfoWindow > = [ ] ;
75
- protected polygons : Array < Polygon > = [ ] ;
82
+ protected polygons = new Map < Polygon > ( ) ;
76
83
77
84
connect ( ) {
78
85
const options = this . optionsValue ;
@@ -91,8 +98,8 @@ export default abstract class<
91
98
92
99
this . dispatchEvent ( 'connect' , {
93
100
map : this . map ,
94
- markers : this . markers ,
95
- polygons : this . polygons ,
101
+ markers : [ ... this . markers . values ( ) ] ,
102
+ polygons : [ ... this . polygons . values ( ) ] ,
96
103
infoWindows : this . infoWindows ,
97
104
} ) ;
98
105
}
@@ -112,20 +119,29 @@ export default abstract class<
112
119
const marker = this . doCreateMarker ( definition ) ;
113
120
this . dispatchEvent ( 'marker:after-create' , { marker } ) ;
114
121
115
- this . markers . push ( marker ) ;
122
+ marker [ '@id' ] = definition [ '@id' ] ;
123
+
124
+ this . markers . set ( definition [ '@id' ] , marker ) ;
116
125
117
126
return marker ;
118
127
}
119
128
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 {
121
134
this . dispatchEvent ( 'polygon:before-create' , { definition } ) ;
122
135
const polygon = this . doCreatePolygon ( definition ) ;
123
136
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
+
125
142
return polygon ;
126
143
}
127
144
128
- protected abstract doCreateMarker ( definition : MarkerDefinition < MarkerOptions , InfoWindowOptions > ) : Marker ;
129
145
protected abstract doCreatePolygon ( definition : PolygonDefinition < PolygonOptions , InfoWindowOptions > ) : Polygon ;
130
146
131
147
protected createInfoWindow ( {
@@ -162,4 +178,50 @@ export default abstract class<
162
178
protected abstract doFitBoundsToMarkers ( ) : void ;
163
179
164
180
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
+ }
165
227
}
0 commit comments