@symfony/ux-google-map 2.26.1 → 2.27.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/map_controller.d.ts +15 -10
- package/dist/map_controller.js +150 -69
- package/package.json +2 -2
package/dist/map_controller.d.ts
CHANGED
|
@@ -1,19 +1,16 @@
|
|
|
1
1
|
import type { LoaderOptions } from '@googlemaps/js-api-loader';
|
|
2
|
+
import type { CircleDefinition, Icon, InfoWindowDefinition, MapDefinition, MarkerDefinition, PolygonDefinition, PolylineDefinition, RectangleDefinition } from '@symfony/ux-map';
|
|
2
3
|
import AbstractMapController from '@symfony/ux-map';
|
|
3
|
-
import type { Icon, InfoWindowWithoutPositionDefinition, MarkerDefinition, Point, PolygonDefinition, PolylineDefinition } from '@symfony/ux-map';
|
|
4
4
|
type MapOptions = Pick<google.maps.MapOptions, 'mapId' | 'gestureHandling' | 'backgroundColor' | 'disableDoubleClickZoom' | 'zoomControl' | 'zoomControlOptions' | 'mapTypeControl' | 'mapTypeControlOptions' | 'streetViewControl' | 'streetViewControlOptions' | 'fullscreenControl' | 'fullscreenControlOptions'>;
|
|
5
|
-
export default class extends AbstractMapController<MapOptions, google.maps.Map, google.maps.marker.AdvancedMarkerElementOptions, google.maps.marker.AdvancedMarkerElement, google.maps.InfoWindowOptions, google.maps.InfoWindow, google.maps.PolygonOptions, google.maps.Polygon, google.maps.PolylineOptions, google.maps.Polyline> {
|
|
5
|
+
export default class extends AbstractMapController<MapOptions, google.maps.MapOptions, google.maps.Map, google.maps.marker.AdvancedMarkerElementOptions, google.maps.marker.AdvancedMarkerElement, google.maps.InfoWindowOptions, google.maps.InfoWindow, google.maps.PolygonOptions, google.maps.Polygon, google.maps.PolylineOptions, google.maps.Polyline, google.maps.CircleOptions, google.maps.Circle, google.maps.RectangleOptions, google.maps.Rectangle> {
|
|
6
6
|
providerOptionsValue: Pick<LoaderOptions, 'apiKey' | 'id' | 'language' | 'region' | 'nonce' | 'retries' | 'url' | 'version' | 'libraries'>;
|
|
7
7
|
map: google.maps.Map;
|
|
8
|
-
parser: DOMParser;
|
|
9
8
|
connect(): Promise<void>;
|
|
10
9
|
centerValueChanged(): void;
|
|
11
10
|
zoomValueChanged(): void;
|
|
12
11
|
protected dispatchEvent(name: string, payload?: Record<string, unknown>): void;
|
|
13
|
-
protected doCreateMap({
|
|
14
|
-
|
|
15
|
-
zoom: number | null;
|
|
16
|
-
options: MapOptions;
|
|
12
|
+
protected doCreateMap({ definition }: {
|
|
13
|
+
definition: MapDefinition<MapOptions, google.maps.MapOptions>;
|
|
17
14
|
}): google.maps.Map;
|
|
18
15
|
protected doCreateMarker({ definition, }: {
|
|
19
16
|
definition: MarkerDefinition<google.maps.marker.AdvancedMarkerElementOptions, google.maps.InfoWindowOptions>;
|
|
@@ -27,13 +24,21 @@ export default class extends AbstractMapController<MapOptions, google.maps.Map,
|
|
|
27
24
|
definition: PolylineDefinition<google.maps.PolylineOptions, google.maps.InfoWindowOptions>;
|
|
28
25
|
}): google.maps.Polyline;
|
|
29
26
|
protected doRemovePolyline(polyline: google.maps.Polyline): void;
|
|
27
|
+
protected doCreateCircle({ definition }: {
|
|
28
|
+
definition: CircleDefinition<google.maps.CircleOptions, google.maps.InfoWindowOptions>;
|
|
29
|
+
}): google.maps.Circle;
|
|
30
|
+
protected doRemoveCircle(circle: google.maps.Circle): void;
|
|
31
|
+
protected doCreateRectangle({ definition, }: {
|
|
32
|
+
definition: RectangleDefinition<google.maps.RectangleOptions, google.maps.InfoWindowOptions>;
|
|
33
|
+
}): google.maps.Rectangle;
|
|
34
|
+
protected doRemoveRectangle(rectangle: google.maps.Rectangle): void;
|
|
30
35
|
protected doCreateInfoWindow({ definition, element, }: {
|
|
31
|
-
definition:
|
|
32
|
-
element: google.maps.marker.AdvancedMarkerElement | google.maps.Polygon | google.maps.Polyline;
|
|
36
|
+
definition: Omit<InfoWindowDefinition<google.maps.InfoWindowOptions>, 'position'>;
|
|
37
|
+
element: google.maps.marker.AdvancedMarkerElement | google.maps.Polygon | google.maps.Polyline | google.maps.Circle | google.maps.Rectangle;
|
|
33
38
|
}): google.maps.InfoWindow;
|
|
34
39
|
protected doFitBoundsToMarkers(): void;
|
|
35
40
|
private createTextOrElement;
|
|
36
|
-
protected doCreateIcon({ definition, element
|
|
41
|
+
protected doCreateIcon({ definition, element }: {
|
|
37
42
|
definition: Icon;
|
|
38
43
|
element: google.maps.marker.AdvancedMarkerElement;
|
|
39
44
|
}): void;
|
package/dist/map_controller.js
CHANGED
|
@@ -12,23 +12,31 @@ class default_1 extends Controller {
|
|
|
12
12
|
this.markers = new Map();
|
|
13
13
|
this.polygons = new Map();
|
|
14
14
|
this.polylines = new Map();
|
|
15
|
+
this.circles = new Map();
|
|
16
|
+
this.rectangles = new Map();
|
|
15
17
|
this.infoWindows = [];
|
|
16
18
|
this.isConnected = false;
|
|
17
19
|
}
|
|
18
20
|
connect() {
|
|
19
|
-
const
|
|
20
|
-
|
|
21
|
+
const extra = this.hasExtraValue ? this.extraValue : {};
|
|
22
|
+
const mapDefinition = {
|
|
23
|
+
center: this.hasCenterValue ? this.centerValue : null,
|
|
24
|
+
zoom: this.hasZoomValue ? this.zoomValue : null,
|
|
25
|
+
options: this.optionsValue,
|
|
26
|
+
extra,
|
|
27
|
+
};
|
|
28
|
+
this.dispatchEvent('pre-connect', mapDefinition);
|
|
21
29
|
this.createMarker = this.createDrawingFactory('marker', this.markers, this.doCreateMarker.bind(this));
|
|
22
30
|
this.createPolygon = this.createDrawingFactory('polygon', this.polygons, this.doCreatePolygon.bind(this));
|
|
23
31
|
this.createPolyline = this.createDrawingFactory('polyline', this.polylines, this.doCreatePolyline.bind(this));
|
|
24
|
-
this.
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
options,
|
|
28
|
-
});
|
|
32
|
+
this.createCircle = this.createDrawingFactory('circle', this.circles, this.doCreateCircle.bind(this));
|
|
33
|
+
this.createRectangle = this.createDrawingFactory('rectangle', this.rectangles, this.doCreateRectangle.bind(this));
|
|
34
|
+
this.map = this.doCreateMap({ definition: mapDefinition });
|
|
29
35
|
this.markersValue.forEach((definition) => this.createMarker({ definition }));
|
|
30
36
|
this.polygonsValue.forEach((definition) => this.createPolygon({ definition }));
|
|
31
37
|
this.polylinesValue.forEach((definition) => this.createPolyline({ definition }));
|
|
38
|
+
this.circlesValue.forEach((definition) => this.createCircle({ definition }));
|
|
39
|
+
this.rectanglesValue.forEach((definition) => this.createRectangle({ definition }));
|
|
32
40
|
if (this.fitBoundsToMarkersValue) {
|
|
33
41
|
this.doFitBoundsToMarkers();
|
|
34
42
|
}
|
|
@@ -37,7 +45,10 @@ class default_1 extends Controller {
|
|
|
37
45
|
markers: [...this.markers.values()],
|
|
38
46
|
polygons: [...this.polygons.values()],
|
|
39
47
|
polylines: [...this.polylines.values()],
|
|
48
|
+
circles: [...this.circles.values()],
|
|
49
|
+
rectangles: [...this.rectangles.values()],
|
|
40
50
|
infoWindows: this.infoWindows,
|
|
51
|
+
extra,
|
|
41
52
|
});
|
|
42
53
|
this.isConnected = true;
|
|
43
54
|
}
|
|
@@ -69,11 +80,26 @@ class default_1 extends Controller {
|
|
|
69
80
|
}
|
|
70
81
|
this.onDrawChanged(this.polylines, this.polylinesValue, this.createPolyline, this.doRemovePolyline);
|
|
71
82
|
}
|
|
83
|
+
circlesValueChanged() {
|
|
84
|
+
if (!this.isConnected) {
|
|
85
|
+
return;
|
|
86
|
+
}
|
|
87
|
+
this.onDrawChanged(this.circles, this.circlesValue, this.createCircle, this.doRemoveCircle);
|
|
88
|
+
}
|
|
89
|
+
rectanglesValueChanged() {
|
|
90
|
+
if (!this.isConnected) {
|
|
91
|
+
return;
|
|
92
|
+
}
|
|
93
|
+
this.onDrawChanged(this.rectangles, this.rectanglesValue, this.createRectangle, this.doRemoveRectangle);
|
|
94
|
+
}
|
|
72
95
|
createDrawingFactory(type, draws, factory) {
|
|
73
96
|
const eventBefore = `${type}:before-create`;
|
|
74
97
|
const eventAfter = `${type}:after-create`;
|
|
75
98
|
return ({ definition }) => {
|
|
76
99
|
this.dispatchEvent(eventBefore, { definition });
|
|
100
|
+
if (typeof definition.rawOptions !== 'undefined') {
|
|
101
|
+
console.warn(`[Symfony UX Map] The event "${eventBefore}" added a deprecated "rawOptions" property to the definition, it will be removed in a next major version, replace it with "bridgeOptions" instead.`, definition);
|
|
102
|
+
}
|
|
77
103
|
const drawing = factory({ definition });
|
|
78
104
|
this.dispatchEvent(eventAfter, { [type]: drawing, definition });
|
|
79
105
|
draws.set(definition['@id'], drawing);
|
|
@@ -105,34 +131,51 @@ default_1.values = {
|
|
|
105
131
|
markers: Array,
|
|
106
132
|
polygons: Array,
|
|
107
133
|
polylines: Array,
|
|
134
|
+
circles: Array,
|
|
135
|
+
rectangles: Array,
|
|
108
136
|
options: Object,
|
|
137
|
+
extra: Object,
|
|
109
138
|
};
|
|
110
139
|
|
|
111
140
|
let _google;
|
|
141
|
+
let _loading = false;
|
|
142
|
+
let _loaded = false;
|
|
143
|
+
let _onLoadedCallbacks = [];
|
|
112
144
|
const parser = new DOMParser();
|
|
113
145
|
class map_controller extends default_1 {
|
|
114
146
|
async connect() {
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
return;
|
|
124
|
-
}
|
|
125
|
-
const library = libraries[index];
|
|
126
|
-
if (['marker', 'places', 'geometry', 'journeySharing', 'drawing', 'visualization'].includes(library)) {
|
|
127
|
-
_google.maps[library] = libraryImplementation;
|
|
128
|
-
}
|
|
129
|
-
else {
|
|
130
|
-
_google.maps = { ..._google.maps, ...libraryImplementation };
|
|
131
|
-
}
|
|
132
|
-
});
|
|
147
|
+
const onLoaded = () => super.connect();
|
|
148
|
+
if (_loaded) {
|
|
149
|
+
onLoaded();
|
|
150
|
+
return;
|
|
151
|
+
}
|
|
152
|
+
if (_loading) {
|
|
153
|
+
_onLoadedCallbacks.push(onLoaded);
|
|
154
|
+
return;
|
|
133
155
|
}
|
|
134
|
-
|
|
135
|
-
|
|
156
|
+
_loading = true;
|
|
157
|
+
_google = { maps: {} };
|
|
158
|
+
let { libraries = [], ...loaderOptions } = this.providerOptionsValue;
|
|
159
|
+
const loader = new Loader(loaderOptions);
|
|
160
|
+
libraries = ['core', ...libraries.filter((library) => library !== 'core')];
|
|
161
|
+
const librariesImplementations = await Promise.all(libraries.map((library) => loader.importLibrary(library)));
|
|
162
|
+
librariesImplementations.map((libraryImplementation, index) => {
|
|
163
|
+
if (typeof libraryImplementation !== 'object' || libraryImplementation === null) {
|
|
164
|
+
return;
|
|
165
|
+
}
|
|
166
|
+
const library = libraries[index];
|
|
167
|
+
if (['marker', 'places', 'geometry', 'journeySharing', 'drawing', 'visualization'].includes(library)) {
|
|
168
|
+
_google.maps[library] = libraryImplementation;
|
|
169
|
+
}
|
|
170
|
+
else {
|
|
171
|
+
_google.maps = { ..._google.maps, ...libraryImplementation };
|
|
172
|
+
}
|
|
173
|
+
});
|
|
174
|
+
_loading = false;
|
|
175
|
+
_loaded = true;
|
|
176
|
+
onLoaded();
|
|
177
|
+
_onLoadedCallbacks.forEach((callback) => callback());
|
|
178
|
+
_onLoadedCallbacks = [];
|
|
136
179
|
}
|
|
137
180
|
centerValueChanged() {
|
|
138
181
|
if (this.map && this.hasCenterValue && this.centerValue) {
|
|
@@ -145,33 +188,33 @@ class map_controller extends default_1 {
|
|
|
145
188
|
}
|
|
146
189
|
}
|
|
147
190
|
dispatchEvent(name, payload = {}) {
|
|
191
|
+
payload.google = _google;
|
|
148
192
|
this.dispatch(name, {
|
|
149
193
|
prefix: 'ux:map',
|
|
150
|
-
detail:
|
|
151
|
-
...payload,
|
|
152
|
-
google: _google,
|
|
153
|
-
},
|
|
194
|
+
detail: payload,
|
|
154
195
|
});
|
|
155
196
|
}
|
|
156
|
-
doCreateMap({
|
|
197
|
+
doCreateMap({ definition }) {
|
|
198
|
+
const { center, zoom, options, bridgeOptions = {} } = definition;
|
|
157
199
|
options.zoomControl = typeof options.zoomControlOptions !== 'undefined';
|
|
158
200
|
options.mapTypeControl = typeof options.mapTypeControlOptions !== 'undefined';
|
|
159
201
|
options.streetViewControl = typeof options.streetViewControlOptions !== 'undefined';
|
|
160
202
|
options.fullscreenControl = typeof options.fullscreenControlOptions !== 'undefined';
|
|
161
203
|
return new _google.maps.Map(this.element, {
|
|
162
|
-
...options,
|
|
163
204
|
center,
|
|
164
205
|
zoom,
|
|
206
|
+
...options,
|
|
207
|
+
...bridgeOptions,
|
|
165
208
|
});
|
|
166
209
|
}
|
|
167
210
|
doCreateMarker({ definition, }) {
|
|
168
|
-
const { '@id': _id, position, title, infoWindow, icon,
|
|
211
|
+
const { '@id': _id, position, title, infoWindow, icon, rawOptions = {}, bridgeOptions = {} } = definition;
|
|
169
212
|
const marker = new _google.maps.marker.AdvancedMarkerElement({
|
|
170
213
|
position,
|
|
171
214
|
title,
|
|
172
|
-
...otherOptions,
|
|
173
|
-
...rawOptions,
|
|
174
215
|
map: this.map,
|
|
216
|
+
...rawOptions,
|
|
217
|
+
...bridgeOptions,
|
|
175
218
|
});
|
|
176
219
|
if (infoWindow) {
|
|
177
220
|
this.createInfoWindow({ definition: infoWindow, element: marker });
|
|
@@ -185,11 +228,12 @@ class map_controller extends default_1 {
|
|
|
185
228
|
marker.map = null;
|
|
186
229
|
}
|
|
187
230
|
doCreatePolygon({ definition, }) {
|
|
188
|
-
const { '@id': _id, points, title, infoWindow, rawOptions = {} } = definition;
|
|
231
|
+
const { '@id': _id, points, title, infoWindow, rawOptions = {}, bridgeOptions = {} } = definition;
|
|
189
232
|
const polygon = new _google.maps.Polygon({
|
|
190
|
-
...rawOptions,
|
|
191
233
|
paths: points,
|
|
192
234
|
map: this.map,
|
|
235
|
+
...rawOptions,
|
|
236
|
+
...bridgeOptions,
|
|
193
237
|
});
|
|
194
238
|
if (title) {
|
|
195
239
|
polygon.set('title', title);
|
|
@@ -203,11 +247,12 @@ class map_controller extends default_1 {
|
|
|
203
247
|
polygon.setMap(null);
|
|
204
248
|
}
|
|
205
249
|
doCreatePolyline({ definition, }) {
|
|
206
|
-
const { '@id': _id, points, title, infoWindow, rawOptions = {} } = definition;
|
|
250
|
+
const { '@id': _id, points, title, infoWindow, rawOptions = {}, bridgeOptions = {} } = definition;
|
|
207
251
|
const polyline = new _google.maps.Polyline({
|
|
208
|
-
...rawOptions,
|
|
209
252
|
path: points,
|
|
210
253
|
map: this.map,
|
|
254
|
+
...rawOptions,
|
|
255
|
+
...bridgeOptions,
|
|
211
256
|
});
|
|
212
257
|
if (title) {
|
|
213
258
|
polyline.set('title', title);
|
|
@@ -220,41 +265,77 @@ class map_controller extends default_1 {
|
|
|
220
265
|
doRemovePolyline(polyline) {
|
|
221
266
|
polyline.setMap(null);
|
|
222
267
|
}
|
|
268
|
+
doCreateCircle({ definition }) {
|
|
269
|
+
const { '@id': _id, center, radius, title, infoWindow, rawOptions = {}, bridgeOptions = {} } = definition;
|
|
270
|
+
const circle = new _google.maps.Circle({
|
|
271
|
+
center,
|
|
272
|
+
radius,
|
|
273
|
+
map: this.map,
|
|
274
|
+
...rawOptions,
|
|
275
|
+
...bridgeOptions,
|
|
276
|
+
});
|
|
277
|
+
if (title) {
|
|
278
|
+
circle.set('title', title);
|
|
279
|
+
}
|
|
280
|
+
if (infoWindow) {
|
|
281
|
+
this.createInfoWindow({ definition: infoWindow, element: circle });
|
|
282
|
+
}
|
|
283
|
+
return circle;
|
|
284
|
+
}
|
|
285
|
+
doRemoveCircle(circle) {
|
|
286
|
+
circle.setMap(null);
|
|
287
|
+
}
|
|
288
|
+
doCreateRectangle({ definition, }) {
|
|
289
|
+
const { northEast, southWest, title, infoWindow, rawOptions = {}, bridgeOptions = {} } = definition;
|
|
290
|
+
const rectangle = new _google.maps.Rectangle({
|
|
291
|
+
bounds: new _google.maps.LatLngBounds(southWest, northEast),
|
|
292
|
+
map: this.map,
|
|
293
|
+
...rawOptions,
|
|
294
|
+
...bridgeOptions,
|
|
295
|
+
});
|
|
296
|
+
if (title) {
|
|
297
|
+
rectangle.set('title', title);
|
|
298
|
+
}
|
|
299
|
+
if (infoWindow) {
|
|
300
|
+
this.createInfoWindow({ definition: infoWindow, element: rectangle });
|
|
301
|
+
}
|
|
302
|
+
return rectangle;
|
|
303
|
+
}
|
|
304
|
+
doRemoveRectangle(rectangle) {
|
|
305
|
+
rectangle.setMap(null);
|
|
306
|
+
}
|
|
223
307
|
doCreateInfoWindow({ definition, element, }) {
|
|
224
|
-
const { headerContent, content,
|
|
225
|
-
|
|
308
|
+
const { headerContent, content, opened, autoClose, rawOptions = {}, bridgeOptions = {} } = definition;
|
|
309
|
+
let position = null;
|
|
310
|
+
if (element instanceof google.maps.Circle) {
|
|
311
|
+
position = element.getCenter();
|
|
312
|
+
}
|
|
313
|
+
else if (element instanceof google.maps.Rectangle) {
|
|
314
|
+
position = element.getBounds()?.getCenter() || null;
|
|
315
|
+
}
|
|
316
|
+
else if (element instanceof google.maps.Polygon || element instanceof google.maps.Polyline) ;
|
|
317
|
+
const infoWindowOptions = {
|
|
226
318
|
headerContent: this.createTextOrElement(headerContent),
|
|
227
319
|
content: this.createTextOrElement(content),
|
|
228
|
-
|
|
320
|
+
position,
|
|
229
321
|
...rawOptions,
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
infoWindow.open({ map: this.map, anchor: element });
|
|
237
|
-
});
|
|
238
|
-
if (definition.opened) {
|
|
239
|
-
infoWindow.open({ map: this.map, anchor: element });
|
|
322
|
+
...bridgeOptions,
|
|
323
|
+
};
|
|
324
|
+
const infoWindow = new _google.maps.InfoWindow(infoWindowOptions);
|
|
325
|
+
element.addListener('click', (event) => {
|
|
326
|
+
if (autoClose) {
|
|
327
|
+
this.closeInfoWindowsExcept(infoWindow);
|
|
240
328
|
}
|
|
241
|
-
|
|
242
|
-
else if (element instanceof google.maps.Polygon) {
|
|
243
|
-
element.addListener('click', (event) => {
|
|
244
|
-
if (definition.autoClose) {
|
|
245
|
-
this.closeInfoWindowsExcept(infoWindow);
|
|
246
|
-
}
|
|
329
|
+
if (infoWindowOptions.position === null) {
|
|
247
330
|
infoWindow.setPosition(event.latLng);
|
|
248
|
-
infoWindow.open(this.map);
|
|
249
|
-
});
|
|
250
|
-
if (definition.opened) {
|
|
251
|
-
const bounds = new google.maps.LatLngBounds();
|
|
252
|
-
element.getPath().forEach((point) => {
|
|
253
|
-
bounds.extend(point);
|
|
254
|
-
});
|
|
255
|
-
infoWindow.setPosition(bounds.getCenter());
|
|
256
|
-
infoWindow.open({ map: this.map, anchor: element });
|
|
257
331
|
}
|
|
332
|
+
infoWindow.open({ map: this.map, anchor: element });
|
|
333
|
+
});
|
|
334
|
+
if (opened) {
|
|
335
|
+
if (autoClose) {
|
|
336
|
+
this.closeInfoWindowsExcept(infoWindow);
|
|
337
|
+
}
|
|
338
|
+
infoWindow.open({ map: this.map, anchor: element });
|
|
258
339
|
}
|
|
259
340
|
return infoWindow;
|
|
260
341
|
}
|
|
@@ -282,7 +363,7 @@ class map_controller extends default_1 {
|
|
|
282
363
|
}
|
|
283
364
|
return content;
|
|
284
365
|
}
|
|
285
|
-
doCreateIcon({ definition, element
|
|
366
|
+
doCreateIcon({ definition, element }) {
|
|
286
367
|
const { type, width, height } = definition;
|
|
287
368
|
if (type === IconTypes.Svg) {
|
|
288
369
|
element.content = parser.parseFromString(definition.html, 'image/svg+xml').documentElement;
|
package/package.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"name": "@symfony/ux-google-map",
|
|
3
3
|
"description": "GoogleMaps bridge for Symfony UX Map, integrate interactive maps in your Symfony applications",
|
|
4
4
|
"license": "MIT",
|
|
5
|
-
"version": "2.
|
|
5
|
+
"version": "2.27.0",
|
|
6
6
|
"keywords": [
|
|
7
7
|
"symfony-ux",
|
|
8
8
|
"google-maps",
|
|
@@ -50,7 +50,7 @@
|
|
|
50
50
|
"devDependencies": {
|
|
51
51
|
"@googlemaps/js-api-loader": "^1.16.6",
|
|
52
52
|
"@hotwired/stimulus": "^3.0.0",
|
|
53
|
-
"@symfony/ux-map": "2.
|
|
53
|
+
"@symfony/ux-map": "2.27.0",
|
|
54
54
|
"@types/google.maps": "^3.55.9"
|
|
55
55
|
}
|
|
56
56
|
}
|