@symfony/ux-leaflet-map 2.26.0 → 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 +31 -13
- package/dist/map_controller.js +114 -25
- package/package.json +2 -2
package/dist/map_controller.d.ts
CHANGED
|
@@ -1,46 +1,64 @@
|
|
|
1
|
+
import type { CircleDefinition, Icon, InfoWindowDefinition, MapDefinition, MarkerDefinition, PolygonDefinition, PolylineDefinition, RectangleDefinition } from '@symfony/ux-map';
|
|
1
2
|
import AbstractMapController from '@symfony/ux-map';
|
|
2
|
-
import type { Icon, InfoWindowWithoutPositionDefinition, MarkerDefinition, Point, PolygonDefinition, PolylineDefinition } from '@symfony/ux-map';
|
|
3
3
|
import 'leaflet/dist/leaflet.min.css';
|
|
4
|
+
import type { CircleOptions, ControlPosition, MapOptions as LeafletMapOptions, MarkerOptions, PolylineOptions as PolygonOptions, PolylineOptions, PopupOptions, PolylineOptions as RectangleOptions } from 'leaflet';
|
|
4
5
|
import * as L from 'leaflet';
|
|
5
|
-
|
|
6
|
-
|
|
6
|
+
type MapOptions = Pick<LeafletMapOptions, 'attributionControl' | 'zoomControl'> & {
|
|
7
|
+
attributionControlOptions?: {
|
|
8
|
+
position: ControlPosition;
|
|
9
|
+
prefix: string | false;
|
|
10
|
+
};
|
|
11
|
+
zoomControlOptions?: {
|
|
12
|
+
position: ControlPosition;
|
|
13
|
+
zoomInText: string;
|
|
14
|
+
zoomInTitle: string;
|
|
15
|
+
zoomOutText: string;
|
|
16
|
+
zoomOutTitle: string;
|
|
17
|
+
};
|
|
7
18
|
tileLayer: {
|
|
8
19
|
url: string;
|
|
9
20
|
attribution: string;
|
|
10
21
|
options: Record<string, unknown>;
|
|
11
22
|
} | false;
|
|
12
23
|
};
|
|
13
|
-
export default class extends AbstractMapController<MapOptions, L.Map, MarkerOptions, L.Marker, PopupOptions, L.Popup, PolygonOptions, L.Polygon, PolylineOptions, L.Polyline> {
|
|
24
|
+
export default class extends AbstractMapController<MapOptions, LeafletMapOptions, L.Map, MarkerOptions, L.Marker, PopupOptions, L.Popup, PolygonOptions, L.Polygon, PolylineOptions, L.Polyline, CircleOptions, L.Circle, RectangleOptions, L.Rectangle> {
|
|
14
25
|
map: L.Map;
|
|
15
26
|
connect(): void;
|
|
16
27
|
centerValueChanged(): void;
|
|
17
28
|
zoomValueChanged(): void;
|
|
18
29
|
protected dispatchEvent(name: string, payload?: Record<string, unknown>): void;
|
|
19
|
-
protected doCreateMap({
|
|
20
|
-
|
|
21
|
-
zoom: number | null;
|
|
22
|
-
options: MapOptions;
|
|
30
|
+
protected doCreateMap({ definition }: {
|
|
31
|
+
definition: MapDefinition<MapOptions, LeafletMapOptions>;
|
|
23
32
|
}): L.Map;
|
|
24
33
|
protected doCreateMarker({ definition }: {
|
|
25
34
|
definition: MarkerDefinition<MarkerOptions, PopupOptions>;
|
|
26
35
|
}): L.Marker;
|
|
27
36
|
protected doRemoveMarker(marker: L.Marker): void;
|
|
28
|
-
protected doCreatePolygon({ definition
|
|
37
|
+
protected doCreatePolygon({ definition }: {
|
|
29
38
|
definition: PolygonDefinition<PolygonOptions, PopupOptions>;
|
|
30
39
|
}): L.Polygon;
|
|
31
40
|
protected doRemovePolygon(polygon: L.Polygon): void;
|
|
32
|
-
protected doCreatePolyline({ definition
|
|
41
|
+
protected doCreatePolyline({ definition }: {
|
|
33
42
|
definition: PolylineDefinition<PolylineOptions, PopupOptions>;
|
|
34
43
|
}): L.Polyline;
|
|
35
44
|
protected doRemovePolyline(polyline: L.Polyline): void;
|
|
45
|
+
protected doCreateCircle({ definition }: {
|
|
46
|
+
definition: CircleDefinition<CircleOptions, PopupOptions>;
|
|
47
|
+
}): L.Circle;
|
|
48
|
+
protected doRemoveCircle(circle: L.Circle): void;
|
|
49
|
+
protected doCreateRectangle({ definition }: {
|
|
50
|
+
definition: RectangleDefinition<RectangleOptions, PopupOptions>;
|
|
51
|
+
}): L.Rectangle;
|
|
52
|
+
protected doRemoveRectangle(rectangle: L.Rectangle): void;
|
|
36
53
|
protected doCreateInfoWindow({ definition, element, }: {
|
|
37
|
-
definition:
|
|
38
|
-
element: L.Marker | L.Polygon | L.Polyline;
|
|
54
|
+
definition: Omit<InfoWindowDefinition<PopupOptions>, 'position'>;
|
|
55
|
+
element: L.Marker | L.Polygon | L.Polyline | L.Circle | L.Rectangle;
|
|
39
56
|
}): L.Popup;
|
|
40
|
-
protected doCreateIcon({ definition, element
|
|
57
|
+
protected doCreateIcon({ definition, element }: {
|
|
41
58
|
definition: Icon;
|
|
42
59
|
element: L.Marker;
|
|
43
60
|
}): void;
|
|
44
61
|
protected doFitBoundsToMarkers(): void;
|
|
62
|
+
private closePopups;
|
|
45
63
|
}
|
|
46
64
|
export {};
|
package/dist/map_controller.js
CHANGED
|
@@ -13,23 +13,31 @@ class default_1 extends Controller {
|
|
|
13
13
|
this.markers = new Map();
|
|
14
14
|
this.polygons = new Map();
|
|
15
15
|
this.polylines = new Map();
|
|
16
|
+
this.circles = new Map();
|
|
17
|
+
this.rectangles = new Map();
|
|
16
18
|
this.infoWindows = [];
|
|
17
19
|
this.isConnected = false;
|
|
18
20
|
}
|
|
19
21
|
connect() {
|
|
20
|
-
const
|
|
21
|
-
|
|
22
|
+
const extra = this.hasExtraValue ? this.extraValue : {};
|
|
23
|
+
const mapDefinition = {
|
|
24
|
+
center: this.hasCenterValue ? this.centerValue : null,
|
|
25
|
+
zoom: this.hasZoomValue ? this.zoomValue : null,
|
|
26
|
+
options: this.optionsValue,
|
|
27
|
+
extra,
|
|
28
|
+
};
|
|
29
|
+
this.dispatchEvent('pre-connect', mapDefinition);
|
|
22
30
|
this.createMarker = this.createDrawingFactory('marker', this.markers, this.doCreateMarker.bind(this));
|
|
23
31
|
this.createPolygon = this.createDrawingFactory('polygon', this.polygons, this.doCreatePolygon.bind(this));
|
|
24
32
|
this.createPolyline = this.createDrawingFactory('polyline', this.polylines, this.doCreatePolyline.bind(this));
|
|
25
|
-
this.
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
options,
|
|
29
|
-
});
|
|
33
|
+
this.createCircle = this.createDrawingFactory('circle', this.circles, this.doCreateCircle.bind(this));
|
|
34
|
+
this.createRectangle = this.createDrawingFactory('rectangle', this.rectangles, this.doCreateRectangle.bind(this));
|
|
35
|
+
this.map = this.doCreateMap({ definition: mapDefinition });
|
|
30
36
|
this.markersValue.forEach((definition) => this.createMarker({ definition }));
|
|
31
37
|
this.polygonsValue.forEach((definition) => this.createPolygon({ definition }));
|
|
32
38
|
this.polylinesValue.forEach((definition) => this.createPolyline({ definition }));
|
|
39
|
+
this.circlesValue.forEach((definition) => this.createCircle({ definition }));
|
|
40
|
+
this.rectanglesValue.forEach((definition) => this.createRectangle({ definition }));
|
|
33
41
|
if (this.fitBoundsToMarkersValue) {
|
|
34
42
|
this.doFitBoundsToMarkers();
|
|
35
43
|
}
|
|
@@ -38,7 +46,10 @@ class default_1 extends Controller {
|
|
|
38
46
|
markers: [...this.markers.values()],
|
|
39
47
|
polygons: [...this.polygons.values()],
|
|
40
48
|
polylines: [...this.polylines.values()],
|
|
49
|
+
circles: [...this.circles.values()],
|
|
50
|
+
rectangles: [...this.rectangles.values()],
|
|
41
51
|
infoWindows: this.infoWindows,
|
|
52
|
+
extra,
|
|
42
53
|
});
|
|
43
54
|
this.isConnected = true;
|
|
44
55
|
}
|
|
@@ -70,11 +81,26 @@ class default_1 extends Controller {
|
|
|
70
81
|
}
|
|
71
82
|
this.onDrawChanged(this.polylines, this.polylinesValue, this.createPolyline, this.doRemovePolyline);
|
|
72
83
|
}
|
|
84
|
+
circlesValueChanged() {
|
|
85
|
+
if (!this.isConnected) {
|
|
86
|
+
return;
|
|
87
|
+
}
|
|
88
|
+
this.onDrawChanged(this.circles, this.circlesValue, this.createCircle, this.doRemoveCircle);
|
|
89
|
+
}
|
|
90
|
+
rectanglesValueChanged() {
|
|
91
|
+
if (!this.isConnected) {
|
|
92
|
+
return;
|
|
93
|
+
}
|
|
94
|
+
this.onDrawChanged(this.rectangles, this.rectanglesValue, this.createRectangle, this.doRemoveRectangle);
|
|
95
|
+
}
|
|
73
96
|
createDrawingFactory(type, draws, factory) {
|
|
74
97
|
const eventBefore = `${type}:before-create`;
|
|
75
98
|
const eventAfter = `${type}:after-create`;
|
|
76
99
|
return ({ definition }) => {
|
|
77
100
|
this.dispatchEvent(eventBefore, { definition });
|
|
101
|
+
if (typeof definition.rawOptions !== 'undefined') {
|
|
102
|
+
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);
|
|
103
|
+
}
|
|
78
104
|
const drawing = factory({ definition });
|
|
79
105
|
this.dispatchEvent(eventAfter, { [type]: drawing, definition });
|
|
80
106
|
draws.set(definition['@id'], drawing);
|
|
@@ -106,7 +132,10 @@ default_1.values = {
|
|
|
106
132
|
markers: Array,
|
|
107
133
|
polygons: Array,
|
|
108
134
|
polylines: Array,
|
|
135
|
+
circles: Array,
|
|
136
|
+
rectangles: Array,
|
|
109
137
|
options: Object,
|
|
138
|
+
extra: Object,
|
|
110
139
|
};
|
|
111
140
|
|
|
112
141
|
class map_controller extends default_1 {
|
|
@@ -131,19 +160,21 @@ class map_controller extends default_1 {
|
|
|
131
160
|
}
|
|
132
161
|
}
|
|
133
162
|
dispatchEvent(name, payload = {}) {
|
|
163
|
+
payload.L = L;
|
|
134
164
|
this.dispatch(name, {
|
|
135
165
|
prefix: 'ux:map',
|
|
136
|
-
detail:
|
|
137
|
-
...payload,
|
|
138
|
-
L,
|
|
139
|
-
},
|
|
166
|
+
detail: payload,
|
|
140
167
|
});
|
|
141
168
|
}
|
|
142
|
-
doCreateMap({
|
|
169
|
+
doCreateMap({ definition }) {
|
|
170
|
+
const { center, zoom, options, bridgeOptions = {} } = definition;
|
|
143
171
|
const map = L.map(this.element, {
|
|
144
|
-
...options,
|
|
145
172
|
center: center === null ? undefined : center,
|
|
146
173
|
zoom: zoom === null ? undefined : zoom,
|
|
174
|
+
attributionControl: false,
|
|
175
|
+
zoomControl: false,
|
|
176
|
+
...options,
|
|
177
|
+
...bridgeOptions,
|
|
147
178
|
});
|
|
148
179
|
if (options.tileLayer) {
|
|
149
180
|
L.tileLayer(options.tileLayer.url, {
|
|
@@ -151,11 +182,22 @@ class map_controller extends default_1 {
|
|
|
151
182
|
...options.tileLayer.options,
|
|
152
183
|
}).addTo(map);
|
|
153
184
|
}
|
|
185
|
+
if (typeof options.attributionControlOptions !== 'undefined') {
|
|
186
|
+
L.control.attribution({ ...options.attributionControlOptions }).addTo(map);
|
|
187
|
+
}
|
|
188
|
+
if (typeof options.zoomControlOptions !== 'undefined') {
|
|
189
|
+
L.control.zoom({ ...options.zoomControlOptions }).addTo(map);
|
|
190
|
+
}
|
|
154
191
|
return map;
|
|
155
192
|
}
|
|
156
193
|
doCreateMarker({ definition }) {
|
|
157
|
-
const { '@id': _id, position, title, infoWindow, icon,
|
|
158
|
-
const marker = L.marker(position, {
|
|
194
|
+
const { '@id': _id, position, title, infoWindow, icon, rawOptions = {}, bridgeOptions = {} } = definition;
|
|
195
|
+
const marker = L.marker(position, {
|
|
196
|
+
title: title || undefined,
|
|
197
|
+
...rawOptions,
|
|
198
|
+
...bridgeOptions,
|
|
199
|
+
riseOnHover: true,
|
|
200
|
+
}).addTo(this.map);
|
|
159
201
|
if (infoWindow) {
|
|
160
202
|
this.createInfoWindow({ definition: infoWindow, element: marker });
|
|
161
203
|
}
|
|
@@ -167,9 +209,9 @@ class map_controller extends default_1 {
|
|
|
167
209
|
doRemoveMarker(marker) {
|
|
168
210
|
marker.remove();
|
|
169
211
|
}
|
|
170
|
-
doCreatePolygon({ definition
|
|
171
|
-
const { '@id': _id, points, title, infoWindow, rawOptions = {} } = definition;
|
|
172
|
-
const polygon = L.polygon(points, { ...rawOptions }).addTo(this.map);
|
|
212
|
+
doCreatePolygon({ definition }) {
|
|
213
|
+
const { '@id': _id, points, title, infoWindow, rawOptions = {}, bridgeOptions = {} } = definition;
|
|
214
|
+
const polygon = L.polygon(points, { ...rawOptions, ...bridgeOptions }).addTo(this.map);
|
|
173
215
|
if (title) {
|
|
174
216
|
polygon.bindPopup(title);
|
|
175
217
|
}
|
|
@@ -181,9 +223,9 @@ class map_controller extends default_1 {
|
|
|
181
223
|
doRemovePolygon(polygon) {
|
|
182
224
|
polygon.remove();
|
|
183
225
|
}
|
|
184
|
-
doCreatePolyline({ definition
|
|
185
|
-
const { '@id': _id, points, title, infoWindow, rawOptions = {} } = definition;
|
|
186
|
-
const polyline = L.polyline(points, { ...rawOptions }).addTo(this.map);
|
|
226
|
+
doCreatePolyline({ definition }) {
|
|
227
|
+
const { '@id': _id, points, title, infoWindow, rawOptions = {}, bridgeOptions = {} } = definition;
|
|
228
|
+
const polyline = L.polyline(points, { ...rawOptions, ...bridgeOptions }).addTo(this.map);
|
|
187
229
|
if (title) {
|
|
188
230
|
polyline.bindPopup(title);
|
|
189
231
|
}
|
|
@@ -195,19 +237,58 @@ class map_controller extends default_1 {
|
|
|
195
237
|
doRemovePolyline(polyline) {
|
|
196
238
|
polyline.remove();
|
|
197
239
|
}
|
|
240
|
+
doCreateCircle({ definition }) {
|
|
241
|
+
const { '@id': _id, center, radius, title, infoWindow, rawOptions = {}, bridgeOptions = {} } = definition;
|
|
242
|
+
const circle = L.circle(center, { radius, ...rawOptions, ...bridgeOptions }).addTo(this.map);
|
|
243
|
+
if (title) {
|
|
244
|
+
circle.bindPopup(title);
|
|
245
|
+
}
|
|
246
|
+
if (infoWindow) {
|
|
247
|
+
this.createInfoWindow({ definition: infoWindow, element: circle });
|
|
248
|
+
}
|
|
249
|
+
return circle;
|
|
250
|
+
}
|
|
251
|
+
doRemoveCircle(circle) {
|
|
252
|
+
circle.remove();
|
|
253
|
+
}
|
|
254
|
+
doCreateRectangle({ definition }) {
|
|
255
|
+
const { '@id': _id, southWest, northEast, title, infoWindow, rawOptions = {}, bridgeOptions = {} } = definition;
|
|
256
|
+
const rectangle = L.rectangle([
|
|
257
|
+
[southWest.lat, southWest.lng],
|
|
258
|
+
[northEast.lat, northEast.lng],
|
|
259
|
+
], { ...rawOptions, ...bridgeOptions }).addTo(this.map);
|
|
260
|
+
if (title) {
|
|
261
|
+
rectangle.bindPopup(title);
|
|
262
|
+
}
|
|
263
|
+
if (infoWindow) {
|
|
264
|
+
this.createInfoWindow({ definition: infoWindow, element: rectangle });
|
|
265
|
+
}
|
|
266
|
+
return rectangle;
|
|
267
|
+
}
|
|
268
|
+
doRemoveRectangle(rectangle) {
|
|
269
|
+
rectangle.remove();
|
|
270
|
+
}
|
|
198
271
|
doCreateInfoWindow({ definition, element, }) {
|
|
199
|
-
const { headerContent, content, rawOptions = {},
|
|
200
|
-
element.bindPopup([headerContent, content].filter((x) => x).join('<br>'), { ...
|
|
201
|
-
if (
|
|
272
|
+
const { headerContent, content, opened, autoClose, rawOptions = {}, bridgeOptions = {} } = definition;
|
|
273
|
+
element.bindPopup([headerContent, content].filter((x) => x).join('<br>'), { ...rawOptions, ...bridgeOptions });
|
|
274
|
+
if (opened) {
|
|
275
|
+
if (autoClose) {
|
|
276
|
+
this.closePopups();
|
|
277
|
+
}
|
|
202
278
|
element.openPopup();
|
|
203
279
|
}
|
|
204
280
|
const popup = element.getPopup();
|
|
205
281
|
if (!popup) {
|
|
206
282
|
throw new Error('Unable to get the Popup associated with the element.');
|
|
207
283
|
}
|
|
284
|
+
popup.on('click', () => {
|
|
285
|
+
if (autoClose) {
|
|
286
|
+
this.closePopups({ except: popup });
|
|
287
|
+
}
|
|
288
|
+
});
|
|
208
289
|
return popup;
|
|
209
290
|
}
|
|
210
|
-
doCreateIcon({ definition, element
|
|
291
|
+
doCreateIcon({ definition, element }) {
|
|
211
292
|
const { type, width, height } = definition;
|
|
212
293
|
let icon;
|
|
213
294
|
if (type === IconTypes.Svg) {
|
|
@@ -247,6 +328,14 @@ class map_controller extends default_1 {
|
|
|
247
328
|
});
|
|
248
329
|
this.map.fitBounds(bounds);
|
|
249
330
|
}
|
|
331
|
+
closePopups(options = {}) {
|
|
332
|
+
this.infoWindows.forEach((popup) => {
|
|
333
|
+
if (options.except && popup === options.except) {
|
|
334
|
+
return;
|
|
335
|
+
}
|
|
336
|
+
popup.close();
|
|
337
|
+
});
|
|
338
|
+
}
|
|
250
339
|
}
|
|
251
340
|
|
|
252
341
|
export { map_controller as default };
|
package/package.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"name": "@symfony/ux-leaflet-map",
|
|
3
3
|
"description": "Leaflet 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
|
"leaflet",
|
|
@@ -49,7 +49,7 @@
|
|
|
49
49
|
},
|
|
50
50
|
"devDependencies": {
|
|
51
51
|
"@hotwired/stimulus": "^3.0.0",
|
|
52
|
-
"@symfony/ux-map": "2.
|
|
52
|
+
"@symfony/ux-map": "2.27.0",
|
|
53
53
|
"@types/leaflet": "^1.9.12",
|
|
54
54
|
"leaflet": "^1.9.4"
|
|
55
55
|
}
|