@factorialco/f0-react 7.20.0 → 7.21.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.
@@ -0,0 +1,281 @@
1
+ import { n as L } from "./F0CanvasPanel-DdPS8Xoa.js";
2
+ const O = (e) => e.map(([n, s]) => ({ lat: s, lng: n })), x = (e, n) => ({
3
+ strokeColor: n && e.hover?.color || e.color,
4
+ strokeWeight: n && e.hover?.width || e.width,
5
+ strokeOpacity: e.dashed ? 0 : (n ? e.hover?.opacity : void 0) ?? e.opacity,
6
+ // Google has no dash array on a stroke: a dashed line is an invisible stroke
7
+ // carrying repeated dot symbols, spaced to match MapLibre's [1.5, 2.8].
8
+ icons: e.dashed ? [
9
+ {
10
+ icon: {
11
+ path: "M 0,-1 0,1",
12
+ strokeOpacity: (n ? e.hover?.opacity : void 0) ?? e.opacity,
13
+ strokeWeight: n && e.hover?.width || e.width,
14
+ scale: 1
15
+ },
16
+ offset: "0",
17
+ repeat: `${(n && e.hover?.width || e.width) * 2.9}px`
18
+ }
19
+ ] : void 0
20
+ }), T = (e) => {
21
+ let n = [];
22
+ const s = () => {
23
+ for (const a of n)
24
+ a.listeners.forEach((i) => i.remove()), a.polyline.setMap(null);
25
+ n = [];
26
+ };
27
+ return {
28
+ set: (a, i) => {
29
+ s(), n = a.map((m) => {
30
+ const l = new google.maps.Polyline({
31
+ map: e,
32
+ path: O(m.coordinates),
33
+ clickable: !!i,
34
+ ...x(m, !1)
35
+ }), p = [];
36
+ return i && p.push(
37
+ l.addListener("mouseover", () => {
38
+ l.setOptions(x(m, !0)), e.setOptions({ draggableCursor: "pointer" });
39
+ }),
40
+ l.addListener("mouseout", () => {
41
+ l.setOptions(x(m, !1)), e.setOptions({ draggableCursor: null });
42
+ }),
43
+ l.addListener("click", () => i(m.id))
44
+ ), { line: m, polyline: l, listeners: p };
45
+ });
46
+ },
47
+ destroy: s
48
+ };
49
+ }, w = "__f0GoogleMapsReady";
50
+ let f;
51
+ const k = (e) => f || (f = new Promise((n, s) => {
52
+ const a = window;
53
+ a[w] = () => {
54
+ Reflect.deleteProperty(a, w), n();
55
+ };
56
+ const i = document.createElement("script");
57
+ i.async = !0, i.src = `https://maps.googleapis.com/maps/api/js?key=${encodeURIComponent(e)}&v=weekly&libraries=maps&callback=${w}`, i.onerror = () => {
58
+ f = void 0, s(new Error("F0Map: the Google Maps JavaScript API failed to load."));
59
+ }, document.head.appendChild(i);
60
+ }), f), E = (e) => {
61
+ const n = /* @__PURE__ */ new Set(), s = /* @__PURE__ */ new Set();
62
+ let a, i = !1, m = !1;
63
+ const l = (t, c) => {
64
+ const o = c.fromLatLngToDivPixel(
65
+ new google.maps.LatLng(t.at[1], t.at[0])
66
+ );
67
+ o && (t.element.style.transform = `translate(${o.x}px, ${o.y}px) translate(-50%, -50%)`);
68
+ };
69
+ class p extends google.maps.OverlayView {
70
+ onAdd() {
71
+ a = document.createElement("div"), a.style.cssText = "position:absolute;left:0;top:0;width:0;height:0";
72
+ for (const c of n)
73
+ a.appendChild(c.element);
74
+ this.getPanes()?.overlayMouseTarget.appendChild(a);
75
+ }
76
+ draw() {
77
+ const c = this.getProjection();
78
+ if (c) {
79
+ for (const o of n)
80
+ l(o, c);
81
+ i || (i = !0, s.forEach((o) => o()));
82
+ }
83
+ }
84
+ onRemove() {
85
+ a?.remove(), a = void 0;
86
+ }
87
+ }
88
+ const g = new p();
89
+ g.setMap(e);
90
+ const r = () => m ? void 0 : g.getProjection();
91
+ return {
92
+ add: (t, c) => {
93
+ const o = { element: t, at: c };
94
+ n.add(o), t.style.position = "absolute", a?.appendChild(t);
95
+ const d = r();
96
+ return d && l(o, d), {
97
+ setPosition: (y) => {
98
+ o.at = y;
99
+ const h = r();
100
+ h && l(o, h);
101
+ },
102
+ remove: () => {
103
+ n.delete(o), t.remove();
104
+ }
105
+ };
106
+ },
107
+ project: (t) => {
108
+ const c = r();
109
+ if (!c)
110
+ return null;
111
+ const o = c.fromLatLngToContainerPixel(
112
+ new google.maps.LatLng(t[1], t[0])
113
+ );
114
+ return o ? { x: o.x, y: o.y } : null;
115
+ },
116
+ unproject: (t) => {
117
+ const c = r();
118
+ if (!c)
119
+ return null;
120
+ const o = c.fromContainerPixelToLatLng(
121
+ new google.maps.Point(t.x, t.y)
122
+ );
123
+ return o ? [o.lng(), o.lat()] : null;
124
+ },
125
+ onReady: (t) => i ? (t(), () => {
126
+ }) : (s.add(t), () => s.delete(t)),
127
+ isReady: () => i,
128
+ destroy: () => {
129
+ m = !0, i = !1, s.clear();
130
+ for (const t of n)
131
+ t.element.remove();
132
+ n.clear(), g.setMap(null);
133
+ }
134
+ };
135
+ }, A = {
136
+ globeProjection: !1,
137
+ /**
138
+ * The getters report the destination in the same tick, so a flight in
139
+ * progress cannot be read even though the renderer glides.
140
+ */
141
+ observableFlight: !1
142
+ }, C = (e) => e, v = ([e, n]) => ({ lat: n, lng: e }), $ = {
143
+ move: "bounds_changed",
144
+ zoom: "zoom_changed",
145
+ click: "click",
146
+ styled: "idle"
147
+ }, b = 5.3, R = 11 - b, _ = (e) => {
148
+ const n = document.createElement("div");
149
+ n.style.cssText = "position:absolute;inset:0", e.container.appendChild(n);
150
+ const s = new google.maps.Map(n, {
151
+ center: v(e.center),
152
+ zoom: e.zoom,
153
+ minZoom: e.minZoom,
154
+ maxZoom: e.maxZoom,
155
+ // No `mapId` deliberately: with one, `styles` is ignored and the theme is
156
+ // immutable after the first render, so a light/dark swap means a teardown.
157
+ styles: C(e.style),
158
+ disableDefaultUI: !0,
159
+ gestureHandling: e.interactive ? e.cooperativeGestures ? "cooperative" : "greedy" : "none"
160
+ }), a = E(s), i = T(s);
161
+ let m = !1, l, p;
162
+ const g = (r) => {
163
+ s.panTo(v(r.center)), r.zoom !== void 0 && s.setZoom(r.zoom);
164
+ };
165
+ return {
166
+ provider: "google",
167
+ capabilities: A,
168
+ native: () => s,
169
+ isAlive: () => !m,
170
+ destroy: () => {
171
+ m = !0, i.destroy(), p?.remove(), a.destroy(), n.remove();
172
+ },
173
+ on: (r, t) => {
174
+ if (r === "ready")
175
+ return a.onReady(t);
176
+ if (r === "resize") {
177
+ const o = new ResizeObserver(() => t());
178
+ return o.observe(e.container), () => o.disconnect();
179
+ }
180
+ if (r === "error") {
181
+ const o = window, d = o.gm_authFailure;
182
+ return o.gm_authFailure = t, () => {
183
+ o.gm_authFailure = d;
184
+ };
185
+ }
186
+ const c = s.addListener($[r], t);
187
+ return () => c.remove();
188
+ },
189
+ project: a.project,
190
+ unproject: a.unproject,
191
+ getZoom: () => s.getZoom() ?? e.zoom,
192
+ getCenter: () => {
193
+ const r = s.getCenter();
194
+ return r ? [r.lng(), r.lat()] : e.center;
195
+ },
196
+ jumpTo: (r) => {
197
+ s.moveCamera({
198
+ center: v(r.center),
199
+ ...r.zoom === void 0 ? {} : { zoom: r.zoom }
200
+ });
201
+ },
202
+ easeTo: g,
203
+ // No coupled pan+zoom arc exists here; the renderer glides on its own.
204
+ flyTo: g,
205
+ fitCoordinates: (r, t) => {
206
+ const c = new google.maps.LatLngBounds();
207
+ r.forEach((d) => c.extend(v(d)));
208
+ const o = t?.gutter ?? 0;
209
+ if (s.fitBounds(c, {
210
+ top: o,
211
+ right: o,
212
+ bottom: o,
213
+ left: o
214
+ }), t?.maxZoom !== void 0) {
215
+ const d = s.getZoom();
216
+ d !== void 0 && d > t.maxZoom && s.setZoom(t.maxZoom);
217
+ }
218
+ },
219
+ // Google has no `cameraForBounds`: the pixel box at the current zoom gives
220
+ // the scale change to fit, which is a zoom delta.
221
+ cameraForCoordinates: (r, t) => {
222
+ if (r.length === 0)
223
+ return null;
224
+ const c = r.map((u) => a.project(u));
225
+ if (c.some((u) => u === null))
226
+ return null;
227
+ const o = c.map((u) => u.x), d = c.map((u) => u.y), y = a.unproject({
228
+ x: (Math.min(...o) + Math.max(...o)) / 2,
229
+ y: (Math.min(...d) + Math.max(...d)) / 2
230
+ });
231
+ if (!y)
232
+ return null;
233
+ const h = t?.gutter ?? 0, z = Math.max(Math.max(...o) - Math.min(...o), 1), P = Math.max(Math.max(...d) - Math.min(...d), 1), M = {
234
+ width: Math.max(e.container.clientWidth - h * 2, 1),
235
+ height: Math.max(e.container.clientHeight - h * 2, 1)
236
+ }, Z = Math.min(M.width / z, M.height / P), j = Math.min(
237
+ (s.getZoom() ?? e.zoom) + Math.log2(Z),
238
+ t?.maxZoom ?? 1 / 0
239
+ );
240
+ return { center: y, zoom: j };
241
+ },
242
+ addDomMarker: a.add,
243
+ setLines: (r, t) => i.set(r, t?.onClick),
244
+ setCurrentLocation: (r) => {
245
+ if (!r) {
246
+ p?.remove(), p = void 0, l = void 0;
247
+ return;
248
+ }
249
+ if (!l) {
250
+ l = document.createElement("div"), l.style.cssText = [
251
+ `width:${b * 2}px`,
252
+ `height:${b * 2}px`,
253
+ "border-radius:50%",
254
+ `background:hsl(${L.malibu[60]})`,
255
+ `box-shadow:0 0 0 ${R}px hsl(${L.malibu[50]} / 0.3)`,
256
+ "pointer-events:none"
257
+ ].join(";"), p = a.add(l, r);
258
+ return;
259
+ }
260
+ p?.setPosition(r);
261
+ },
262
+ zoomIn: () => s.setZoom((s.getZoom() ?? e.zoom) + 1),
263
+ zoomOut: () => s.setZoom((s.getZoom() ?? e.zoom) - 1),
264
+ // Google re-reads its container on its own; there is nothing to poke.
265
+ resize: () => {
266
+ },
267
+ applyStyle: (r) => s.setOptions({ styles: C(r) }),
268
+ setGlobeProjection: () => {
269
+ }
270
+ };
271
+ }, G = async (e) => {
272
+ if (!e?.apiKey)
273
+ throw new Error(
274
+ "F0Map: the google provider needs an apiKey on <F0Provider map={{ ... }}>."
275
+ );
276
+ return await k(e.apiKey), _;
277
+ };
278
+ export {
279
+ _ as createGoogleAdapter,
280
+ G as loadGoogleAdapter
281
+ };