@@ -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
+ return ;
189
+ }
190
+
191
+ this . markers . forEach ( ( marker ) => {
192
+ if ( ! this . markersValue . find ( ( m ) => m [ '@id' ] === marker [ '@id' ] ) ) {
193
+ this . removeMarker ( marker ) ;
194
+ this . markers . delete ( marker [ '@id' ] ) ;
195
+ }
196
+ } ) ;
197
+
198
+ this . markersValue . forEach ( ( marker ) => {
199
+ if ( ! this . markers . has ( marker [ '@id' ] ) ) {
200
+ this . createMarker ( marker ) ;
201
+ }
202
+ } ) ;
203
+
204
+ if ( this . fitBoundsToMarkersValue ) {
205
+ this . doFitBoundsToMarkers ( ) ;
206
+ }
207
+ }
208
+
209
+ public polygonsValueChanged ( ) : void {
210
+ if ( ! this . map ) {
211
+ return ;
212
+ }
213
+
214
+ this . polygons . forEach ( ( polygon ) => {
215
+ if ( ! this . polygonsValue . find ( ( p ) => p [ '@id' ] === polygon [ '@id' ] ) ) {
216
+ polygon . remove ( ) ;
217
+ this . polygons . delete ( polygon [ '@id' ] ) ;
218
+ }
219
+ } ) ;
220
+
221
+ this . polygonsValue . forEach ( ( polygon ) => {
222
+ if ( ! this . polygons . has ( polygon [ '@id' ] ) ) {
223
+ this . createPolygon ( polygon ) ;
224
+ }
225
+ } ) ;
226
+ }
165
227
}
0 commit comments