Skip to content

Commit 0363d5d

Browse files
committed
[Map] Add extra data to Map
1 parent b4b7f61 commit 0363d5d

13 files changed

+169
-17
lines changed

src/Map/CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ this.element.addEventListener('ux:map:pre-connect', (event) => {
3939
};
4040
});
4141
```
42+
- Add `extra` data support to `Map`, which can be accessed in `ux:map:pre-connect` and `ux:map:connect` events
4243

4344
## 2.26
4445

src/Map/assets/dist/abstract_map_controller.d.ts

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ export type Identifier = string;
77
export type WithIdentifier<T extends Record<string, unknown>> = T & {
88
'@id': Identifier;
99
};
10+
type ExtraData = Record<string, unknown>;
1011
export declare const IconTypes: {
1112
readonly Url: "url";
1213
readonly Svg: "svg";
@@ -31,6 +32,7 @@ export type MapDefinition<MapOptions, BridgeMapOptions> = {
3132
zoom: number | null;
3233
options: MapOptions;
3334
bridgeOptions?: BridgeMapOptions;
35+
extra: ExtraData;
3436
};
3537
export type MarkerDefinition<BridgeMarkerOptions, BridgeInfoWindowOptions> = WithIdentifier<{
3638
position: Point;
@@ -39,23 +41,23 @@ export type MarkerDefinition<BridgeMarkerOptions, BridgeInfoWindowOptions> = Wit
3941
icon?: Icon;
4042
rawOptions?: BridgeMarkerOptions;
4143
bridgeOptions?: BridgeMarkerOptions;
42-
extra: Record<string, unknown>;
44+
extra: ExtraData;
4345
}>;
4446
export type PolygonDefinition<BridgePolygonOptions, BridgeInfoWindowOptions> = WithIdentifier<{
4547
infoWindow?: Omit<InfoWindowDefinition<BridgeInfoWindowOptions>, 'position'>;
4648
points: Array<Point> | Array<Array<Point>>;
4749
title: string | null;
4850
rawOptions?: BridgePolygonOptions;
4951
bridgeOptions?: BridgePolygonOptions;
50-
extra: Record<string, unknown>;
52+
extra: ExtraData;
5153
}>;
5254
export type PolylineDefinition<BridgePolylineOptions, BridgeInfoWindowOptions> = WithIdentifier<{
5355
infoWindow?: Omit<InfoWindowDefinition<BridgeInfoWindowOptions>, 'position'>;
5456
points: Array<Point>;
5557
title: string | null;
5658
rawOptions?: BridgePolylineOptions;
5759
bridgeOptions?: BridgePolylineOptions;
58-
extra: Record<string, unknown>;
60+
extra: ExtraData;
5961
}>;
6062
export type CircleDefinition<BridgeCircleOptions, BridgeInfoWindowOptions> = WithIdentifier<{
6163
infoWindow?: Omit<InfoWindowDefinition<BridgeInfoWindowOptions>, 'position'>;
@@ -64,7 +66,7 @@ export type CircleDefinition<BridgeCircleOptions, BridgeInfoWindowOptions> = Wit
6466
title: string | null;
6567
rawOptions?: BridgeCircleOptions;
6668
bridgeOptions?: BridgeCircleOptions;
67-
extra: Record<string, unknown>;
69+
extra: ExtraData;
6870
}>;
6971
export type RectangleDefinition<BridgeRectangleOptions, BridgeInfoWindowOptions> = WithIdentifier<{
7072
infoWindow?: Omit<InfoWindowDefinition<BridgeInfoWindowOptions>, 'position'>;
@@ -73,7 +75,7 @@ export type RectangleDefinition<BridgeRectangleOptions, BridgeInfoWindowOptions>
7375
title: string | null;
7476
rawOptions?: BridgeRectangleOptions;
7577
bridgeOptions?: BridgeRectangleOptions;
76-
extra: Record<string, unknown>;
78+
extra: ExtraData;
7779
}>;
7880
export type InfoWindowDefinition<BridgeInfoWindowOptions> = {
7981
headerContent: string | null;
@@ -83,7 +85,7 @@ export type InfoWindowDefinition<BridgeInfoWindowOptions> = {
8385
autoClose: boolean;
8486
rawOptions?: BridgeInfoWindowOptions;
8587
bridgeOptions?: BridgeInfoWindowOptions;
86-
extra: Record<string, unknown>;
88+
extra: ExtraData;
8789
};
8890
export default abstract class<MapOptions, BridgeMapOptions, BridgeMap, BridgeMarkerOptions, BridgeMarker, BridgeInfoWindowOptions, BridgeInfoWindow, BridgePolygonOptions, BridgePolygon, BridgePolylineOptions, BridgePolyline, BridgeCircleOptions, BridgeCircle, BridgeRectangleOptions, BridgeRectangle> extends Controller<HTMLElement> {
8991
static values: {
@@ -97,6 +99,7 @@ export default abstract class<MapOptions, BridgeMapOptions, BridgeMap, BridgeMar
9799
circles: ArrayConstructor;
98100
rectangles: ArrayConstructor;
99101
options: ObjectConstructor;
102+
extra: ObjectConstructor;
100103
};
101104
centerValue: Point | null;
102105
zoomValue: number | null;
@@ -107,6 +110,7 @@ export default abstract class<MapOptions, BridgeMapOptions, BridgeMap, BridgeMar
107110
circlesValue: Array<CircleDefinition<BridgeCircleOptions, BridgeInfoWindowOptions>>;
108111
rectanglesValue: Array<RectangleDefinition<BridgeRectangleOptions, BridgeInfoWindowOptions>>;
109112
optionsValue: MapOptions;
113+
extraValue: Record<string, unknown>;
110114
hasCenterValue: boolean;
111115
hasZoomValue: boolean;
112116
hasFitBoundsToMarkersValue: boolean;
@@ -116,6 +120,7 @@ export default abstract class<MapOptions, BridgeMapOptions, BridgeMap, BridgeMar
116120
hasCirclesValue: boolean;
117121
hasRectanglesValue: boolean;
118122
hasOptionsValue: boolean;
123+
hasExtraValue: boolean;
119124
protected map: BridgeMap;
120125
protected markers: Map<string, BridgeMarker>;
121126
protected polygons: Map<string, BridgePolygon>;
@@ -177,3 +182,4 @@ export default abstract class<MapOptions, BridgeMapOptions, BridgeMap, BridgeMar
177182
private createDrawingFactory;
178183
private onDrawChanged;
179184
}
185+
export {};

src/Map/assets/dist/abstract_map_controller.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,12 @@ class default_1 extends Controller {
1717
this.isConnected = false;
1818
}
1919
connect() {
20+
const extra = this.hasExtraValue ? this.extraValue : {};
2021
const mapDefinition = {
2122
center: this.hasCenterValue ? this.centerValue : null,
2223
zoom: this.hasZoomValue ? this.zoomValue : null,
2324
options: this.optionsValue,
25+
extra,
2426
};
2527
this.dispatchEvent('pre-connect', mapDefinition);
2628
this.createMarker = this.createDrawingFactory('marker', this.markers, this.doCreateMarker.bind(this));
@@ -45,6 +47,7 @@ class default_1 extends Controller {
4547
circles: [...this.circles.values()],
4648
rectangles: [...this.rectangles.values()],
4749
infoWindows: this.infoWindows,
50+
extra,
4851
});
4952
this.isConnected = true;
5053
}
@@ -130,6 +133,7 @@ default_1.values = {
130133
circles: Array,
131134
rectangles: Array,
132135
options: Object,
136+
extra: Object,
133137
};
134138

135139
export { IconTypes, default_1 as default };

src/Map/assets/src/abstract_map_controller.ts

Lines changed: 21 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@ export type Point = { lat: number; lng: number };
1313
export type Identifier = string;
1414
export type WithIdentifier<T extends Record<string, unknown>> = T & { '@id': Identifier };
1515

16+
type ExtraData = Record<string, unknown>;
17+
1618
export const IconTypes = {
1719
Url: 'url',
1820
Svg: 'svg',
@@ -46,6 +48,13 @@ export type MapDefinition<MapOptions, BridgeMapOptions> = {
4648
* These options are specific to the Map Bridge, and can be defined through `ux:map:pre-connect` event.
4749
*/
4850
bridgeOptions?: BridgeMapOptions;
51+
/**
52+
* Extra data defined by the developer.
53+
* They are not directly used by the Stimulus controller, but they can be used by the developer with event listeners:
54+
* - `ux:map:pre-connect`
55+
* - `ux:map:connect`
56+
*/
57+
extra: ExtraData;
4958
};
5059

5160
export type MarkerDefinition<BridgeMarkerOptions, BridgeInfoWindowOptions> = WithIdentifier<{
@@ -69,7 +78,7 @@ export type MarkerDefinition<BridgeMarkerOptions, BridgeInfoWindowOptions> = Wit
6978
* - `ux:map:marker:before-create`
7079
* - `ux:map:marker:after-create`
7180
*/
72-
extra: Record<string, unknown>;
81+
extra: ExtraData;
7382
}>;
7483

7584
export type PolygonDefinition<BridgePolygonOptions, BridgeInfoWindowOptions> = WithIdentifier<{
@@ -92,7 +101,7 @@ export type PolygonDefinition<BridgePolygonOptions, BridgeInfoWindowOptions> = W
92101
* - `ux:map:polygon:before-create`
93102
* - `ux:map:polygon:after-create`
94103
*/
95-
extra: Record<string, unknown>;
104+
extra: ExtraData;
96105
}>;
97106

98107
export type PolylineDefinition<BridgePolylineOptions, BridgeInfoWindowOptions> = WithIdentifier<{
@@ -115,7 +124,7 @@ export type PolylineDefinition<BridgePolylineOptions, BridgeInfoWindowOptions> =
115124
* - `ux:map:polyline:before-create`
116125
* - `ux:map:polyline:after-create`
117126
*/
118-
extra: Record<string, unknown>;
127+
extra: ExtraData;
119128
}>;
120129

121130
export type CircleDefinition<BridgeCircleOptions, BridgeInfoWindowOptions> = WithIdentifier<{
@@ -139,7 +148,7 @@ export type CircleDefinition<BridgeCircleOptions, BridgeInfoWindowOptions> = Wit
139148
* - `ux:map:circle:before-create`
140149
* - `ux:map:circle:after-create`
141150
*/
142-
extra: Record<string, unknown>;
151+
extra: ExtraData;
143152
}>;
144153

145154
export type RectangleDefinition<BridgeRectangleOptions, BridgeInfoWindowOptions> = WithIdentifier<{
@@ -163,7 +172,7 @@ export type RectangleDefinition<BridgeRectangleOptions, BridgeInfoWindowOptions>
163172
* - `ux:map:rectangle:before-create`
164173
* - `ux:map:rectangle:after-create`
165174
*/
166-
extra: Record<string, unknown>;
175+
extra: ExtraData;
167176
}>;
168177

169178
export type InfoWindowDefinition<BridgeInfoWindowOptions> = {
@@ -188,7 +197,7 @@ export type InfoWindowDefinition<BridgeInfoWindowOptions> = {
188197
* - `ux:map:info-window:before-create`
189198
* - `ux:map:info-window:after-create`
190199
*/
191-
extra: Record<string, unknown>;
200+
extra: ExtraData;
192201
};
193202

194203
export default abstract class<
@@ -219,6 +228,7 @@ export default abstract class<
219228
circles: Array,
220229
rectangles: Array,
221230
options: Object,
231+
extra: Object,
222232
};
223233

224234
declare centerValue: Point | null;
@@ -230,6 +240,7 @@ export default abstract class<
230240
declare circlesValue: Array<CircleDefinition<BridgeCircleOptions, BridgeInfoWindowOptions>>;
231241
declare rectanglesValue: Array<RectangleDefinition<BridgeRectangleOptions, BridgeInfoWindowOptions>>;
232242
declare optionsValue: MapOptions;
243+
declare extraValue: Record<string, unknown>;
233244

234245
declare hasCenterValue: boolean;
235246
declare hasZoomValue: boolean;
@@ -240,6 +251,7 @@ export default abstract class<
240251
declare hasCirclesValue: boolean;
241252
declare hasRectanglesValue: boolean;
242253
declare hasOptionsValue: boolean;
254+
declare hasExtraValue: boolean;
243255

244256
protected map: BridgeMap;
245257
protected markers = new Map<Identifier, BridgeMarker>();
@@ -259,10 +271,12 @@ export default abstract class<
259271
protected abstract dispatchEvent(name: string, payload: Record<string, unknown>): void;
260272

261273
connect() {
274+
const extra = this.hasExtraValue ? this.extraValue : {};
262275
const mapDefinition: MapDefinition<MapOptions, BridgeMapOptions> = {
263276
center: this.hasCenterValue ? this.centerValue : null,
264277
zoom: this.hasZoomValue ? this.zoomValue : null,
265278
options: this.optionsValue,
279+
extra,
266280
};
267281
this.dispatchEvent('pre-connect', mapDefinition);
268282

@@ -291,6 +305,7 @@ export default abstract class<
291305
circles: [...this.circles.values()],
292306
rectangles: [...this.rectangles.values()],
293307
infoWindows: this.infoWindows,
308+
extra,
294309
});
295310

296311
this.isConnected = true;

src/Map/doc/index.rst

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -713,6 +713,39 @@ On the JavaScript side, you can access your extra data via the
713713
// ...
714714
}
715715
716+
.. versionadded:: 2.27
717+
718+
The ``Map`` class now has an ``extra`` property, which can be accessed in the ``ux:map:pre-connect`` and ``ux:map:connect`` events::
719+
720+
$map = new Map(/* ... */, extra: [
721+
'foo' => 'bar',
722+
]);
723+
// or
724+
$map->extra([
725+
'foo' => 'bar',
726+
]);
727+
728+
.. code-block:: javascript
729+
730+
// assets/controllers/mymap_controller.js
731+
732+
import { Controller } from '@hotwired/stimulus';
733+
734+
export default class extends Controller {
735+
736+
// ...
737+
738+
_onPreConnect(event) {
739+
console.log(event.detail.extra);
740+
// { foo: 'bar', ... }
741+
}
742+
743+
_onConnect(event) {
744+
console.log(event.detail.extra);
745+
// { foo: 'bar', ... }
746+
}
747+
}
748+
716749
.. _map-live-component:
717750

718751
Usage with Live Components

src/Map/src/Bridge/Google/assets/dist/map_controller.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,10 +18,12 @@ class default_1 extends Controller {
1818
this.isConnected = false;
1919
}
2020
connect() {
21+
const extra = this.hasExtraValue ? this.extraValue : {};
2122
const mapDefinition = {
2223
center: this.hasCenterValue ? this.centerValue : null,
2324
zoom: this.hasZoomValue ? this.zoomValue : null,
2425
options: this.optionsValue,
26+
extra,
2527
};
2628
this.dispatchEvent('pre-connect', mapDefinition);
2729
this.createMarker = this.createDrawingFactory('marker', this.markers, this.doCreateMarker.bind(this));
@@ -46,6 +48,7 @@ class default_1 extends Controller {
4648
circles: [...this.circles.values()],
4749
rectangles: [...this.rectangles.values()],
4850
infoWindows: this.infoWindows,
51+
extra,
4952
});
5053
this.isConnected = true;
5154
}
@@ -131,6 +134,7 @@ default_1.values = {
131134
circles: Array,
132135
rectangles: Array,
133136
options: Object,
137+
extra: Object,
134138
};
135139

136140
let _google;

src/Map/src/Bridge/Google/tests/GoogleRendererTest.php

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -188,5 +188,16 @@ public function renderIcon(string $name, array $attributes = []): string
188188
->addMarker(new Marker(position: new Point(45.7640, 4.8357), title: 'Lyon', icon: Icon::ux('fa:map-marker')->width(32)->height(32)))
189189
->addMarker(new Marker(position: new Point(45.8566, 2.3522), title: 'Dijon', icon: Icon::svg('<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24">...</svg>'))),
190190
];
191+
192+
yield 'with map extra data' => [
193+
'renderer' => new GoogleRenderer(new StimulusHelper(null), new UxIconRenderer(null), apiKey: 'api_key'),
194+
'map' => (new Map())
195+
->center(new Point(48.8566, 2.3522))
196+
->zoom(12)
197+
->extra([
198+
'foo' => 'bar',
199+
'baz' => 42,
200+
]),
201+
];
191202
}
192203
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
<!-- This HTML has been prettified for testing purposes, and may not represent the actual HTML output.
2+
Run "php vendor/bin/phpunit -d --update-snapshots" to update the snapshot. -->
3+
<div
4+
data-controller="symfony--ux-google-map--map"
5+
data-symfony--ux-google-map--map-provider-options-value="{&quot;apiKey&quot;:&quot;api_key&quot;}"
6+
data-symfony--ux-google-map--map-center-value="{&quot;lat&quot;:48.8566,&quot;lng&quot;:2.3522}"
7+
data-symfony--ux-google-map--map-zoom-value="12"
8+
data-symfony--ux-google-map--map-fit-bounds-to-markers-value="false"
9+
data-symfony--ux-google-map--map-options-value="{&quot;mapId&quot;:null,&quot;gestureHandling&quot;:&quot;auto&quot;,&quot;backgroundColor&quot;:null,&quot;disableDoubleClickZoom&quot;:false,&quot;zoomControlOptions&quot;:{&quot;position&quot;:22},&quot;mapTypeControlOptions&quot;:{&quot;mapTypeIds&quot;:[],&quot;position&quot;:14,&quot;style&quot;:0},&quot;streetViewControlOptions&quot;:{&quot;position&quot;:22},&quot;fullscreenControlOptions&quot;:{&quot;position&quot;:20},&quot;@provider&quot;:&quot;google&quot;}"
10+
data-symfony--ux-google-map--map-markers-value="[]"
11+
data-symfony--ux-google-map--map-polygons-value="[]"
12+
data-symfony--ux-google-map--map-polylines-value="[]"
13+
data-symfony--ux-google-map--map-circles-value="[]"
14+
data-symfony--ux-google-map--map-rectangles-value="[]"
15+
data-symfony--ux-google-map--map-extra-value="{&quot;foo&quot;:&quot;bar&quot;,&quot;baz&quot;:42}"
16+
></div>

src/Map/src/Bridge/Leaflet/assets/dist/map_controller.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,10 +19,12 @@ class default_1 extends Controller {
1919
this.isConnected = false;
2020
}
2121
connect() {
22+
const extra = this.hasExtraValue ? this.extraValue : {};
2223
const mapDefinition = {
2324
center: this.hasCenterValue ? this.centerValue : null,
2425
zoom: this.hasZoomValue ? this.zoomValue : null,
2526
options: this.optionsValue,
27+
extra,
2628
};
2729
this.dispatchEvent('pre-connect', mapDefinition);
2830
this.createMarker = this.createDrawingFactory('marker', this.markers, this.doCreateMarker.bind(this));
@@ -47,6 +49,7 @@ class default_1 extends Controller {
4749
circles: [...this.circles.values()],
4850
rectangles: [...this.rectangles.values()],
4951
infoWindows: this.infoWindows,
52+
extra,
5053
});
5154
this.isConnected = true;
5255
}
@@ -132,6 +135,7 @@ default_1.values = {
132135
circles: Array,
133136
rectangles: Array,
134137
options: Object,
138+
extra: Object,
135139
};
136140

137141
class map_controller extends default_1 {

0 commit comments

Comments
 (0)