@sanity/google-maps-input 3.0.2-0 → 4.0.0-beta.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,1043 @@
1
+ import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
2
+ import * as React from 'react';
3
+ import React__default, { useState, useEffect } from 'react';
4
+ import { uniqueId } from 'lodash';
5
+ import { Card, Box, Text, Code, TextInput, Stack, Grid, Button, Dialog } from '@sanity/ui';
6
+ import { EditIcon, TrashIcon } from '@sanity/icons';
7
+ import { ChangeIndicator, setIfMissing, set, unset, useUserColor, getAnnotationAtPath, DiffTooltip, definePlugin } from 'sanity';
8
+ import { styled } from 'styled-components';
9
+ const callbackName = "___sanity_googleMapsApiCallback";
10
+ const authFailureCallbackName = "gm_authFailure";
11
+ let AuthError$1 = class AuthError extends Error {};
12
+ function _loadGoogleMapsApi(config) {
13
+ return new Promise((resolve, reject) => {
14
+ window[authFailureCallbackName] = () => {
15
+ reject(new AuthError$1("Authentication error when loading Google Maps API."));
16
+ };
17
+ window[callbackName] = () => {
18
+ resolve(window.google.maps);
19
+ };
20
+ const script = document.createElement("script");
21
+ script.onerror = (event, source, lineno, colno, error) => reject(new Error(coeerceError(event, error)));
22
+ script.src = "https://maps.googleapis.com/maps/api/js?key=".concat(config.apiKey, "&libraries=places&callback=").concat(callbackName, "&language=").concat(config.locale);
23
+ document.getElementsByTagName("head")[0].appendChild(script);
24
+ }).finally(() => {
25
+ delete window[callbackName];
26
+ delete window[authFailureCallbackName];
27
+ });
28
+ }
29
+ let memo = null;
30
+ function loadGoogleMapsApi(config) {
31
+ if (memo) {
32
+ return memo;
33
+ }
34
+ memo = _loadGoogleMapsApi(config);
35
+ memo.catch(() => {
36
+ memo = null;
37
+ });
38
+ return memo;
39
+ }
40
+ function coeerceError(event, error) {
41
+ if (error) {
42
+ return error.message;
43
+ }
44
+ if (typeof event === "string") {
45
+ return event;
46
+ }
47
+ return isErrorEvent(event) ? event.message : "Failed to load Google Maps API";
48
+ }
49
+ function isErrorEvent(event) {
50
+ if (typeof event !== "object" || event === null) {
51
+ return false;
52
+ }
53
+ if (!("message" in event)) {
54
+ return false;
55
+ }
56
+ return typeof event.message === "string";
57
+ }
58
+ function LoadError(props) {
59
+ var _a;
60
+ return /* @__PURE__ */jsxs(Card, {
61
+ tone: "critical",
62
+ radius: 1,
63
+ children: [/* @__PURE__ */jsx(Box, {
64
+ as: "header",
65
+ paddingX: 4,
66
+ paddingTop: 4,
67
+ paddingBottom: 1,
68
+ children: /* @__PURE__ */jsx(Text, {
69
+ as: "h2",
70
+ weight: "bold",
71
+ children: "Google Maps failed to load"
72
+ })
73
+ }), /* @__PURE__ */jsx(Box, {
74
+ paddingX: 4,
75
+ paddingTop: 4,
76
+ paddingBottom: 1,
77
+ children: props.isAuthError ? /* @__PURE__ */jsx(AuthError, {}) : /* @__PURE__ */jsxs(Fragment, {
78
+ children: [/* @__PURE__ */jsx(Text, {
79
+ as: "h3",
80
+ children: "Error details:"
81
+ }), /* @__PURE__ */jsx("pre", {
82
+ children: /* @__PURE__ */jsx(Code, {
83
+ size: 1,
84
+ children: "error" in props && ((_a = props.error) == null ? void 0 : _a.message)
85
+ })
86
+ })]
87
+ })
88
+ })]
89
+ });
90
+ }
91
+ function AuthError() {
92
+ return /* @__PURE__ */jsxs(Text, {
93
+ children: [/* @__PURE__ */jsx("p", {
94
+ children: "The error appears to be related to authentication"
95
+ }), /* @__PURE__ */jsx("p", {
96
+ children: "Common causes include:"
97
+ }), /* @__PURE__ */jsxs("ul", {
98
+ children: [/* @__PURE__ */jsx("li", {
99
+ children: "Incorrect API key"
100
+ }), /* @__PURE__ */jsx("li", {
101
+ children: "Referer not allowed"
102
+ }), /* @__PURE__ */jsx("li", {
103
+ children: "Missing authentication scope"
104
+ })]
105
+ }), /* @__PURE__ */jsx("p", {
106
+ children: "Check the browser developer tools for more information."
107
+ })]
108
+ });
109
+ }
110
+ const browserLocale = typeof window !== "undefined" && window.navigator.language || "en";
111
+ function useLoadGoogleMapsApi(config) {
112
+ const locale = config.defaultLocale || browserLocale || "en-US";
113
+ const [state, setState] = useState({
114
+ type: "loading"
115
+ });
116
+ useEffect(() => {
117
+ loadGoogleMapsApi({
118
+ locale,
119
+ apiKey: config.apiKey
120
+ }).then(api => setState({
121
+ type: "loaded",
122
+ api
123
+ }), err => setState({
124
+ type: "error",
125
+ error: {
126
+ type: err instanceof AuthError$1 ? "authError" : "loadError",
127
+ message: err.message
128
+ }
129
+ }));
130
+ }, [locale, config.apiKey]);
131
+ return state;
132
+ }
133
+ function GoogleMapsLoadProxy(props) {
134
+ const loadState = useLoadGoogleMapsApi(props.config);
135
+ switch (loadState.type) {
136
+ case "error":
137
+ return /* @__PURE__ */jsx(LoadError, {
138
+ error: loadState.error,
139
+ isAuthError: loadState.error.type === "authError"
140
+ });
141
+ case "loading":
142
+ return /* @__PURE__ */jsx("div", {
143
+ children: "Loading Google Maps API"
144
+ });
145
+ case "loaded":
146
+ return props.children(loadState.api);
147
+ default:
148
+ return null;
149
+ }
150
+ }
151
+ var __freeze$3 = Object.freeze;
152
+ var __defProp$9 = Object.defineProperty;
153
+ var __template$3 = (cooked, raw) => __freeze$3(__defProp$9(cooked, "raw", {
154
+ value: __freeze$3(raw || cooked.slice())
155
+ }));
156
+ var _a$3;
157
+ const WrapperContainer = styled.div(_a$3 || (_a$3 = __template$3(["\n position: absolute;\n right: 10px;\n top: 10px;\n width: 220px;\n"])));
158
+ var __defProp$8 = Object.defineProperty;
159
+ var __defNormalProp$5 = (obj, key, value) => key in obj ? __defProp$8(obj, key, {
160
+ enumerable: true,
161
+ configurable: true,
162
+ writable: true,
163
+ value
164
+ }) : obj[key] = value;
165
+ var __publicField$5 = (obj, key, value) => {
166
+ __defNormalProp$5(obj, typeof key !== "symbol" ? key + "" : key, value);
167
+ return value;
168
+ };
169
+ class SearchInput extends React.PureComponent {
170
+ constructor() {
171
+ super(...arguments);
172
+ __publicField$5(this, "searchInputRef", React.createRef());
173
+ __publicField$5(this, "autoComplete");
174
+ __publicField$5(this, "handleChange", () => {
175
+ if (!this.autoComplete) {
176
+ return;
177
+ }
178
+ this.props.onChange(this.autoComplete.getPlace());
179
+ if (this.searchInputRef.current) {
180
+ this.searchInputRef.current.value = "";
181
+ }
182
+ });
183
+ }
184
+ componentDidMount() {
185
+ const input = this.searchInputRef.current;
186
+ if (!input) {
187
+ return;
188
+ }
189
+ const {
190
+ api,
191
+ map
192
+ } = this.props;
193
+ const {
194
+ Circle,
195
+ places,
196
+ event
197
+ } = api;
198
+ const searchBounds = new Circle({
199
+ center: map.getCenter(),
200
+ radius: 100
201
+ }).getBounds();
202
+ this.autoComplete = new places.Autocomplete(input, {
203
+ bounds: searchBounds,
204
+ types: []
205
+ // return all kinds of places
206
+ });
207
+
208
+ event.addListener(this.autoComplete, "place_changed", this.handleChange);
209
+ }
210
+ render() {
211
+ return /* @__PURE__ */jsx(WrapperContainer, {
212
+ children: /* @__PURE__ */jsx(TextInput, {
213
+ name: "place",
214
+ ref: this.searchInputRef,
215
+ placeholder: "Search for place or address",
216
+ padding: 4
217
+ })
218
+ });
219
+ }
220
+ }
221
+ function latLngAreEqual(latLng1, latLng2) {
222
+ const lat1 = typeof latLng1.lat === "function" ? latLng1.lat() : latLng1.lat;
223
+ const lng1 = typeof latLng1.lng === "function" ? latLng1.lng() : latLng1.lng;
224
+ const lat2 = typeof latLng2.lat === "function" ? latLng2.lat() : latLng2.lat;
225
+ const lng2 = typeof latLng2.lng === "function" ? latLng2.lng() : latLng2.lng;
226
+ return lat1 === lat2 && lng1 === lng2;
227
+ }
228
+ var __freeze$2 = Object.freeze;
229
+ var __defProp$7 = Object.defineProperty;
230
+ var __template$2 = (cooked, raw) => __freeze$2(__defProp$7(cooked, "raw", {
231
+ value: __freeze$2(raw || cooked.slice())
232
+ }));
233
+ var _a$2;
234
+ const MapContainer = styled.div(_a$2 || (_a$2 = __template$2(["\n position: absolute;\n top: 0;\n left: 0;\n height: 100%;\n width: 100%;\n box-sizing: border-box;\n"])));
235
+ var __defProp$6 = Object.defineProperty;
236
+ var __defNormalProp$4 = (obj, key, value) => key in obj ? __defProp$6(obj, key, {
237
+ enumerable: true,
238
+ configurable: true,
239
+ writable: true,
240
+ value
241
+ }) : obj[key] = value;
242
+ var __publicField$4 = (obj, key, value) => {
243
+ __defNormalProp$4(obj, typeof key !== "symbol" ? key + "" : key, value);
244
+ return value;
245
+ };
246
+ class GoogleMap extends React__default.PureComponent {
247
+ constructor() {
248
+ super(...arguments);
249
+ __publicField$4(this, "state", {
250
+ map: void 0
251
+ });
252
+ __publicField$4(this, "clickHandler");
253
+ __publicField$4(this, "mapRef", React__default.createRef());
254
+ __publicField$4(this, "mapEl", null);
255
+ __publicField$4(this, "attachClickHandler", () => {
256
+ const map = this.state.map;
257
+ if (!map) {
258
+ return;
259
+ }
260
+ const {
261
+ api,
262
+ onClick
263
+ } = this.props;
264
+ const {
265
+ event
266
+ } = api;
267
+ if (this.clickHandler) {
268
+ this.clickHandler.remove();
269
+ }
270
+ if (onClick) {
271
+ this.clickHandler = event.addListener(map, "click", onClick);
272
+ }
273
+ });
274
+ __publicField$4(this, "setMapElement", element => {
275
+ if (element && element !== this.mapEl) {
276
+ const map = this.constructMap(element);
277
+ this.setState({
278
+ map
279
+ }, this.attachClickHandler);
280
+ }
281
+ this.mapEl = element;
282
+ });
283
+ }
284
+ componentDidMount() {
285
+ this.attachClickHandler();
286
+ }
287
+ componentDidUpdate(prevProps) {
288
+ const map = this.state.map;
289
+ if (!map) {
290
+ return;
291
+ }
292
+ const {
293
+ onClick,
294
+ location,
295
+ bounds
296
+ } = this.props;
297
+ if (prevProps.onClick !== onClick) {
298
+ this.attachClickHandler();
299
+ }
300
+ if (!latLngAreEqual(prevProps.location, location)) {
301
+ map.panTo(this.getCenter());
302
+ }
303
+ if (bounds && (!prevProps.bounds || !bounds.equals(prevProps.bounds))) {
304
+ map.fitBounds(bounds);
305
+ }
306
+ }
307
+ componentWillUnmount() {
308
+ if (this.clickHandler) {
309
+ this.clickHandler.remove();
310
+ }
311
+ }
312
+ getCenter() {
313
+ const {
314
+ location,
315
+ api
316
+ } = this.props;
317
+ return new api.LatLng(location.lat, location.lng);
318
+ }
319
+ constructMap(el) {
320
+ const {
321
+ defaultZoom,
322
+ api,
323
+ mapTypeControl,
324
+ controlSize,
325
+ bounds,
326
+ scrollWheel
327
+ } = this.props;
328
+ const map = new api.Map(el, {
329
+ zoom: defaultZoom,
330
+ center: this.getCenter(),
331
+ scrollwheel: scrollWheel,
332
+ streetViewControl: false,
333
+ mapTypeControl,
334
+ controlSize
335
+ });
336
+ if (bounds) {
337
+ map.fitBounds(bounds);
338
+ }
339
+ return map;
340
+ }
341
+ render() {
342
+ const {
343
+ children
344
+ } = this.props;
345
+ const {
346
+ map
347
+ } = this.state;
348
+ return /* @__PURE__ */jsxs(Fragment, {
349
+ children: [/* @__PURE__ */jsx(MapContainer, {
350
+ ref: this.setMapElement
351
+ }), children && map ? children(map) : null]
352
+ });
353
+ }
354
+ }
355
+ __publicField$4(GoogleMap, "defaultProps", {
356
+ defaultZoom: 8,
357
+ scrollWheel: true
358
+ });
359
+ var __defProp$5 = Object.defineProperty;
360
+ var __defNormalProp$3 = (obj, key, value) => key in obj ? __defProp$5(obj, key, {
361
+ enumerable: true,
362
+ configurable: true,
363
+ writable: true,
364
+ value
365
+ }) : obj[key] = value;
366
+ var __publicField$3 = (obj, key, value) => {
367
+ __defNormalProp$3(obj, typeof key !== "symbol" ? key + "" : key, value);
368
+ return value;
369
+ };
370
+ const markerPath = "M 3.052 3.7 C 1.56 5.293 0.626 7.612 0.663 9.793 C 0.738 14.352 2.793 16.077 6.078 22.351 C 7.263 25.111 8.497 28.032 9.672 32.871 C 9.835 33.584 9.994 34.246 10.069 34.305 C 10.143 34.362 10.301 33.697 10.465 32.983 C 11.639 28.145 12.875 25.226 14.059 22.466 C 17.344 16.192 19.398 14.466 19.474 9.908 C 19.511 7.727 18.574 5.405 17.083 3.814 C 15.379 1.994 12.809 0.649 10.069 0.593 C 7.328 0.536 4.756 1.882 3.052 3.7 Z";
371
+ class Marker extends React.PureComponent {
372
+ constructor() {
373
+ super(...arguments);
374
+ __publicField$3(this, "marker");
375
+ __publicField$3(this, "eventHandlers", {});
376
+ }
377
+ componentDidMount() {
378
+ const {
379
+ position,
380
+ api,
381
+ map,
382
+ onMove,
383
+ zIndex,
384
+ opacity,
385
+ label,
386
+ markerRef,
387
+ color
388
+ } = this.props;
389
+ const {
390
+ Marker: GMarker
391
+ } = api;
392
+ let icon;
393
+ if (color) {
394
+ icon = {
395
+ path: markerPath,
396
+ fillOpacity: 1,
397
+ fillColor: color.background,
398
+ strokeColor: color.border,
399
+ strokeWeight: 2,
400
+ anchor: new api.Point(10, 35),
401
+ labelOrigin: new api.Point(10, 11)
402
+ };
403
+ }
404
+ this.marker = new GMarker({
405
+ draggable: Boolean(onMove),
406
+ position,
407
+ map,
408
+ zIndex,
409
+ opacity,
410
+ label,
411
+ icon
412
+ });
413
+ if (markerRef) {
414
+ markerRef.current = this.marker;
415
+ }
416
+ this.attachMoveHandler();
417
+ this.attachClickHandler();
418
+ }
419
+ componentDidUpdate(prevProps) {
420
+ if (!this.marker) {
421
+ return;
422
+ }
423
+ const {
424
+ position,
425
+ onMove,
426
+ label,
427
+ zIndex,
428
+ opacity,
429
+ map
430
+ } = this.props;
431
+ if (prevProps.onMove !== onMove) {
432
+ this.attachMoveHandler();
433
+ }
434
+ if (!latLngAreEqual(prevProps.position, position)) {
435
+ this.marker.setPosition(position);
436
+ }
437
+ if (prevProps.label !== label) {
438
+ this.marker.setLabel(label || null);
439
+ }
440
+ if (prevProps.zIndex !== zIndex) {
441
+ this.marker.setZIndex(zIndex || null);
442
+ }
443
+ if (prevProps.opacity !== opacity) {
444
+ this.marker.setOpacity(opacity || null);
445
+ }
446
+ if (prevProps.map !== map) {
447
+ this.marker.setMap(map);
448
+ }
449
+ }
450
+ componentWillUnmount() {
451
+ if (this.eventHandlers.move) {
452
+ this.eventHandlers.move.remove();
453
+ }
454
+ if (this.marker) {
455
+ this.marker.setMap(null);
456
+ }
457
+ }
458
+ attachMoveHandler() {
459
+ const {
460
+ api,
461
+ onMove
462
+ } = this.props;
463
+ if (this.eventHandlers.move) {
464
+ this.eventHandlers.move.remove();
465
+ }
466
+ if (this.marker && onMove) {
467
+ this.eventHandlers.move = api.event.addListener(this.marker, "dragend", onMove);
468
+ }
469
+ }
470
+ attachClickHandler() {
471
+ const {
472
+ api,
473
+ onClick
474
+ } = this.props;
475
+ if (this.eventHandlers.click) {
476
+ this.eventHandlers.click.remove();
477
+ }
478
+ if (this.marker && onClick) {
479
+ this.eventHandlers.click = api.event.addListener(this.marker, "click", onClick);
480
+ }
481
+ }
482
+ // eslint-disable-next-line class-methods-use-this
483
+ render() {
484
+ return null;
485
+ }
486
+ }
487
+ var __defProp$4 = Object.defineProperty;
488
+ var __defNormalProp$2 = (obj, key, value) => key in obj ? __defProp$4(obj, key, {
489
+ enumerable: true,
490
+ configurable: true,
491
+ writable: true,
492
+ value
493
+ }) : obj[key] = value;
494
+ var __publicField$2 = (obj, key, value) => {
495
+ __defNormalProp$2(obj, typeof key !== "symbol" ? key + "" : key, value);
496
+ return value;
497
+ };
498
+ const fallbackLatLng = {
499
+ lat: 40.7058254,
500
+ lng: -74.1180863
501
+ };
502
+ class GeopointSelect extends React__default.PureComponent {
503
+ constructor() {
504
+ super(...arguments);
505
+ __publicField$2(this, "mapRef", React__default.createRef());
506
+ __publicField$2(this, "handlePlaceChanged", place => {
507
+ var _a;
508
+ if (!((_a = place.geometry) == null ? void 0 : _a.location)) {
509
+ return;
510
+ }
511
+ this.setValue(place.geometry.location);
512
+ });
513
+ __publicField$2(this, "handleMarkerDragEnd", event => {
514
+ if (event.latLng) this.setValue(event.latLng);
515
+ });
516
+ __publicField$2(this, "handleMapClick", event => {
517
+ if (event.latLng) this.setValue(event.latLng);
518
+ });
519
+ }
520
+ getCenter() {
521
+ const {
522
+ value = {},
523
+ defaultLocation = {}
524
+ } = this.props;
525
+ const point = {
526
+ ...fallbackLatLng,
527
+ ...defaultLocation,
528
+ ...value
529
+ };
530
+ return point;
531
+ }
532
+ setValue(geoPoint) {
533
+ if (this.props.onChange) {
534
+ this.props.onChange(geoPoint);
535
+ }
536
+ }
537
+ render() {
538
+ const {
539
+ api,
540
+ defaultZoom,
541
+ value,
542
+ onChange
543
+ } = this.props;
544
+ return /* @__PURE__ */jsx(GoogleMap, {
545
+ api,
546
+ location: this.getCenter(),
547
+ onClick: this.handleMapClick,
548
+ defaultZoom,
549
+ children: map => /* @__PURE__ */jsxs(Fragment, {
550
+ children: [/* @__PURE__ */jsx(SearchInput, {
551
+ api,
552
+ map,
553
+ onChange: this.handlePlaceChanged
554
+ }), value && /* @__PURE__ */jsx(Marker, {
555
+ api,
556
+ map,
557
+ position: value,
558
+ onMove: onChange ? this.handleMarkerDragEnd : void 0
559
+ })]
560
+ })
561
+ });
562
+ }
563
+ }
564
+ __publicField$2(GeopointSelect, "defaultProps", {
565
+ defaultZoom: 8,
566
+ defaultLocation: {
567
+ lng: 10.74609,
568
+ lat: 59.91273
569
+ }
570
+ });
571
+ var __freeze$1 = Object.freeze;
572
+ var __defProp$3 = Object.defineProperty;
573
+ var __template$1 = (cooked, raw) => __freeze$1(__defProp$3(cooked, "raw", {
574
+ value: __freeze$1(raw || cooked.slice())
575
+ }));
576
+ var _a$1, _b;
577
+ const PreviewImage = styled.img(_a$1 || (_a$1 = __template$1(["\n width: 100%;\n height: auto;\n vertical-align: top;\n"])));
578
+ const DialogInnerContainer = styled.div(_b || (_b = __template$1(["\n height: 40rem;\n width: 50rem;\n"])));
579
+ let config;
580
+ function getGeoConfig() {
581
+ return config;
582
+ }
583
+ function setGeoConfig(newConfig) {
584
+ config = newConfig;
585
+ }
586
+ var __defProp$2 = Object.defineProperty;
587
+ var __defNormalProp$1 = (obj, key, value) => key in obj ? __defProp$2(obj, key, {
588
+ enumerable: true,
589
+ configurable: true,
590
+ writable: true,
591
+ value
592
+ }) : obj[key] = value;
593
+ var __publicField$1 = (obj, key, value) => {
594
+ __defNormalProp$1(obj, typeof key !== "symbol" ? key + "" : key, value);
595
+ return value;
596
+ };
597
+ const getStaticImageUrl = (value, apiKey) => {
598
+ const loc = "".concat(value.lat, ",").concat(value.lng);
599
+ const params = {
600
+ key: apiKey,
601
+ center: loc,
602
+ markers: loc,
603
+ zoom: 13,
604
+ scale: 2,
605
+ size: "640x300"
606
+ };
607
+ const qs = Object.keys(params).reduce((res, param) => {
608
+ return res.concat("".concat(param, "=").concat(encodeURIComponent(params[param])));
609
+ }, []);
610
+ return "https://maps.googleapis.com/maps/api/staticmap?".concat(qs.join("&"));
611
+ };
612
+ class GeopointInput extends React__default.PureComponent {
613
+ constructor(props) {
614
+ super(props);
615
+ __publicField$1(this, "_geopointInputId", uniqueId("GeopointInput"));
616
+ __publicField$1(this, "editButton");
617
+ __publicField$1(this, "setEditButton", el => {
618
+ this.editButton = el;
619
+ });
620
+ __publicField$1(this, "handleToggleModal", () => {
621
+ this.setState(prevState => ({
622
+ modalOpen: !prevState.modalOpen
623
+ }));
624
+ });
625
+ __publicField$1(this, "handleCloseModal", () => {
626
+ this.setState({
627
+ modalOpen: false
628
+ });
629
+ });
630
+ __publicField$1(this, "handleChange", latLng => {
631
+ const {
632
+ schemaType,
633
+ onChange
634
+ } = this.props;
635
+ onChange([setIfMissing({
636
+ _type: schemaType.name
637
+ }), set(latLng.lat(), ["lat"]), set(latLng.lng(), ["lng"])]);
638
+ });
639
+ __publicField$1(this, "handleClear", () => {
640
+ const {
641
+ onChange
642
+ } = this.props;
643
+ onChange(unset());
644
+ });
645
+ this.state = {
646
+ modalOpen: false
647
+ };
648
+ }
649
+ focus() {
650
+ if (this.editButton) {
651
+ this.editButton.focus();
652
+ }
653
+ }
654
+ render() {
655
+ const {
656
+ value,
657
+ readOnly,
658
+ geoConfig: config,
659
+ path,
660
+ changed,
661
+ focused
662
+ } = this.props;
663
+ const {
664
+ modalOpen
665
+ } = this.state;
666
+ if (!config || !config.apiKey) {
667
+ return /* @__PURE__ */jsxs("div", {
668
+ children: [/* @__PURE__ */jsxs("p", {
669
+ children: ["The ", /* @__PURE__ */jsx("a", {
670
+ href: "https://sanity.io/docs/schema-types/geopoint-type",
671
+ children: "Geopoint type"
672
+ }), " needs a Google Maps API key with access to:"]
673
+ }), /* @__PURE__ */jsxs("ul", {
674
+ children: [/* @__PURE__ */jsx("li", {
675
+ children: "Google Maps JavaScript API"
676
+ }), /* @__PURE__ */jsx("li", {
677
+ children: "Google Places API Web Service"
678
+ }), /* @__PURE__ */jsx("li", {
679
+ children: "Google Static Maps API"
680
+ })]
681
+ }), /* @__PURE__ */jsx("p", {
682
+ children: "Please enter the API key with access to these services in your googleMapsInput plugin config."
683
+ })]
684
+ });
685
+ }
686
+ return /* @__PURE__ */jsxs(Stack, {
687
+ space: 3,
688
+ children: [value && /* @__PURE__ */jsx(ChangeIndicator, {
689
+ path,
690
+ isChanged: changed,
691
+ hasFocus: !!focused,
692
+ children: /* @__PURE__ */jsx(PreviewImage, {
693
+ src: getStaticImageUrl(value, config.apiKey),
694
+ alt: "Map location"
695
+ })
696
+ }), /* @__PURE__ */jsx(Box, {
697
+ children: /* @__PURE__ */jsxs(Grid, {
698
+ columns: value ? 2 : 1,
699
+ gap: 3,
700
+ children: [/* @__PURE__ */jsx(Button, {
701
+ mode: "ghost",
702
+ icon: value && EditIcon,
703
+ padding: 3,
704
+ ref: this.setEditButton,
705
+ text: value ? "Edit" : "Set location",
706
+ onClick: this.handleToggleModal,
707
+ disabled: readOnly
708
+ }), value && /* @__PURE__ */jsx(Button, {
709
+ tone: "critical",
710
+ icon: TrashIcon,
711
+ padding: 3,
712
+ mode: "ghost",
713
+ text: "Remove",
714
+ onClick: this.handleClear,
715
+ disabled: readOnly
716
+ })]
717
+ })
718
+ }), modalOpen && /* @__PURE__ */jsx(Dialog, {
719
+ id: "".concat(this._geopointInputId, "_dialog"),
720
+ onClose: this.handleCloseModal,
721
+ header: "Place the marker on the map",
722
+ width: 1,
723
+ children: /* @__PURE__ */jsx(DialogInnerContainer, {
724
+ children: /* @__PURE__ */jsx(GoogleMapsLoadProxy, {
725
+ config: getGeoConfig(),
726
+ children: api => /* @__PURE__ */jsx(GeopointSelect, {
727
+ api,
728
+ value: value || void 0,
729
+ onChange: readOnly ? void 0 : this.handleChange,
730
+ defaultLocation: config.defaultLocation,
731
+ defaultZoom: config.defaultZoom
732
+ })
733
+ })
734
+ })
735
+ })]
736
+ });
737
+ }
738
+ }
739
+ var __defProp$1 = Object.defineProperty;
740
+ var __defNormalProp = (obj, key, value) => key in obj ? __defProp$1(obj, key, {
741
+ enumerable: true,
742
+ configurable: true,
743
+ writable: true,
744
+ value
745
+ }) : obj[key] = value;
746
+ var __publicField = (obj, key, value) => {
747
+ __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
748
+ return value;
749
+ };
750
+ class Arrow extends React.PureComponent {
751
+ constructor() {
752
+ super(...arguments);
753
+ __publicField(this, "line");
754
+ __publicField(this, "eventHandlers", {});
755
+ }
756
+ componentDidMount() {
757
+ const {
758
+ from,
759
+ to,
760
+ api,
761
+ map,
762
+ zIndex,
763
+ onClick,
764
+ color,
765
+ arrowRef
766
+ } = this.props;
767
+ const lineSymbol = {
768
+ path: api.SymbolPath.FORWARD_OPEN_ARROW
769
+ };
770
+ this.line = new api.Polyline({
771
+ map,
772
+ zIndex,
773
+ path: [from, to],
774
+ icons: [{
775
+ icon: lineSymbol,
776
+ offset: "50%"
777
+ }],
778
+ strokeOpacity: 0.55,
779
+ strokeColor: color ? color.text : "black"
780
+ });
781
+ if (onClick) {
782
+ this.eventHandlers.click = api.event.addListener(this.line, "click", onClick);
783
+ }
784
+ if (arrowRef) {
785
+ arrowRef.current = this.line;
786
+ }
787
+ }
788
+ componentDidUpdate(prevProps) {
789
+ if (!this.line) {
790
+ return;
791
+ }
792
+ const {
793
+ from,
794
+ to,
795
+ map
796
+ } = this.props;
797
+ if (!latLngAreEqual(prevProps.from, from) || !latLngAreEqual(prevProps.to, to)) {
798
+ this.line.setPath([from, to]);
799
+ }
800
+ if (prevProps.map !== map) {
801
+ this.line.setMap(map);
802
+ }
803
+ }
804
+ componentWillUnmount() {
805
+ if (this.line) {
806
+ this.line.setMap(null);
807
+ }
808
+ if (this.eventHandlers.click) {
809
+ this.eventHandlers.click.remove();
810
+ }
811
+ }
812
+ // eslint-disable-next-line class-methods-use-this
813
+ render() {
814
+ return null;
815
+ }
816
+ }
817
+ function GeopointMove(_ref) {
818
+ let {
819
+ diff,
820
+ api,
821
+ map,
822
+ label
823
+ } = _ref;
824
+ const {
825
+ fromValue: from,
826
+ toValue: to
827
+ } = diff;
828
+ const annotation = diff.isChanged ? diff.annotation : void 0;
829
+ const userColor = useUserColor(annotation ? annotation.author : null) || void 0;
830
+ const fromRef = React.useRef();
831
+ const toRef = React.useRef();
832
+ return /* @__PURE__ */jsxs(Fragment, {
833
+ children: [from && /* @__PURE__ */jsx(Marker, {
834
+ api,
835
+ map,
836
+ position: from,
837
+ zIndex: 0,
838
+ opacity: 0.55,
839
+ markerRef: fromRef,
840
+ color: userColor
841
+ }), from && to && /* @__PURE__ */jsx(Arrow, {
842
+ api,
843
+ map,
844
+ from,
845
+ to,
846
+ zIndex: 1,
847
+ color: userColor
848
+ }), to && /* @__PURE__ */jsx(Marker, {
849
+ api,
850
+ map,
851
+ position: to,
852
+ zIndex: 2,
853
+ markerRef: toRef,
854
+ label,
855
+ color: userColor
856
+ })]
857
+ });
858
+ }
859
+ var __freeze = Object.freeze;
860
+ var __defProp = Object.defineProperty;
861
+ var __template = (cooked, raw) => __freeze(__defProp(cooked, "raw", {
862
+ value: __freeze(raw || cooked.slice())
863
+ }));
864
+ var _a;
865
+ const RootContainer = styled.div(_a || (_a = __template(["\n position: relative;\n min-height: 200px;\n\n &:empty {\n background-color: var(--card-skeleton-color-from);\n display: table;\n width: 100%;\n }\n\n &:empty:after {\n content: 'Missing/invalid data';\n display: table-cell;\n vertical-align: middle;\n text-align: center;\n position: relative;\n }\n"])));
866
+ const GeopointArrayDiff = _ref2 => {
867
+ let {
868
+ diff,
869
+ schemaType
870
+ } = _ref2;
871
+ return /* @__PURE__ */jsx(RootContainer, {
872
+ children: /* @__PURE__ */jsx(GoogleMapsLoadProxy, {
873
+ config: getGeoConfig(),
874
+ children: api => /* @__PURE__ */jsx(GeopointDiff$1, {
875
+ api,
876
+ diff,
877
+ schemaType
878
+ })
879
+ })
880
+ });
881
+ };
882
+ function GeopointDiff$1(_ref3) {
883
+ let {
884
+ api,
885
+ diff
886
+ } = _ref3;
887
+ const fromValue = (diff.fromValue || []).filter(hasCoordinates);
888
+ const toValue = (diff.toValue || []).filter(hasCoordinates);
889
+ if (fromValue.length === 0 && toValue.length === 0) {
890
+ return null;
891
+ }
892
+ const bounds = getBounds$1(fromValue, toValue, api);
893
+ return /* @__PURE__ */jsx(GoogleMap, {
894
+ api,
895
+ location: bounds.getCenter().toJSON(),
896
+ mapTypeControl: false,
897
+ controlSize: 20,
898
+ bounds,
899
+ children: map => /* @__PURE__ */jsx(Fragment, {
900
+ children: diff.items.map(_ref4 => {
901
+ let {
902
+ toIndex,
903
+ diff: pointDiff
904
+ } = _ref4;
905
+ if (!isChangeDiff(pointDiff)) {
906
+ return null;
907
+ }
908
+ return /* @__PURE__ */jsx(GeopointMove, {
909
+ api,
910
+ map,
911
+ diff: pointDiff,
912
+ label: "".concat(toIndex)
913
+ }, toIndex);
914
+ })
915
+ })
916
+ });
917
+ }
918
+ function isChangeDiff(diff) {
919
+ return diff.action !== "unchanged" && diff.type === "object";
920
+ }
921
+ function hasCoordinates(point) {
922
+ return typeof point.lat === "number" && typeof point.lng === "number";
923
+ }
924
+ function getBounds$1(fromValue, toValue, api) {
925
+ const bounds = new api.LatLngBounds();
926
+ const points = [...(fromValue || []), ...(toValue || [])];
927
+ points.forEach(point => bounds.extend(point));
928
+ return bounds;
929
+ }
930
+ const GeopointFieldDiff = _ref5 => {
931
+ let {
932
+ diff,
933
+ schemaType
934
+ } = _ref5;
935
+ return /* @__PURE__ */jsx(RootContainer, {
936
+ children: /* @__PURE__ */jsx(GoogleMapsLoadProxy, {
937
+ config: getGeoConfig(),
938
+ children: api => /* @__PURE__ */jsx(GeopointDiff, {
939
+ api,
940
+ diff,
941
+ schemaType
942
+ })
943
+ })
944
+ });
945
+ };
946
+ function GeopointDiff(_ref6) {
947
+ let {
948
+ api,
949
+ diff
950
+ } = _ref6;
951
+ const {
952
+ fromValue,
953
+ toValue
954
+ } = diff;
955
+ const annotation = getAnnotationAtPath(diff, ["lat"]) || getAnnotationAtPath(diff, ["lng"]) || getAnnotationAtPath(diff, []);
956
+ const center = getCenter(diff, api);
957
+ const bounds = fromValue && toValue ? getBounds(fromValue, toValue, api) : void 0;
958
+ return /* @__PURE__ */jsx(DiffTooltip, {
959
+ annotations: annotation ? [annotation] : [],
960
+ description: getAction(diff),
961
+ children: /* @__PURE__ */jsx("div", {
962
+ children: /* @__PURE__ */jsx(GoogleMap, {
963
+ api,
964
+ location: center,
965
+ mapTypeControl: false,
966
+ controlSize: 20,
967
+ bounds,
968
+ scrollWheel: false,
969
+ children: map => /* @__PURE__ */jsx(GeopointMove, {
970
+ api,
971
+ map,
972
+ diff
973
+ })
974
+ })
975
+ })
976
+ });
977
+ }
978
+ function getBounds(fromValue, toValue, api) {
979
+ return new api.LatLngBounds().extend(fromValue).extend(toValue);
980
+ }
981
+ function getCenter(diff, api) {
982
+ const {
983
+ fromValue,
984
+ toValue
985
+ } = diff;
986
+ if (fromValue && toValue) {
987
+ return getBounds(fromValue, toValue, api).getCenter().toJSON();
988
+ }
989
+ if (fromValue) {
990
+ return fromValue;
991
+ }
992
+ if (toValue) {
993
+ return toValue;
994
+ }
995
+ throw new Error("Neither a from or a to value present");
996
+ }
997
+ function getAction(diff) {
998
+ const {
999
+ fromValue,
1000
+ toValue
1001
+ } = diff;
1002
+ if (fromValue && toValue) {
1003
+ return "Moved";
1004
+ } else if (fromValue) {
1005
+ return "Removed";
1006
+ } else if (toValue) {
1007
+ return "Added";
1008
+ }
1009
+ return "Unchanged";
1010
+ }
1011
+ const googleMapsInput = definePlugin(config => {
1012
+ setGeoConfig(config);
1013
+ return {
1014
+ name: "google-maps-input",
1015
+ form: {
1016
+ components: {
1017
+ input(props) {
1018
+ if (isGeopoint(props.schemaType)) {
1019
+ const castedProps = props;
1020
+ return /* @__PURE__ */jsx(GeopointInput, {
1021
+ ...castedProps,
1022
+ geoConfig: config
1023
+ });
1024
+ }
1025
+ return props.renderDefault(props);
1026
+ }
1027
+ }
1028
+ }
1029
+ };
1030
+ });
1031
+ function isGeopoint(schemaType) {
1032
+ return isType("geopoint", schemaType);
1033
+ }
1034
+ function isType(name, schema) {
1035
+ if ((schema == null ? void 0 : schema.name) === name) {
1036
+ return true;
1037
+ } else if (!(schema == null ? void 0 : schema.name)) {
1038
+ return false;
1039
+ }
1040
+ return isType(name, schema == null ? void 0 : schema.type);
1041
+ }
1042
+ export { GeopointArrayDiff, GeopointFieldDiff, GeopointInput, googleMapsInput };
1043
+ //# sourceMappingURL=index.esm.js.map