@symfony/ux-google-map 2.32.0 → 2.33.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/README.md CHANGED
@@ -6,9 +6,10 @@ JavaScript assets of the [symfony/ux-google-map](https://packagist.org/packages/
6
6
 
7
7
  This npm package is **reserved for advanced users** who want to decouple their JavaScript dependencies from their PHP dependencies (e.g., when building Docker images, running JavaScript-only pipelines, etc.).
8
8
 
9
- We **strongly recommend not installing this package directly**, but instead install the PHP package [symfony/ux-google-map](https://packagist.org/packages/symfony/ux-google-map) in your Symfony application with [Flex](https://github.com/symfony/flex) enabled.
9
+ We **strongly recommend not installing this package directly**, but instead install the PHP package [symfony/ux-google-map](https://packagist.org/packages/symfony/ux-google-map) in your Symfony application with [Flex](https://github.com/symfony/flex) enabled.
10
10
 
11
11
  If you still want to install this package directly, please make sure its version exactly matches [symfony/ux-google-map](https://packagist.org/packages/symfony/ux-google-map) PHP package version:
12
+
12
13
  ```shell
13
14
  composer require symfony/ux-google-map:2.23.0
14
15
  npm add @symfony/ux-google-map@2.23.0
@@ -18,7 +19,7 @@ npm add @symfony/ux-google-map@2.23.0
18
19
 
19
20
  ## Resources
20
21
 
21
- - [Documentation](https://github.com/symfony/ux/tree/2.x/src/Map/src/Bridge/Google)
22
- - [Report issues](https://github.com/symfony/ux/issues) and
23
- [send Pull Requests](https://github.com/symfony/ux/pulls)
24
- in the [main Symfony UX repository](https://github.com/symfony/ux)
22
+ - [Documentation](https://github.com/symfony/ux/tree/2.x/src/Map/src/Bridge/Google)
23
+ - [Report issues](https://github.com/symfony/ux/issues) and
24
+ [send Pull Requests](https://github.com/symfony/ux/pulls)
25
+ in the [main Symfony UX repository](https://github.com/symfony/ux)
@@ -1,50 +1,280 @@
1
- import { LoaderOptions } from '@googlemaps/js-api-loader';
2
- import AbstractMapController, { MapDefinition, MarkerDefinition, PolygonDefinition, PolylineDefinition, CircleDefinition, RectangleDefinition, InfoWindowDefinition, Icon } from '@symfony/ux-map';
3
-
1
+ import { LoaderOptions } from "@googlemaps/js-api-loader";
2
+ import { Controller } from "@hotwired/stimulus";
3
+ type Point = {
4
+ lat: number;
5
+ lng: number;
6
+ };
7
+ type Identifier = string;
8
+ type WithIdentifier<T extends Record<string, unknown>> = T & {
9
+ '@id': Identifier;
10
+ };
11
+ type ExtraData = Record<string, unknown>;
12
+ declare const IconTypes: {
13
+ readonly Url: "url";
14
+ readonly Svg: "svg";
15
+ readonly UxIcon: "ux-icon";
16
+ };
17
+ type Icon = {
18
+ width: number;
19
+ height: number;
20
+ } & ({
21
+ type: typeof IconTypes.UxIcon;
22
+ name: string;
23
+ _generated_html: string;
24
+ } | {
25
+ type: typeof IconTypes.Url;
26
+ url: string;
27
+ } | {
28
+ type: typeof IconTypes.Svg;
29
+ html: string;
30
+ });
31
+ type MapDefinition<MapOptions, BridgeMapOptions> = {
32
+ center: Point | null;
33
+ zoom: number | null;
34
+ minZoom: number | null;
35
+ maxZoom: number | null;
36
+ options: MapOptions;
37
+ bridgeOptions?: BridgeMapOptions;
38
+ extra: ExtraData;
39
+ };
40
+ type MarkerDefinition<BridgeMarkerOptions, BridgeInfoWindowOptions> = WithIdentifier<{
41
+ position: Point;
42
+ title: string | null;
43
+ infoWindow?: Omit<InfoWindowDefinition<BridgeInfoWindowOptions>, 'position'>;
44
+ icon?: Icon;
45
+ rawOptions?: BridgeMarkerOptions;
46
+ bridgeOptions?: BridgeMarkerOptions;
47
+ extra: ExtraData;
48
+ }>;
49
+ type PolygonDefinition<BridgePolygonOptions, BridgeInfoWindowOptions> = WithIdentifier<{
50
+ infoWindow?: Omit<InfoWindowDefinition<BridgeInfoWindowOptions>, 'position'>;
51
+ points: Array<Point> | Array<Array<Point>>;
52
+ title: string | null;
53
+ rawOptions?: BridgePolygonOptions;
54
+ bridgeOptions?: BridgePolygonOptions;
55
+ extra: ExtraData;
56
+ }>;
57
+ type PolylineDefinition<BridgePolylineOptions, BridgeInfoWindowOptions> = WithIdentifier<{
58
+ infoWindow?: Omit<InfoWindowDefinition<BridgeInfoWindowOptions>, 'position'>;
59
+ points: Array<Point>;
60
+ title: string | null;
61
+ rawOptions?: BridgePolylineOptions;
62
+ bridgeOptions?: BridgePolylineOptions;
63
+ extra: ExtraData;
64
+ }>;
65
+ type CircleDefinition<BridgeCircleOptions, BridgeInfoWindowOptions> = WithIdentifier<{
66
+ infoWindow?: Omit<InfoWindowDefinition<BridgeInfoWindowOptions>, 'position'>;
67
+ center: Point;
68
+ radius: number;
69
+ title: string | null;
70
+ rawOptions?: BridgeCircleOptions;
71
+ bridgeOptions?: BridgeCircleOptions;
72
+ extra: ExtraData;
73
+ }>;
74
+ type RectangleDefinition<BridgeRectangleOptions, BridgeInfoWindowOptions> = WithIdentifier<{
75
+ infoWindow?: Omit<InfoWindowDefinition<BridgeInfoWindowOptions>, 'position'>;
76
+ southWest: Point;
77
+ northEast: Point;
78
+ title: string | null;
79
+ rawOptions?: BridgeRectangleOptions;
80
+ bridgeOptions?: BridgeRectangleOptions;
81
+ extra: ExtraData;
82
+ }>;
83
+ type InfoWindowDefinition<BridgeInfoWindowOptions> = {
84
+ headerContent: string | null;
85
+ content: string | null;
86
+ position: Point;
87
+ opened: boolean;
88
+ autoClose: boolean;
89
+ rawOptions?: BridgeInfoWindowOptions;
90
+ bridgeOptions?: BridgeInfoWindowOptions;
91
+ extra: ExtraData;
92
+ };
93
+ declare abstract class export_default$1<MapOptions, BridgeMapOptions, BridgeMap, BridgeMarkerOptions, BridgeMarker, BridgeInfoWindowOptions, BridgeInfoWindow, BridgePolygonOptions, BridgePolygon, BridgePolylineOptions, BridgePolyline, BridgeCircleOptions, BridgeCircle, BridgeRectangleOptions, BridgeRectangle> extends Controller<HTMLElement> {
94
+ static values: {
95
+ providerOptions: ObjectConstructor;
96
+ center: ObjectConstructor;
97
+ zoom: NumberConstructor;
98
+ minZoom: NumberConstructor;
99
+ maxZoom: NumberConstructor;
100
+ fitBoundsToMarkers: BooleanConstructor;
101
+ markers: ArrayConstructor;
102
+ polygons: ArrayConstructor;
103
+ polylines: ArrayConstructor;
104
+ circles: ArrayConstructor;
105
+ rectangles: ArrayConstructor;
106
+ options: ObjectConstructor;
107
+ extra: ObjectConstructor;
108
+ };
109
+ centerValue: Point | null;
110
+ zoomValue: number | null;
111
+ minZoomValue: number | null;
112
+ maxZoomValue: number | null;
113
+ fitBoundsToMarkersValue: boolean;
114
+ markersValue: Array<MarkerDefinition<BridgeMarkerOptions, BridgeInfoWindowOptions>>;
115
+ polygonsValue: Array<PolygonDefinition<BridgePolygonOptions, BridgeInfoWindowOptions>>;
116
+ polylinesValue: Array<PolylineDefinition<BridgePolylineOptions, BridgeInfoWindowOptions>>;
117
+ circlesValue: Array<CircleDefinition<BridgeCircleOptions, BridgeInfoWindowOptions>>;
118
+ rectanglesValue: Array<RectangleDefinition<BridgeRectangleOptions, BridgeInfoWindowOptions>>;
119
+ optionsValue: MapOptions;
120
+ extraValue: Record<string, unknown>;
121
+ hasCenterValue: boolean;
122
+ hasZoomValue: boolean;
123
+ hasMinZoomValue: boolean;
124
+ hasMaxZoomValue: boolean;
125
+ hasFitBoundsToMarkersValue: boolean;
126
+ hasMarkersValue: boolean;
127
+ hasPolygonsValue: boolean;
128
+ hasPolylinesValue: boolean;
129
+ hasCirclesValue: boolean;
130
+ hasRectanglesValue: boolean;
131
+ hasOptionsValue: boolean;
132
+ hasExtraValue: boolean;
133
+ protected map: BridgeMap;
134
+ protected markers: Map<string, BridgeMarker>;
135
+ protected polygons: Map<string, BridgePolygon>;
136
+ protected polylines: Map<string, BridgePolyline>;
137
+ protected circles: Map<string, BridgeCircle>;
138
+ protected rectangles: Map<string, BridgeRectangle>;
139
+ protected infoWindows: Array<BridgeInfoWindow>;
140
+ private isConnected;
141
+ private createMarker;
142
+ private createPolygon;
143
+ private createPolyline;
144
+ private createCircle;
145
+ private createRectangle;
146
+ protected abstract dispatchEvent(name: string, payload: Record<string, unknown>): void;
147
+ connect(): void;
148
+ createInfoWindow({
149
+ definition,
150
+ element
151
+ }: {
152
+ definition: Omit<InfoWindowDefinition<BridgeInfoWindowOptions>, 'position'>;
153
+ element: BridgeMarker | BridgePolygon | BridgePolyline | BridgeCircle | BridgeRectangle;
154
+ }): BridgeInfoWindow;
155
+ abstract centerValueChanged(): void;
156
+ abstract zoomValueChanged(): void;
157
+ abstract minZoomValueChanged(): void;
158
+ abstract maxZoomValueChanged(): void;
159
+ markersValueChanged(): void;
160
+ polygonsValueChanged(): void;
161
+ polylinesValueChanged(): void;
162
+ circlesValueChanged(): void;
163
+ rectanglesValueChanged(): void;
164
+ protected abstract doCreateMap({
165
+ definition
166
+ }: {
167
+ definition: MapDefinition<MapOptions, BridgeMapOptions>;
168
+ }): BridgeMap;
169
+ protected abstract doFitBoundsToMarkers(): void;
170
+ protected abstract doCreateMarker({
171
+ definition
172
+ }: {
173
+ definition: MarkerDefinition<BridgeMarkerOptions, BridgeInfoWindowOptions>;
174
+ }): BridgeMarker;
175
+ protected abstract doRemoveMarker(marker: BridgeMarker): void;
176
+ protected abstract doCreatePolygon({
177
+ definition
178
+ }: {
179
+ definition: PolygonDefinition<BridgePolygonOptions, BridgeInfoWindowOptions>;
180
+ }): BridgePolygon;
181
+ protected abstract doRemovePolygon(polygon: BridgePolygon): void;
182
+ protected abstract doCreatePolyline({
183
+ definition
184
+ }: {
185
+ definition: PolylineDefinition<BridgePolylineOptions, BridgeInfoWindowOptions>;
186
+ }): BridgePolyline;
187
+ protected abstract doRemovePolyline(polyline: BridgePolyline): void;
188
+ protected abstract doCreateCircle({
189
+ definition
190
+ }: {
191
+ definition: CircleDefinition<BridgeCircleOptions, BridgeInfoWindowOptions>;
192
+ }): BridgeCircle;
193
+ protected abstract doRemoveCircle(circle: BridgeCircle): void;
194
+ protected abstract doCreateRectangle({
195
+ definition
196
+ }: {
197
+ definition: RectangleDefinition<BridgeRectangleOptions, BridgeInfoWindowOptions>;
198
+ }): BridgeRectangle;
199
+ protected abstract doRemoveRectangle(rectangle: BridgeRectangle): void;
200
+ protected abstract doCreateInfoWindow({
201
+ definition,
202
+ element
203
+ }: {
204
+ definition: Omit<InfoWindowDefinition<BridgeInfoWindowOptions>, 'position'>;
205
+ element: BridgeMarker | BridgePolygon | BridgePolyline | BridgeCircle | BridgeRectangle;
206
+ }): BridgeInfoWindow;
207
+ protected abstract doCreateIcon({
208
+ definition,
209
+ element
210
+ }: {
211
+ definition: Icon;
212
+ element: BridgeMarker;
213
+ }): void;
214
+ private createDrawingFactory;
215
+ private onDrawChanged;
216
+ }
4
217
  type MapOptions = Pick<google.maps.MapOptions, 'mapId' | 'gestureHandling' | 'backgroundColor' | 'disableDoubleClickZoom' | 'zoomControl' | 'zoomControlOptions' | 'mapTypeControl' | 'mapTypeControlOptions' | 'streetViewControl' | 'streetViewControlOptions' | 'fullscreenControl' | 'fullscreenControlOptions'>;
5
- declare class export_default 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
- providerOptionsValue: Pick<LoaderOptions, 'apiKey' | 'id' | 'language' | 'region' | 'nonce' | 'retries' | 'url' | 'version' | 'libraries'>;
7
- map: google.maps.Map;
8
- connect(): Promise<void>;
9
- centerValueChanged(): void;
10
- zoomValueChanged(): void;
11
- minZoomValueChanged(): void;
12
- maxZoomValueChanged(): void;
13
- protected dispatchEvent(name: string, payload?: Record<string, unknown>): void;
14
- protected doCreateMap({ definition }: {
15
- definition: MapDefinition<MapOptions, google.maps.MapOptions>;
16
- }): google.maps.Map;
17
- protected doCreateMarker({ definition, }: {
18
- definition: MarkerDefinition<google.maps.marker.AdvancedMarkerElementOptions, google.maps.InfoWindowOptions>;
19
- }): google.maps.marker.AdvancedMarkerElement;
20
- protected doRemoveMarker(marker: google.maps.marker.AdvancedMarkerElement): void;
21
- protected doCreatePolygon({ definition, }: {
22
- definition: PolygonDefinition<google.maps.PolygonOptions, google.maps.InfoWindowOptions>;
23
- }): google.maps.Polygon;
24
- protected doRemovePolygon(polygon: google.maps.Polygon): void;
25
- protected doCreatePolyline({ definition, }: {
26
- definition: PolylineDefinition<google.maps.PolylineOptions, google.maps.InfoWindowOptions>;
27
- }): google.maps.Polyline;
28
- protected doRemovePolyline(polyline: google.maps.Polyline): void;
29
- protected doCreateCircle({ definition }: {
30
- definition: CircleDefinition<google.maps.CircleOptions, google.maps.InfoWindowOptions>;
31
- }): google.maps.Circle;
32
- protected doRemoveCircle(circle: google.maps.Circle): void;
33
- protected doCreateRectangle({ definition, }: {
34
- definition: RectangleDefinition<google.maps.RectangleOptions, google.maps.InfoWindowOptions>;
35
- }): google.maps.Rectangle;
36
- protected doRemoveRectangle(rectangle: google.maps.Rectangle): void;
37
- protected doCreateInfoWindow({ definition, element, }: {
38
- definition: Omit<InfoWindowDefinition<google.maps.InfoWindowOptions>, 'position'>;
39
- element: google.maps.marker.AdvancedMarkerElement | google.maps.Polygon | google.maps.Polyline | google.maps.Circle | google.maps.Rectangle;
40
- }): google.maps.InfoWindow;
41
- protected doFitBoundsToMarkers(): void;
42
- private createTextOrElement;
43
- protected doCreateIcon({ definition, element }: {
44
- definition: Icon;
45
- element: google.maps.marker.AdvancedMarkerElement;
46
- }): void;
47
- private closeInfoWindowsExcept;
218
+ declare class export_default extends export_default$1<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> {
219
+ providerOptionsValue: Pick<LoaderOptions, 'apiKey' | 'id' | 'language' | 'region' | 'nonce' | 'retries' | 'url' | 'version' | 'libraries'>;
220
+ map: google.maps.Map;
221
+ connect(): Promise<void>;
222
+ centerValueChanged(): void;
223
+ zoomValueChanged(): void;
224
+ minZoomValueChanged(): void;
225
+ maxZoomValueChanged(): void;
226
+ protected dispatchEvent(name: string, payload?: Record<string, unknown>): void;
227
+ protected doCreateMap({
228
+ definition
229
+ }: {
230
+ definition: MapDefinition<MapOptions, google.maps.MapOptions>;
231
+ }): google.maps.Map;
232
+ protected doCreateMarker({
233
+ definition
234
+ }: {
235
+ definition: MarkerDefinition<google.maps.marker.AdvancedMarkerElementOptions, google.maps.InfoWindowOptions>;
236
+ }): google.maps.marker.AdvancedMarkerElement;
237
+ protected doRemoveMarker(marker: google.maps.marker.AdvancedMarkerElement): void;
238
+ protected doCreatePolygon({
239
+ definition
240
+ }: {
241
+ definition: PolygonDefinition<google.maps.PolygonOptions, google.maps.InfoWindowOptions>;
242
+ }): google.maps.Polygon;
243
+ protected doRemovePolygon(polygon: google.maps.Polygon): void;
244
+ protected doCreatePolyline({
245
+ definition
246
+ }: {
247
+ definition: PolylineDefinition<google.maps.PolylineOptions, google.maps.InfoWindowOptions>;
248
+ }): google.maps.Polyline;
249
+ protected doRemovePolyline(polyline: google.maps.Polyline): void;
250
+ protected doCreateCircle({
251
+ definition
252
+ }: {
253
+ definition: CircleDefinition<google.maps.CircleOptions, google.maps.InfoWindowOptions>;
254
+ }): google.maps.Circle;
255
+ protected doRemoveCircle(circle: google.maps.Circle): void;
256
+ protected doCreateRectangle({
257
+ definition
258
+ }: {
259
+ definition: RectangleDefinition<google.maps.RectangleOptions, google.maps.InfoWindowOptions>;
260
+ }): google.maps.Rectangle;
261
+ protected doRemoveRectangle(rectangle: google.maps.Rectangle): void;
262
+ protected doCreateInfoWindow({
263
+ definition,
264
+ element
265
+ }: {
266
+ definition: Omit<InfoWindowDefinition<google.maps.InfoWindowOptions>, 'position'>;
267
+ element: google.maps.marker.AdvancedMarkerElement | google.maps.Polygon | google.maps.Polyline | google.maps.Circle | google.maps.Rectangle;
268
+ }): google.maps.InfoWindow;
269
+ protected doFitBoundsToMarkers(): void;
270
+ private createTextOrElement;
271
+ protected doCreateIcon({
272
+ definition,
273
+ element
274
+ }: {
275
+ definition: Icon;
276
+ element: google.maps.marker.AdvancedMarkerElement;
277
+ }): void;
278
+ private closeInfoWindowsExcept;
48
279
  }
49
-
50
- export { export_default as default };
280
+ export { export_default as default };
@@ -1,445 +1,403 @@
1
- // src/map_controller.ts
2
1
  import { Loader } from "@googlemaps/js-api-loader";
3
-
4
- // ../../../../assets/dist/abstract_map_controller.js
5
2
  import { Controller } from "@hotwired/stimulus";
6
- var IconTypes = {
7
- Url: "url",
8
- Svg: "svg",
9
- UxIcon: "ux-icon"
3
+ const IconTypes = {
4
+ Url: "url",
5
+ Svg: "svg",
6
+ UxIcon: "ux-icon"
10
7
  };
11
- var abstract_map_controller_default = class extends Controller {
12
- constructor() {
13
- super(...arguments);
14
- this.markers = /* @__PURE__ */ new Map();
15
- this.polygons = /* @__PURE__ */ new Map();
16
- this.polylines = /* @__PURE__ */ new Map();
17
- this.circles = /* @__PURE__ */ new Map();
18
- this.rectangles = /* @__PURE__ */ new Map();
19
- this.infoWindows = [];
20
- this.isConnected = false;
21
- }
22
- connect() {
23
- const extra = this.hasExtraValue ? this.extraValue : {};
24
- const mapDefinition = {
25
- center: this.hasCenterValue ? this.centerValue : null,
26
- zoom: this.hasZoomValue ? this.zoomValue : null,
27
- minZoom: this.hasMinZoomValue ? this.minZoomValue : null,
28
- maxZoom: this.hasMaxZoomValue ? this.maxZoomValue : null,
29
- options: this.optionsValue,
30
- extra
31
- };
32
- this.dispatchEvent("pre-connect", mapDefinition);
33
- this.createMarker = this.createDrawingFactory("marker", this.markers, this.doCreateMarker.bind(this));
34
- this.createPolygon = this.createDrawingFactory("polygon", this.polygons, this.doCreatePolygon.bind(this));
35
- this.createPolyline = this.createDrawingFactory("polyline", this.polylines, this.doCreatePolyline.bind(this));
36
- this.createCircle = this.createDrawingFactory("circle", this.circles, this.doCreateCircle.bind(this));
37
- this.createRectangle = this.createDrawingFactory("rectangle", this.rectangles, this.doCreateRectangle.bind(this));
38
- this.map = this.doCreateMap({ definition: mapDefinition });
39
- this.markersValue.forEach((definition) => {
40
- this.createMarker({ definition });
41
- });
42
- this.polygonsValue.forEach((definition) => {
43
- this.createPolygon({ definition });
44
- });
45
- this.polylinesValue.forEach((definition) => {
46
- this.createPolyline({ definition });
47
- });
48
- this.circlesValue.forEach((definition) => {
49
- this.createCircle({ definition });
50
- });
51
- this.rectanglesValue.forEach((definition) => {
52
- this.createRectangle({ definition });
53
- });
54
- if (this.fitBoundsToMarkersValue) {
55
- this.doFitBoundsToMarkers();
56
- }
57
- this.dispatchEvent("connect", {
58
- map: this.map,
59
- markers: [...this.markers.values()],
60
- polygons: [...this.polygons.values()],
61
- polylines: [...this.polylines.values()],
62
- circles: [...this.circles.values()],
63
- rectangles: [...this.rectangles.values()],
64
- infoWindows: this.infoWindows,
65
- extra
66
- });
67
- this.isConnected = true;
68
- }
69
- //region Public API
70
- createInfoWindow({
71
- definition,
72
- element
73
- }) {
74
- this.dispatchEvent("info-window:before-create", { definition, element });
75
- const infoWindow = this.doCreateInfoWindow({ definition, element });
76
- this.dispatchEvent("info-window:after-create", { infoWindow, definition, element });
77
- this.infoWindows.push(infoWindow);
78
- return infoWindow;
79
- }
80
- markersValueChanged() {
81
- if (!this.isConnected) {
82
- return;
83
- }
84
- this.onDrawChanged(this.markers, this.markersValue, this.createMarker, this.doRemoveMarker);
85
- if (this.fitBoundsToMarkersValue) {
86
- this.doFitBoundsToMarkers();
87
- }
88
- }
89
- polygonsValueChanged() {
90
- if (!this.isConnected) {
91
- return;
92
- }
93
- this.onDrawChanged(this.polygons, this.polygonsValue, this.createPolygon, this.doRemovePolygon);
94
- }
95
- polylinesValueChanged() {
96
- if (!this.isConnected) {
97
- return;
98
- }
99
- this.onDrawChanged(this.polylines, this.polylinesValue, this.createPolyline, this.doRemovePolyline);
100
- }
101
- circlesValueChanged() {
102
- if (!this.isConnected) {
103
- return;
104
- }
105
- this.onDrawChanged(this.circles, this.circlesValue, this.createCircle, this.doRemoveCircle);
106
- }
107
- rectanglesValueChanged() {
108
- if (!this.isConnected) {
109
- return;
110
- }
111
- this.onDrawChanged(this.rectangles, this.rectanglesValue, this.createRectangle, this.doRemoveRectangle);
112
- }
113
- createDrawingFactory(type, draws, factory) {
114
- const eventBefore = `${type}:before-create`;
115
- const eventAfter = `${type}:after-create`;
116
- return ({ definition }) => {
117
- this.dispatchEvent(eventBefore, { definition });
118
- if (typeof definition.rawOptions !== "undefined") {
119
- console.warn(
120
- `[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.`,
121
- definition
122
- );
123
- }
124
- const drawing = factory({ definition });
125
- this.dispatchEvent(eventAfter, { [type]: drawing, definition });
126
- draws.set(definition["@id"], drawing);
127
- return drawing;
128
- };
129
- }
130
- onDrawChanged(draws, newDrawDefinitions, factory, remover) {
131
- const idsToRemove = new Set(draws.keys());
132
- newDrawDefinitions.forEach((definition) => {
133
- idsToRemove.delete(definition["@id"]);
134
- });
135
- idsToRemove.forEach((id) => {
136
- const draw = draws.get(id);
137
- remover(draw);
138
- draws.delete(id);
139
- });
140
- newDrawDefinitions.forEach((definition) => {
141
- if (!draws.has(definition["@id"])) {
142
- factory({ definition });
143
- }
144
- });
145
- }
146
- //endregion
8
+ var _Class = class extends Controller {
9
+ constructor(..._args) {
10
+ super(..._args);
11
+ this.markers = /* @__PURE__ */ new Map();
12
+ this.polygons = /* @__PURE__ */ new Map();
13
+ this.polylines = /* @__PURE__ */ new Map();
14
+ this.circles = /* @__PURE__ */ new Map();
15
+ this.rectangles = /* @__PURE__ */ new Map();
16
+ this.infoWindows = [];
17
+ this.isConnected = false;
18
+ }
19
+ connect() {
20
+ const extra = this.hasExtraValue ? this.extraValue : {};
21
+ const mapDefinition = {
22
+ center: this.hasCenterValue ? this.centerValue : null,
23
+ zoom: this.hasZoomValue ? this.zoomValue : null,
24
+ minZoom: this.hasMinZoomValue ? this.minZoomValue : null,
25
+ maxZoom: this.hasMaxZoomValue ? this.maxZoomValue : null,
26
+ options: this.optionsValue,
27
+ extra
28
+ };
29
+ this.dispatchEvent("pre-connect", mapDefinition);
30
+ this.createMarker = this.createDrawingFactory("marker", this.markers, this.doCreateMarker.bind(this));
31
+ this.createPolygon = this.createDrawingFactory("polygon", this.polygons, this.doCreatePolygon.bind(this));
32
+ this.createPolyline = this.createDrawingFactory("polyline", this.polylines, this.doCreatePolyline.bind(this));
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 });
36
+ this.markersValue.forEach((definition) => {
37
+ this.createMarker({ definition });
38
+ });
39
+ this.polygonsValue.forEach((definition) => {
40
+ this.createPolygon({ definition });
41
+ });
42
+ this.polylinesValue.forEach((definition) => {
43
+ this.createPolyline({ definition });
44
+ });
45
+ this.circlesValue.forEach((definition) => {
46
+ this.createCircle({ definition });
47
+ });
48
+ this.rectanglesValue.forEach((definition) => {
49
+ this.createRectangle({ definition });
50
+ });
51
+ if (this.fitBoundsToMarkersValue) this.doFitBoundsToMarkers();
52
+ this.dispatchEvent("connect", {
53
+ map: this.map,
54
+ markers: [...this.markers.values()],
55
+ polygons: [...this.polygons.values()],
56
+ polylines: [...this.polylines.values()],
57
+ circles: [...this.circles.values()],
58
+ rectangles: [...this.rectangles.values()],
59
+ infoWindows: this.infoWindows,
60
+ extra
61
+ });
62
+ this.isConnected = true;
63
+ }
64
+ createInfoWindow({ definition, element }) {
65
+ this.dispatchEvent("info-window:before-create", {
66
+ definition,
67
+ element
68
+ });
69
+ const infoWindow = this.doCreateInfoWindow({
70
+ definition,
71
+ element
72
+ });
73
+ this.dispatchEvent("info-window:after-create", {
74
+ infoWindow,
75
+ definition,
76
+ element
77
+ });
78
+ this.infoWindows.push(infoWindow);
79
+ return infoWindow;
80
+ }
81
+ markersValueChanged() {
82
+ if (!this.isConnected) return;
83
+ this.onDrawChanged(this.markers, this.markersValue, this.createMarker, this.doRemoveMarker);
84
+ if (this.fitBoundsToMarkersValue) this.doFitBoundsToMarkers();
85
+ }
86
+ polygonsValueChanged() {
87
+ if (!this.isConnected) return;
88
+ this.onDrawChanged(this.polygons, this.polygonsValue, this.createPolygon, this.doRemovePolygon);
89
+ }
90
+ polylinesValueChanged() {
91
+ if (!this.isConnected) return;
92
+ this.onDrawChanged(this.polylines, this.polylinesValue, this.createPolyline, this.doRemovePolyline);
93
+ }
94
+ circlesValueChanged() {
95
+ if (!this.isConnected) return;
96
+ this.onDrawChanged(this.circles, this.circlesValue, this.createCircle, this.doRemoveCircle);
97
+ }
98
+ rectanglesValueChanged() {
99
+ if (!this.isConnected) return;
100
+ this.onDrawChanged(this.rectangles, this.rectanglesValue, this.createRectangle, this.doRemoveRectangle);
101
+ }
102
+ createDrawingFactory(type, draws, factory) {
103
+ const eventBefore = `${type}:before-create`;
104
+ const eventAfter = `${type}:after-create`;
105
+ return ({ definition }) => {
106
+ this.dispatchEvent(eventBefore, { definition });
107
+ if (typeof definition.rawOptions !== "undefined") 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);
108
+ const drawing = factory({ definition });
109
+ this.dispatchEvent(eventAfter, {
110
+ [type]: drawing,
111
+ definition
112
+ });
113
+ draws.set(definition["@id"], drawing);
114
+ return drawing;
115
+ };
116
+ }
117
+ onDrawChanged(draws, newDrawDefinitions, factory, remover) {
118
+ const idsToRemove = new Set(draws.keys());
119
+ newDrawDefinitions.forEach((definition) => {
120
+ idsToRemove.delete(definition["@id"]);
121
+ });
122
+ idsToRemove.forEach((id) => {
123
+ remover(draws.get(id));
124
+ draws.delete(id);
125
+ });
126
+ newDrawDefinitions.forEach((definition) => {
127
+ if (!draws.has(definition["@id"])) factory({ definition });
128
+ });
129
+ }
147
130
  };
148
- abstract_map_controller_default.values = {
149
- providerOptions: Object,
150
- center: Object,
151
- zoom: Number,
152
- minZoom: Number,
153
- maxZoom: Number,
154
- fitBoundsToMarkers: Boolean,
155
- markers: Array,
156
- polygons: Array,
157
- polylines: Array,
158
- circles: Array,
159
- rectangles: Array,
160
- options: Object,
161
- extra: Object
131
+ _Class.values = {
132
+ providerOptions: Object,
133
+ center: Object,
134
+ zoom: Number,
135
+ minZoom: Number,
136
+ maxZoom: Number,
137
+ fitBoundsToMarkers: Boolean,
138
+ markers: Array,
139
+ polygons: Array,
140
+ polylines: Array,
141
+ circles: Array,
142
+ rectangles: Array,
143
+ options: Object,
144
+ extra: Object
162
145
  };
163
-
164
- // src/map_controller.ts
165
- var _google;
166
- var _loading = false;
167
- var _loaded = false;
168
- var _onLoadedCallbacks = [];
169
- var parser = new DOMParser();
170
- var map_controller_default = class extends abstract_map_controller_default {
171
- async connect() {
172
- const onLoaded = () => super.connect();
173
- if (_loaded) {
174
- onLoaded();
175
- return;
176
- }
177
- if (_loading) {
178
- _onLoadedCallbacks.push(onLoaded);
179
- return;
180
- }
181
- _loading = true;
182
- _google = { maps: {} };
183
- let { libraries = [], ...loaderOptions } = this.providerOptionsValue;
184
- const loader = new Loader(loaderOptions);
185
- libraries = ["core", ...libraries.filter((library) => library !== "core")];
186
- const librariesImplementations = await Promise.all(libraries.map((library) => loader.importLibrary(library)));
187
- librariesImplementations.forEach((libraryImplementation, index) => {
188
- if (typeof libraryImplementation !== "object" || libraryImplementation === null) {
189
- return;
190
- }
191
- const library = libraries[index];
192
- if (["marker", "places", "geometry", "journeySharing", "drawing", "visualization"].includes(library)) {
193
- _google.maps[library] = libraryImplementation;
194
- } else {
195
- _google.maps = { ..._google.maps, ...libraryImplementation };
196
- }
197
- });
198
- _loading = false;
199
- _loaded = true;
200
- onLoaded();
201
- _onLoadedCallbacks.forEach((callback) => {
202
- callback();
203
- });
204
- _onLoadedCallbacks = [];
205
- }
206
- centerValueChanged() {
207
- if (this.map && this.hasCenterValue && this.centerValue) {
208
- this.map.setCenter(this.centerValue);
209
- }
210
- }
211
- zoomValueChanged() {
212
- if (this.map && this.hasZoomValue && this.zoomValue) {
213
- this.map.setZoom(this.zoomValue);
214
- }
215
- }
216
- minZoomValueChanged() {
217
- if (this.map && this.hasMinZoomValue && this.minZoomValue) {
218
- this.map.setOptions({ minZoom: this.minZoomValue });
219
- }
220
- }
221
- maxZoomValueChanged() {
222
- if (this.map && this.hasMaxZoomValue && this.maxZoomValue) {
223
- this.map.setOptions({ maxZoom: this.maxZoomValue });
224
- }
225
- }
226
- dispatchEvent(name, payload = {}) {
227
- payload.google = _google;
228
- this.dispatch(name, {
229
- prefix: "ux:map",
230
- detail: payload
231
- });
232
- }
233
- doCreateMap({ definition }) {
234
- const { center, zoom, minZoom, maxZoom, options, bridgeOptions = {} } = definition;
235
- options.zoomControl = typeof options.zoomControlOptions !== "undefined";
236
- options.mapTypeControl = typeof options.mapTypeControlOptions !== "undefined";
237
- options.streetViewControl = typeof options.streetViewControlOptions !== "undefined";
238
- options.fullscreenControl = typeof options.fullscreenControlOptions !== "undefined";
239
- return new _google.maps.Map(this.element, {
240
- center,
241
- zoom,
242
- minZoom,
243
- maxZoom,
244
- ...options,
245
- ...bridgeOptions
246
- });
247
- }
248
- doCreateMarker({
249
- definition
250
- }) {
251
- const { "@id": _id, position, title, infoWindow, icon, rawOptions = {}, bridgeOptions = {} } = definition;
252
- const marker = new _google.maps.marker.AdvancedMarkerElement({
253
- position,
254
- title,
255
- map: this.map,
256
- ...rawOptions,
257
- ...bridgeOptions
258
- });
259
- if (infoWindow) {
260
- this.createInfoWindow({ definition: infoWindow, element: marker });
261
- }
262
- if (icon) {
263
- if (Object.prototype.hasOwnProperty.call(bridgeOptions, "content")) {
264
- console.warn('[Symfony UX Map] Defining "bridgeOptions.content" for a marker with a custom icon is not supported and will be ignored.');
265
- } else if (Object.prototype.hasOwnProperty.call(rawOptions, "content")) {
266
- console.warn('[Symfony UX Map] Defining "rawOptions.content" for a marker with a custom icon is not supported and will be ignored.');
267
- }
268
- this.doCreateIcon({ definition: icon, element: marker });
269
- }
270
- return marker;
271
- }
272
- doRemoveMarker(marker) {
273
- marker.map = null;
274
- }
275
- doCreatePolygon({
276
- definition
277
- }) {
278
- const { "@id": _id, points, title, infoWindow, rawOptions = {}, bridgeOptions = {} } = definition;
279
- const polygon = new _google.maps.Polygon({
280
- paths: points,
281
- map: this.map,
282
- ...rawOptions,
283
- ...bridgeOptions
284
- });
285
- if (title) {
286
- polygon.set("title", title);
287
- }
288
- if (infoWindow) {
289
- this.createInfoWindow({ definition: infoWindow, element: polygon });
290
- }
291
- return polygon;
292
- }
293
- doRemovePolygon(polygon) {
294
- polygon.setMap(null);
295
- }
296
- doCreatePolyline({
297
- definition
298
- }) {
299
- const { "@id": _id, points, title, infoWindow, rawOptions = {}, bridgeOptions = {} } = definition;
300
- const polyline = new _google.maps.Polyline({
301
- path: points,
302
- map: this.map,
303
- ...rawOptions,
304
- ...bridgeOptions
305
- });
306
- if (title) {
307
- polyline.set("title", title);
308
- }
309
- if (infoWindow) {
310
- this.createInfoWindow({ definition: infoWindow, element: polyline });
311
- }
312
- return polyline;
313
- }
314
- doRemovePolyline(polyline) {
315
- polyline.setMap(null);
316
- }
317
- doCreateCircle({ definition }) {
318
- const { "@id": _id, center, radius, title, infoWindow, rawOptions = {}, bridgeOptions = {} } = definition;
319
- const circle = new _google.maps.Circle({
320
- center,
321
- radius,
322
- map: this.map,
323
- ...rawOptions,
324
- ...bridgeOptions
325
- });
326
- if (title) {
327
- circle.set("title", title);
328
- }
329
- if (infoWindow) {
330
- this.createInfoWindow({ definition: infoWindow, element: circle });
331
- }
332
- return circle;
333
- }
334
- doRemoveCircle(circle) {
335
- circle.setMap(null);
336
- }
337
- doCreateRectangle({
338
- definition
339
- }) {
340
- const { northEast, southWest, title, infoWindow, rawOptions = {}, bridgeOptions = {} } = definition;
341
- const rectangle = new _google.maps.Rectangle({
342
- bounds: new _google.maps.LatLngBounds(southWest, northEast),
343
- map: this.map,
344
- ...rawOptions,
345
- ...bridgeOptions
346
- });
347
- if (title) {
348
- rectangle.set("title", title);
349
- }
350
- if (infoWindow) {
351
- this.createInfoWindow({ definition: infoWindow, element: rectangle });
352
- }
353
- return rectangle;
354
- }
355
- doRemoveRectangle(rectangle) {
356
- rectangle.setMap(null);
357
- }
358
- doCreateInfoWindow({
359
- definition,
360
- element
361
- }) {
362
- const { headerContent, content, opened, autoClose, rawOptions = {}, bridgeOptions = {} } = definition;
363
- let position = null;
364
- if (element instanceof google.maps.Circle) {
365
- position = element.getCenter();
366
- } else if (element instanceof google.maps.Rectangle) {
367
- position = element.getBounds()?.getCenter() || null;
368
- } else if (element instanceof google.maps.Polygon || element instanceof google.maps.Polyline) {
369
- }
370
- const infoWindowOptions = {
371
- headerContent: this.createTextOrElement(headerContent),
372
- content: this.createTextOrElement(content),
373
- position,
374
- ...rawOptions,
375
- ...bridgeOptions
376
- };
377
- const infoWindow = new _google.maps.InfoWindow(infoWindowOptions);
378
- element.addListener("click", (event) => {
379
- if (autoClose) {
380
- this.closeInfoWindowsExcept(infoWindow);
381
- }
382
- if (infoWindowOptions.position === null) {
383
- infoWindow.setPosition(event.latLng);
384
- }
385
- infoWindow.open({ map: this.map, anchor: element });
386
- });
387
- if (opened) {
388
- if (autoClose) {
389
- this.closeInfoWindowsExcept(infoWindow);
390
- }
391
- infoWindow.open({ map: this.map, anchor: element });
392
- }
393
- return infoWindow;
394
- }
395
- doFitBoundsToMarkers() {
396
- if (this.markers.size === 0) {
397
- return;
398
- }
399
- const bounds = new google.maps.LatLngBounds();
400
- this.markers.forEach((marker) => {
401
- if (!marker.position) {
402
- return;
403
- }
404
- bounds.extend(marker.position);
405
- });
406
- this.map.fitBounds(bounds);
407
- }
408
- createTextOrElement(content) {
409
- if (!content) {
410
- return null;
411
- }
412
- if (content.includes("<")) {
413
- const div = document.createElement("div");
414
- div.innerHTML = content;
415
- return div;
416
- }
417
- return content;
418
- }
419
- doCreateIcon({ definition, element }) {
420
- const { type, width, height } = definition;
421
- if (type === IconTypes.Svg) {
422
- element.content = parser.parseFromString(definition.html, "image/svg+xml").documentElement;
423
- } else if (type === IconTypes.UxIcon) {
424
- element.content = parser.parseFromString(definition._generated_html, "image/svg+xml").documentElement;
425
- } else if (type === IconTypes.Url) {
426
- const icon = document.createElement("img");
427
- icon.width = width;
428
- icon.height = height;
429
- icon.src = definition.url;
430
- element.content = icon;
431
- } else {
432
- throw new Error(`Unsupported icon type: ${type}.`);
433
- }
434
- }
435
- closeInfoWindowsExcept(infoWindow) {
436
- this.infoWindows.forEach((otherInfoWindow) => {
437
- if (otherInfoWindow !== infoWindow) {
438
- otherInfoWindow.close();
439
- }
440
- });
441
- }
442
- };
443
- export {
444
- map_controller_default as default
146
+ let _google;
147
+ let _loading = false;
148
+ let _loaded = false;
149
+ let _onLoadedCallbacks = [];
150
+ const parser = new DOMParser();
151
+ var map_controller_default = class extends _Class {
152
+ async connect() {
153
+ const onLoaded = () => super.connect();
154
+ if (_loaded) {
155
+ onLoaded();
156
+ return;
157
+ }
158
+ if (_loading) {
159
+ _onLoadedCallbacks.push(onLoaded);
160
+ return;
161
+ }
162
+ _loading = true;
163
+ _google = { maps: {} };
164
+ let { libraries = [], ...loaderOptions } = this.providerOptionsValue;
165
+ const loader = new Loader(loaderOptions);
166
+ libraries = ["core", ...libraries.filter((library) => library !== "core")];
167
+ (await Promise.all(libraries.map((library) => loader.importLibrary(library)))).forEach((libraryImplementation, index) => {
168
+ if (typeof libraryImplementation !== "object" || libraryImplementation === null) return;
169
+ const library = libraries[index];
170
+ if ([
171
+ "marker",
172
+ "places",
173
+ "geometry",
174
+ "journeySharing",
175
+ "drawing",
176
+ "visualization"
177
+ ].includes(library)) _google.maps[library] = libraryImplementation;
178
+ else _google.maps = {
179
+ ..._google.maps,
180
+ ...libraryImplementation
181
+ };
182
+ });
183
+ _loading = false;
184
+ _loaded = true;
185
+ onLoaded();
186
+ _onLoadedCallbacks.forEach((callback) => {
187
+ callback();
188
+ });
189
+ _onLoadedCallbacks = [];
190
+ }
191
+ centerValueChanged() {
192
+ if (this.map && this.hasCenterValue && this.centerValue) this.map.setCenter(this.centerValue);
193
+ }
194
+ zoomValueChanged() {
195
+ if (this.map && this.hasZoomValue && this.zoomValue) this.map.setZoom(this.zoomValue);
196
+ }
197
+ minZoomValueChanged() {
198
+ if (this.map && this.hasMinZoomValue && this.minZoomValue) this.map.setOptions({ minZoom: this.minZoomValue });
199
+ }
200
+ maxZoomValueChanged() {
201
+ if (this.map && this.hasMaxZoomValue && this.maxZoomValue) this.map.setOptions({ maxZoom: this.maxZoomValue });
202
+ }
203
+ dispatchEvent(name, payload = {}) {
204
+ payload.google = _google;
205
+ this.dispatch(name, {
206
+ prefix: "ux:map",
207
+ detail: payload
208
+ });
209
+ }
210
+ doCreateMap({ definition }) {
211
+ const { center, zoom, minZoom, maxZoom, options, bridgeOptions = {} } = definition;
212
+ options.zoomControl = typeof options.zoomControlOptions !== "undefined";
213
+ options.mapTypeControl = typeof options.mapTypeControlOptions !== "undefined";
214
+ options.streetViewControl = typeof options.streetViewControlOptions !== "undefined";
215
+ options.fullscreenControl = typeof options.fullscreenControlOptions !== "undefined";
216
+ return new _google.maps.Map(this.element, {
217
+ center,
218
+ zoom,
219
+ minZoom,
220
+ maxZoom,
221
+ ...options,
222
+ ...bridgeOptions
223
+ });
224
+ }
225
+ doCreateMarker({ definition }) {
226
+ const { "@id": _id, position, title, infoWindow, icon, rawOptions = {}, bridgeOptions = {} } = definition;
227
+ const marker = new _google.maps.marker.AdvancedMarkerElement({
228
+ position,
229
+ title,
230
+ map: this.map,
231
+ ...rawOptions,
232
+ ...bridgeOptions
233
+ });
234
+ if (infoWindow) this.createInfoWindow({
235
+ definition: infoWindow,
236
+ element: marker
237
+ });
238
+ if (icon) {
239
+ if (Object.prototype.hasOwnProperty.call(bridgeOptions, "content")) console.warn("[Symfony UX Map] Defining \"bridgeOptions.content\" for a marker with a custom icon is not supported and will be ignored.");
240
+ else if (Object.prototype.hasOwnProperty.call(rawOptions, "content")) console.warn("[Symfony UX Map] Defining \"rawOptions.content\" for a marker with a custom icon is not supported and will be ignored.");
241
+ this.doCreateIcon({
242
+ definition: icon,
243
+ element: marker
244
+ });
245
+ }
246
+ return marker;
247
+ }
248
+ doRemoveMarker(marker) {
249
+ marker.map = null;
250
+ }
251
+ doCreatePolygon({ definition }) {
252
+ const { "@id": _id, points, title, infoWindow, rawOptions = {}, bridgeOptions = {} } = definition;
253
+ const polygon = new _google.maps.Polygon({
254
+ paths: points,
255
+ map: this.map,
256
+ ...rawOptions,
257
+ ...bridgeOptions
258
+ });
259
+ /**
260
+ * @deprecated since Symfony UX Map 2.29, will be removed in 3.0
261
+ */
262
+ if (title) polygon.set("title", title);
263
+ if (infoWindow) this.createInfoWindow({
264
+ definition: infoWindow,
265
+ element: polygon
266
+ });
267
+ return polygon;
268
+ }
269
+ doRemovePolygon(polygon) {
270
+ polygon.setMap(null);
271
+ }
272
+ doCreatePolyline({ definition }) {
273
+ const { "@id": _id, points, title, infoWindow, rawOptions = {}, bridgeOptions = {} } = definition;
274
+ const polyline = new _google.maps.Polyline({
275
+ path: points,
276
+ map: this.map,
277
+ ...rawOptions,
278
+ ...bridgeOptions
279
+ });
280
+ /**
281
+ * @deprecated since Symfony UX Map 2.29, will be removed in 3.0
282
+ */
283
+ if (title) polyline.set("title", title);
284
+ if (infoWindow) this.createInfoWindow({
285
+ definition: infoWindow,
286
+ element: polyline
287
+ });
288
+ return polyline;
289
+ }
290
+ doRemovePolyline(polyline) {
291
+ polyline.setMap(null);
292
+ }
293
+ doCreateCircle({ definition }) {
294
+ const { "@id": _id, center, radius, title, infoWindow, rawOptions = {}, bridgeOptions = {} } = definition;
295
+ const circle = new _google.maps.Circle({
296
+ center,
297
+ radius,
298
+ map: this.map,
299
+ ...rawOptions,
300
+ ...bridgeOptions
301
+ });
302
+ /**
303
+ * @deprecated since Symfony UX Map 2.29, will be removed in 3.0
304
+ */
305
+ if (title) circle.set("title", title);
306
+ if (infoWindow) this.createInfoWindow({
307
+ definition: infoWindow,
308
+ element: circle
309
+ });
310
+ return circle;
311
+ }
312
+ doRemoveCircle(circle) {
313
+ circle.setMap(null);
314
+ }
315
+ doCreateRectangle({ definition }) {
316
+ const { northEast, southWest, title, infoWindow, rawOptions = {}, bridgeOptions = {} } = definition;
317
+ const rectangle = new _google.maps.Rectangle({
318
+ bounds: new _google.maps.LatLngBounds(southWest, northEast),
319
+ map: this.map,
320
+ ...rawOptions,
321
+ ...bridgeOptions
322
+ });
323
+ /**
324
+ * @deprecated since Symfony UX Map 2.29, will be removed in 3.0
325
+ */
326
+ if (title) rectangle.set("title", title);
327
+ if (infoWindow) this.createInfoWindow({
328
+ definition: infoWindow,
329
+ element: rectangle
330
+ });
331
+ return rectangle;
332
+ }
333
+ doRemoveRectangle(rectangle) {
334
+ rectangle.setMap(null);
335
+ }
336
+ doCreateInfoWindow({ definition, element }) {
337
+ const { headerContent, content, opened, autoClose, rawOptions = {}, bridgeOptions = {} } = definition;
338
+ let position = null;
339
+ if (element instanceof google.maps.Circle) position = element.getCenter();
340
+ else if (element instanceof google.maps.Rectangle) position = element.getBounds()?.getCenter() || null;
341
+ else if (element instanceof google.maps.Polygon || element instanceof google.maps.Polyline) {}
342
+ const infoWindowOptions = {
343
+ headerContent: this.createTextOrElement(headerContent),
344
+ content: this.createTextOrElement(content),
345
+ position,
346
+ ...rawOptions,
347
+ ...bridgeOptions
348
+ };
349
+ const infoWindow = new _google.maps.InfoWindow(infoWindowOptions);
350
+ element.addListener("click", (event) => {
351
+ if (autoClose) this.closeInfoWindowsExcept(infoWindow);
352
+ if (infoWindowOptions.position === null) infoWindow.setPosition(event.latLng);
353
+ infoWindow.open({
354
+ map: this.map,
355
+ anchor: element
356
+ });
357
+ });
358
+ if (opened) {
359
+ if (autoClose) this.closeInfoWindowsExcept(infoWindow);
360
+ infoWindow.open({
361
+ map: this.map,
362
+ anchor: element
363
+ });
364
+ }
365
+ return infoWindow;
366
+ }
367
+ doFitBoundsToMarkers() {
368
+ if (this.markers.size === 0) return;
369
+ const bounds = new google.maps.LatLngBounds();
370
+ this.markers.forEach((marker) => {
371
+ if (!marker.position) return;
372
+ bounds.extend(marker.position);
373
+ });
374
+ this.map.fitBounds(bounds);
375
+ }
376
+ createTextOrElement(content) {
377
+ if (!content) return null;
378
+ if (content.includes("<")) {
379
+ const div = document.createElement("div");
380
+ div.innerHTML = content;
381
+ return div;
382
+ }
383
+ return content;
384
+ }
385
+ doCreateIcon({ definition, element }) {
386
+ const { type, width, height } = definition;
387
+ if (type === IconTypes.Svg) element.content = parser.parseFromString(definition.html, "image/svg+xml").documentElement;
388
+ else if (type === IconTypes.UxIcon) element.content = parser.parseFromString(definition._generated_html, "image/svg+xml").documentElement;
389
+ else if (type === IconTypes.Url) {
390
+ const icon = document.createElement("img");
391
+ icon.width = width;
392
+ icon.height = height;
393
+ icon.src = definition.url;
394
+ element.content = icon;
395
+ } else throw new Error(`Unsupported icon type: ${type}.`);
396
+ }
397
+ closeInfoWindowsExcept(infoWindow) {
398
+ this.infoWindows.forEach((otherInfoWindow) => {
399
+ if (otherInfoWindow !== infoWindow) otherInfoWindow.close();
400
+ });
401
+ }
445
402
  };
403
+ export { map_controller_default as default };
package/package.json CHANGED
@@ -2,14 +2,14 @@
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.32.0",
5
+ "version": "2.33.0",
6
6
  "keywords": [
7
7
  "symfony-ux",
8
8
  "google-maps",
9
9
  "map"
10
10
  ],
11
11
  "homepage": "https://ux.symfony.com/map",
12
- "repository": "https://github.com/symfony/ux-google-map",
12
+ "repository": "https://github.com/symfony/ux",
13
13
  "type": "module",
14
14
  "files": [
15
15
  "dist"
@@ -47,20 +47,15 @@
47
47
  "@testing-library/jest-dom": "^6.6.3",
48
48
  "@testing-library/user-event": "^14.6.1",
49
49
  "@types/google.maps": "^3.55.9",
50
- "@vitest/browser": "^3.2.4",
51
50
  "jsdom": "^26.1.0",
52
51
  "tslib": "^2.8.1",
53
- "tsx": "^4.20.3",
54
- "typescript": "^5.8.3",
55
- "vitest": "^3.2.4"
52
+ "typescript": "^5.8.3"
56
53
  },
57
54
  "scripts": {
58
- "build": "tsx ../../../../../../bin/build_package.ts .",
59
- "watch": "tsx ../../../../../../bin/build_package.ts . --watch",
55
+ "build": "node ../../../../../../bin/build_package.ts .",
56
+ "watch": "node ../../../../../../bin/build_package.ts . --watch",
60
57
  "test": "pnpm run test:browser",
61
58
  "test:browser": "playwright test",
62
- "test:browser:ui": "playwright test --ui",
63
- "check": "biome check",
64
- "ci": "biome ci"
59
+ "test:browser:ui": "playwright test --ui"
65
60
  }
66
61
  }