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