@sanity/google-maps-input 4.1.1 → 4.2.1

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.cjs CHANGED
@@ -30,12 +30,11 @@ function isErrorEvent(event) {
30
30
  return typeof event != "object" || event === null || !("message" in event) ? !1 : typeof event.message == "string";
31
31
  }
32
32
  function LoadError(props) {
33
- var _a;
34
33
  return /* @__PURE__ */ jsxRuntime.jsxs(ui.Card, { tone: "critical", radius: 1, children: [
35
34
  /* @__PURE__ */ jsxRuntime.jsx(ui.Box, { as: "header", paddingX: 4, paddingTop: 4, paddingBottom: 1, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { as: "h2", weight: "bold", children: "Google Maps failed to load" }) }),
36
35
  /* @__PURE__ */ jsxRuntime.jsx(ui.Box, { paddingX: 4, paddingTop: 4, paddingBottom: 1, children: props.isAuthError ? /* @__PURE__ */ jsxRuntime.jsx(AuthError2, {}) : /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
37
36
  /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { as: "h3", children: "Error details:" }),
38
- /* @__PURE__ */ jsxRuntime.jsx("pre", { children: /* @__PURE__ */ jsxRuntime.jsx(ui.Code, { size: 1, children: "error" in props && ((_a = props.error) == null ? void 0 : _a.message) }) })
37
+ /* @__PURE__ */ jsxRuntime.jsx("pre", { children: /* @__PURE__ */ jsxRuntime.jsx(ui.Code, { size: 1, children: "error" in props && props.error?.message }) })
39
38
  ] }) })
40
39
  ] });
41
40
  }
@@ -53,7 +52,7 @@ function AuthError2() {
53
52
  }
54
53
  const browserLocale = typeof window < "u" && window.navigator.language || "en";
55
54
  function useLoadGoogleMapsApi(config2) {
56
- const locale = config2.defaultLocale || browserLocale || "en-US", [state, setState] = react.useState({ type: "loading" });
55
+ const locale = config2.defaultLocale || browserLocale, [state, setState] = react.useState({ type: "loading" });
57
56
  return react.useEffect(() => {
58
57
  typeof window > "u" || loadGoogleMapsApi({ locale, apiKey: config2.apiKey }).then(
59
58
  (api) => setState({ type: "loaded", api }),
@@ -96,13 +95,12 @@ const PreviewImage = styledComponents.styled.img`
96
95
  top: 10px;
97
96
  width: 220px;
98
97
  `;
99
- var __defProp$5 = Object.defineProperty, __defNormalProp$5 = (obj, key, value) => key in obj ? __defProp$5(obj, key, { enumerable: !0, configurable: !0, writable: !0, value }) : obj[key] = value, __publicField$3 = (obj, key, value) => __defNormalProp$5(obj, typeof key != "symbol" ? key + "" : key, value);
100
98
  class SearchInput extends react.PureComponent {
101
- constructor() {
102
- super(...arguments), __publicField$3(this, "searchInputRef", react.createRef()), __publicField$3(this, "autoComplete"), __publicField$3(this, "handleChange", () => {
103
- this.autoComplete && (this.props.onChange(this.autoComplete.getPlace()), this.searchInputRef.current && (this.searchInputRef.current.value = ""));
104
- });
105
- }
99
+ searchInputRef = react.createRef();
100
+ autoComplete;
101
+ handleChange = () => {
102
+ this.autoComplete && (this.props.onChange(this.autoComplete.getPlace()), this.searchInputRef.current && (this.searchInputRef.current.value = ""));
103
+ };
106
104
  componentDidMount() {
107
105
  const input = this.searchInputRef.current;
108
106
  if (!input)
@@ -138,26 +136,25 @@ const MapContainer = styledComponents.styled.div`
138
136
  width: 100%;
139
137
  box-sizing: border-box;
140
138
  `;
141
- var __defProp$4 = Object.defineProperty, __defNormalProp$4 = (obj, key, value) => key in obj ? __defProp$4(obj, key, { enumerable: !0, configurable: !0, writable: !0, value }) : obj[key] = value, __publicField$2 = (obj, key, value) => __defNormalProp$4(obj, typeof key != "symbol" ? key + "" : key, value);
142
139
  class GoogleMap extends react.PureComponent {
143
- constructor() {
144
- super(...arguments), __publicField$2(this, "state", { map: void 0 }), __publicField$2(this, "clickHandler"), __publicField$2(this, "mapRef", react.createRef()), __publicField$2(this, "mapEl", null), __publicField$2(this, "attachClickHandler", () => {
145
- const map = this.state.map;
146
- if (!map)
147
- return;
148
- const { api, onClick } = this.props, { event } = api;
149
- this.clickHandler && this.clickHandler.remove(), onClick && (this.clickHandler = event.addListener(map, "click", onClick));
150
- }), __publicField$2(this, "setMapElement", (element) => {
151
- if (element && element !== this.mapEl) {
152
- const map = this.constructMap(element);
153
- this.setState({ map }, this.attachClickHandler);
154
- }
155
- this.mapEl = element;
156
- });
157
- }
140
+ static defaultProps = {
141
+ defaultZoom: 8,
142
+ scrollWheel: !0
143
+ };
144
+ state = { map: void 0 };
145
+ clickHandler;
146
+ mapRef = react.createRef();
147
+ mapEl = null;
158
148
  componentDidMount() {
159
149
  this.attachClickHandler();
160
150
  }
151
+ attachClickHandler = () => {
152
+ const map = this.state.map;
153
+ if (!map)
154
+ return;
155
+ const { api, onClick } = this.props, { event } = api;
156
+ this.clickHandler && this.clickHandler.remove(), onClick && (this.clickHandler = event.addListener(map, "click", onClick));
157
+ };
161
158
  componentDidUpdate(prevProps) {
162
159
  const map = this.state.map;
163
160
  if (!map)
@@ -183,6 +180,13 @@ class GoogleMap extends react.PureComponent {
183
180
  });
184
181
  return bounds && map.fitBounds(bounds), map;
185
182
  }
183
+ setMapElement = (element) => {
184
+ if (element && element !== this.mapEl) {
185
+ const map = this.constructMap(element);
186
+ this.setState({ map }, this.attachClickHandler);
187
+ }
188
+ this.mapEl = element;
189
+ };
186
190
  render() {
187
191
  const { children } = this.props, { map } = this.state;
188
192
  return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
@@ -191,16 +195,10 @@ class GoogleMap extends react.PureComponent {
191
195
  ] });
192
196
  }
193
197
  }
194
- __publicField$2(GoogleMap, "defaultProps", {
195
- defaultZoom: 8,
196
- scrollWheel: !0
197
- });
198
- var __defProp$3 = Object.defineProperty, __defNormalProp$3 = (obj, key, value) => key in obj ? __defProp$3(obj, key, { enumerable: !0, configurable: !0, writable: !0, value }) : obj[key] = value, __publicField$1 = (obj, key, value) => __defNormalProp$3(obj, typeof key != "symbol" ? key + "" : key, value);
199
198
  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";
200
199
  class Marker extends react.PureComponent {
201
- constructor() {
202
- super(...arguments), __publicField$1(this, "marker"), __publicField$1(this, "eventHandlers", {});
203
- }
200
+ marker;
201
+ eventHandlers = {};
204
202
  componentDidMount() {
205
203
  const { position, api, map, onMove, zIndex, opacity, label, markerRef, color } = this.props, { Marker: GMarker } = api;
206
204
  let icon;
@@ -244,30 +242,21 @@ class Marker extends react.PureComponent {
244
242
  return null;
245
243
  }
246
244
  }
247
- var __defProp$2 = Object.defineProperty, __getOwnPropSymbols$1 = Object.getOwnPropertySymbols, __hasOwnProp$1 = Object.prototype.hasOwnProperty, __propIsEnum$1 = Object.prototype.propertyIsEnumerable, __defNormalProp$2 = (obj, key, value) => key in obj ? __defProp$2(obj, key, { enumerable: !0, configurable: !0, writable: !0, value }) : obj[key] = value, __spreadValues$1 = (a, b) => {
248
- for (var prop in b || (b = {}))
249
- __hasOwnProp$1.call(b, prop) && __defNormalProp$2(a, prop, b[prop]);
250
- if (__getOwnPropSymbols$1)
251
- for (var prop of __getOwnPropSymbols$1(b))
252
- __propIsEnum$1.call(b, prop) && __defNormalProp$2(a, prop, b[prop]);
253
- return a;
254
- };
255
- const fallbackLatLng = { lat: 40.7058254, lng: -74.1180863 }, GeopointSelect = ({
245
+ const fallbackLatLng$1 = { lat: 40.7058254, lng: -74.1180863 }, GeopointSelect = ({
256
246
  api,
257
247
  value,
258
248
  onChange,
259
249
  defaultLocation = { lng: 10.74609, lat: 59.91273 },
260
250
  defaultZoom = 8
261
251
  }) => {
262
- const getCenter2 = react.useCallback(() => __spreadValues$1(__spreadValues$1(__spreadValues$1({}, fallbackLatLng), defaultLocation), value), [value, defaultLocation]), setValue = react.useCallback(
252
+ const getCenter2 = react.useCallback(() => ({ ...fallbackLatLng$1, ...defaultLocation, ...value }), [value, defaultLocation]), setValue = react.useCallback(
263
253
  (geoPoint) => {
264
254
  onChange && onChange(geoPoint);
265
255
  },
266
256
  [onChange]
267
257
  ), handlePlaceChanged = react.useCallback(
268
258
  (place) => {
269
- var _a;
270
- (_a = place.geometry) != null && _a.location && setValue(place.geometry.location);
259
+ place.geometry?.location && setValue(place.geometry.location);
271
260
  },
272
261
  [setValue]
273
262
  ), handleMarkerDragEnd = react.useCallback(
@@ -293,7 +282,7 @@ const fallbackLatLng = { lat: 40.7058254, lng: -74.1180863 }, GeopointSelect = (
293
282
  }
294
283
  )
295
284
  ] }) });
296
- }, EMPTY_PATH = [], getStaticImageUrl = (value, apiKey) => {
285
+ }, EMPTY_PATH$1 = [], getStaticImageUrl$1 = (value, apiKey) => {
297
286
  const loc = `${value.lat},${value.lng}`;
298
287
  return `https://maps.googleapis.com/maps/api/staticmap?${new URLSearchParams({
299
288
  key: apiKey,
@@ -322,10 +311,7 @@ function GeopointInput(props) {
322
311
  onBlur: handleBlur,
323
312
  onFocus: handleFocus,
324
313
  "aria-describedby": ariaDescribedBy
325
- } = elementProps, schemaTypeName = schemaType.name, dialogId = react.useId(), dialogRef = react.useRef(null), handleFocusButton = react.useCallback(() => {
326
- var _a;
327
- return (_a = inputRef == null ? void 0 : inputRef.current) == null ? void 0 : _a.focus();
328
- }, [inputRef]), [modalOpen, setModalOpen] = react.useState(!1), handleCloseModal = react.useCallback(() => {
314
+ } = elementProps, schemaTypeName = schemaType.name, dialogId = react.useId(), dialogRef = react.useRef(null), handleFocusButton = react.useCallback(() => inputRef?.current?.focus(), [inputRef]), [modalOpen, setModalOpen] = react.useState(!1), handleCloseModal = react.useCallback(() => {
329
315
  dialogRef.current && dialogRef.current.blur(), setModalOpen(!1), handleFocusButton();
330
316
  }, [setModalOpen, handleFocusButton]), handleToggleModal = react.useCallback(
331
317
  () => setModalOpen((currentState) => !currentState),
@@ -343,7 +329,7 @@ function GeopointInput(props) {
343
329
  onChange(sanity.unset());
344
330
  }, [onChange]);
345
331
  return react.useEffect(() => {
346
- modalOpen && onPathFocus(EMPTY_PATH);
332
+ modalOpen && onPathFocus(EMPTY_PATH$1);
347
333
  }, [modalOpen, onPathFocus]), !config2 || !config2.apiKey ? /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
348
334
  /* @__PURE__ */ jsxRuntime.jsxs("p", { children: [
349
335
  "The ",
@@ -360,7 +346,7 @@ function GeopointInput(props) {
360
346
  value && /* @__PURE__ */ jsxRuntime.jsx(sanity.ChangeIndicator, { path, isChanged: changed, hasFocus: !!focused, children: /* @__PURE__ */ jsxRuntime.jsx(
361
347
  PreviewImage,
362
348
  {
363
- src: getStaticImageUrl(value, config2.apiKey),
349
+ src: getStaticImageUrl$1(value, config2.apiKey),
364
350
  alt: "Map location",
365
351
  onClick: handleFocusButton,
366
352
  onDoubleClick: handleToggleModal
@@ -418,11 +404,274 @@ function GeopointInput(props) {
418
404
  )
419
405
  ] });
420
406
  }
421
- var __defProp$1 = Object.defineProperty, __defNormalProp$1 = (obj, key, value) => key in obj ? __defProp$1(obj, key, { enumerable: !0, configurable: !0, writable: !0, value }) : obj[key] = value, __publicField = (obj, key, value) => __defNormalProp$1(obj, typeof key != "symbol" ? key + "" : key, value);
422
- class Arrow extends react.PureComponent {
423
- constructor() {
424
- super(...arguments), __publicField(this, "line"), __publicField(this, "eventHandlers", {});
407
+ const fallbackLatLng = { lat: 40.7058254, lng: -74.1180863 }, MarkerDragSync = ({ api, marker, circleRef, isMarkerDragging }) => (react.useEffect(() => {
408
+ const handleDrag = () => {
409
+ isMarkerDragging.current = !0;
410
+ }, handleDragEnd = () => {
411
+ isMarkerDragging.current = !1;
412
+ }, dragListener = api.event.addListener(marker, "drag", handleDrag), dragEndListener = api.event.addListener(marker, "dragend", handleDragEnd);
413
+ return () => {
414
+ api.event.removeListener(dragListener), api.event.removeListener(dragEndListener);
415
+ };
416
+ }, [api, marker, circleRef, isMarkerDragging]), null), GeopointRadiusSelect = ({
417
+ api,
418
+ value,
419
+ onChange,
420
+ defaultLocation = { lng: 10.74609, lat: 59.91273 },
421
+ defaultRadiusZoom = 12,
422
+ defaultRadius = 1e3
423
+ }) => {
424
+ const circleRef = react.useRef(null), markerRef = react.useRef(void 0), isMarkerDragging = react.useRef(!1), getCenter2 = react.useCallback(() => ({ ...fallbackLatLng, ...defaultLocation, ...value }), [value, defaultLocation]), setValue = react.useCallback(
425
+ (geoPoint, radius) => {
426
+ if (onChange) {
427
+ const roundedRadius = radius ? Math.round(radius) : void 0;
428
+ onChange(geoPoint, roundedRadius);
429
+ }
430
+ },
431
+ [onChange]
432
+ ), handlePlaceChanged = react.useCallback(
433
+ (place) => {
434
+ place.geometry?.location && setValue(place.geometry.location, value?.radius || defaultRadius);
435
+ },
436
+ [setValue, value?.radius, defaultRadius]
437
+ ), handleMarkerDragEnd = react.useCallback(
438
+ (event) => {
439
+ event.latLng && (circleRef.current && circleRef.current.setCenter(event.latLng), setValue(event.latLng, value?.radius || defaultRadius));
440
+ },
441
+ [setValue, value?.radius, defaultRadius]
442
+ ), handleMapClick = react.useCallback(
443
+ (event) => {
444
+ event.latLng && setValue(event.latLng, value?.radius || defaultRadius);
445
+ },
446
+ [setValue, value?.radius, defaultRadius]
447
+ );
448
+ return react.useEffect(() => {
449
+ value && circleRef.current && (circleRef.current.setCenter({ lat: value.lat, lng: value.lng }), circleRef.current.setRadius(value.radius));
450
+ }, [value]), /* @__PURE__ */ jsxRuntime.jsx(
451
+ GoogleMap,
452
+ {
453
+ api,
454
+ location: getCenter2(),
455
+ onClick: handleMapClick,
456
+ defaultZoom: defaultRadiusZoom,
457
+ children: (map) => (value && !circleRef.current && (circleRef.current = new api.Circle({
458
+ map,
459
+ center: { lat: value.lat, lng: value.lng },
460
+ radius: value.radius,
461
+ fillColor: "#4285F4",
462
+ fillOpacity: 0.2,
463
+ strokeColor: "#4285F4",
464
+ strokeOpacity: 0.8,
465
+ strokeWeight: 2,
466
+ editable: !0
467
+ }), circleRef.current.addListener("center_changed", () => {
468
+ if (circleRef.current && markerRef.current && !isMarkerDragging.current) {
469
+ const circleCenter = circleRef.current.getCenter();
470
+ circleCenter && markerRef.current.setPosition(circleCenter);
471
+ }
472
+ }), circleRef.current.addListener("radius_changed", () => {
473
+ if (circleRef.current) {
474
+ const center = circleRef.current.getCenter(), radius = circleRef.current.getRadius();
475
+ center && setValue(center, Math.round(radius));
476
+ }
477
+ }), circleRef.current.addListener("dragend", () => {
478
+ if (circleRef.current) {
479
+ const center = circleRef.current.getCenter(), radius = circleRef.current.getRadius();
480
+ center && setValue(center, Math.round(radius));
481
+ }
482
+ })), /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
483
+ /* @__PURE__ */ jsxRuntime.jsx(SearchInput, { api, map, onChange: handlePlaceChanged }),
484
+ value && /* @__PURE__ */ jsxRuntime.jsx(
485
+ Marker,
486
+ {
487
+ api,
488
+ map,
489
+ position: value,
490
+ onMove: onChange ? handleMarkerDragEnd : void 0,
491
+ markerRef
492
+ }
493
+ ),
494
+ value && markerRef.current && /* @__PURE__ */ jsxRuntime.jsx(
495
+ MarkerDragSync,
496
+ {
497
+ api,
498
+ marker: markerRef.current,
499
+ circleRef,
500
+ isMarkerDragging
501
+ }
502
+ )
503
+ ] }))
504
+ }
505
+ );
506
+ }, EMPTY_PATH = [], generateCirclePoints = (lat, lng, radius) => {
507
+ const points = [];
508
+ for (let i = 0; i <= 32; i++) {
509
+ const angle = i / 32 * 2 * Math.PI, latOffset = radius / 111e3 * Math.cos(angle), lngOffset = radius / (111e3 * Math.cos(lat * Math.PI / 180)) * Math.sin(angle);
510
+ points.push({
511
+ lat: lat + latOffset,
512
+ lng: lng + lngOffset
513
+ });
514
+ }
515
+ return points;
516
+ }, getStaticImageUrl = (value, apiKey) => {
517
+ const loc = `${value.lat},${value.lng}`;
518
+ let zoom = 13;
519
+ if (value.radius) {
520
+ const scale = (value.radius + value.radius / 2) / 500, calculatedZoom = 16 - Math.log(scale) / Math.log(2);
521
+ zoom = Math.max(8, Math.min(16, Math.round(calculatedZoom - 0.4)));
425
522
  }
523
+ const qs = new URLSearchParams({
524
+ key: apiKey,
525
+ center: loc,
526
+ markers: loc,
527
+ zoom: zoom.toString(),
528
+ scale: "2",
529
+ size: "640x300"
530
+ });
531
+ if (value.radius) {
532
+ const path = generateCirclePoints(value.lat, value.lng, value.radius).map((p) => `${p.lat},${p.lng}`).join("|");
533
+ qs.append("path", `fillcolor:0x4285F480|color:0x4285F4|weight:2|${path}`);
534
+ }
535
+ return `https://maps.googleapis.com/maps/api/staticmap?${qs.toString()}`;
536
+ };
537
+ function GeopointRadiusInput(props) {
538
+ const {
539
+ changed,
540
+ elementProps,
541
+ focused,
542
+ geoConfig: config2,
543
+ onChange,
544
+ onPathFocus,
545
+ path,
546
+ readOnly,
547
+ schemaType,
548
+ value
549
+ } = props, {
550
+ id,
551
+ ref: inputRef,
552
+ onBlur: handleBlur,
553
+ onFocus: handleFocus,
554
+ "aria-describedby": ariaDescribedBy
555
+ } = elementProps, schemaTypeName = schemaType.name, dialogId = react.useId(), dialogRef = react.useRef(null), handleFocusButton = react.useCallback(() => inputRef?.current?.focus(), [inputRef]), [modalOpen, setModalOpen] = react.useState(!1), handleCloseModal = react.useCallback(() => {
556
+ dialogRef.current && dialogRef.current.blur(), setModalOpen(!1), handleFocusButton();
557
+ }, [setModalOpen, handleFocusButton]), handleToggleModal = react.useCallback(
558
+ () => setModalOpen((currentState) => !currentState),
559
+ [setModalOpen]
560
+ ), handleChange = react.useCallback(
561
+ (latLng, radius) => {
562
+ const currentRadius = radius ?? value?.radius ?? config2.defaultRadius ?? 1e3;
563
+ onChange([
564
+ sanity.setIfMissing({ _type: schemaTypeName }),
565
+ sanity.set(latLng.lat(), ["lat"]),
566
+ sanity.set(latLng.lng(), ["lng"]),
567
+ sanity.set(currentRadius, ["radius"])
568
+ ]);
569
+ },
570
+ [schemaTypeName, onChange, value?.radius, config2.defaultRadius]
571
+ ), handleRadiusChange = react.useCallback(
572
+ (event) => {
573
+ value && onChange([sanity.set(Math.round(Number(event.currentTarget.value)), ["radius"])]);
574
+ },
575
+ [onChange, value]
576
+ ), handleClear = react.useCallback(() => {
577
+ onChange(sanity.unset());
578
+ }, [onChange]);
579
+ return react.useEffect(() => {
580
+ modalOpen && onPathFocus(EMPTY_PATH);
581
+ }, [modalOpen, onPathFocus]), !config2 || !config2.apiKey ? /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
582
+ /* @__PURE__ */ jsxRuntime.jsxs("p", { children: [
583
+ "The ",
584
+ /* @__PURE__ */ jsxRuntime.jsx("a", { href: "https://sanity.io/docs/schema-types/geopoint-type", children: "Geopoint Radius type" }),
585
+ " ",
586
+ "needs a Google Maps API key with access to:"
587
+ ] }),
588
+ /* @__PURE__ */ jsxRuntime.jsxs("ul", { children: [
589
+ /* @__PURE__ */ jsxRuntime.jsx("li", { children: "Google Maps JavaScript API" }),
590
+ /* @__PURE__ */ jsxRuntime.jsx("li", { children: "Google Places API Web Service" }),
591
+ /* @__PURE__ */ jsxRuntime.jsx("li", { children: "Google Static Maps API" })
592
+ ] }),
593
+ /* @__PURE__ */ jsxRuntime.jsx("p", { children: "Please enter the API key with access to these services in your googleMapsInput plugin config." })
594
+ ] }) : /* @__PURE__ */ jsxRuntime.jsxs(ui.Stack, { space: 3, children: [
595
+ value && /* @__PURE__ */ jsxRuntime.jsx(sanity.ChangeIndicator, { path, isChanged: changed, hasFocus: !!focused, children: /* @__PURE__ */ jsxRuntime.jsx(
596
+ PreviewImage,
597
+ {
598
+ src: getStaticImageUrl(value, config2.apiKey),
599
+ alt: "Map location with radius",
600
+ onClick: handleFocusButton,
601
+ onDoubleClick: handleToggleModal
602
+ }
603
+ ) }),
604
+ value && /* @__PURE__ */ jsxRuntime.jsxs(ui.Stack, { space: 2, children: [
605
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Label, { children: "Radius (meters)" }),
606
+ /* @__PURE__ */ jsxRuntime.jsx(
607
+ ui.TextInput,
608
+ {
609
+ type: "number",
610
+ value: Math.round(value.radius || config2.defaultRadius || 1e3),
611
+ onChange: handleRadiusChange,
612
+ disabled: readOnly,
613
+ min: 1,
614
+ max: 5e4,
615
+ step: 1
616
+ }
617
+ )
618
+ ] }),
619
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Box, { children: /* @__PURE__ */ jsxRuntime.jsxs(ui.Grid, { columns: value ? 2 : 1, gap: 3, children: [
620
+ /* @__PURE__ */ jsxRuntime.jsx(
621
+ ui.Button,
622
+ {
623
+ "aria-describedby": ariaDescribedBy,
624
+ disabled: readOnly,
625
+ icon: value && icons.EditIcon,
626
+ id,
627
+ mode: "ghost",
628
+ onClick: handleToggleModal,
629
+ onFocus: handleFocus,
630
+ padding: 3,
631
+ ref: inputRef,
632
+ text: value ? "Edit" : "Set location and radius"
633
+ }
634
+ ),
635
+ value && /* @__PURE__ */ jsxRuntime.jsx(
636
+ ui.Button,
637
+ {
638
+ disabled: readOnly,
639
+ icon: icons.TrashIcon,
640
+ mode: "ghost",
641
+ onClick: handleClear,
642
+ padding: 3,
643
+ text: "Remove",
644
+ tone: "critical"
645
+ }
646
+ )
647
+ ] }) }),
648
+ modalOpen && /* @__PURE__ */ jsxRuntime.jsx(
649
+ ui.Dialog,
650
+ {
651
+ header: "Place the marker and set radius on the map",
652
+ id: `${dialogId}_dialog`,
653
+ onBlur: handleBlur,
654
+ onClose: handleCloseModal,
655
+ ref: dialogRef,
656
+ width: 1,
657
+ children: /* @__PURE__ */ jsxRuntime.jsx(DialogInnerContainer, { children: /* @__PURE__ */ jsxRuntime.jsx(GoogleMapsLoadProxy, { config: getGeoConfig(), children: (api) => /* @__PURE__ */ jsxRuntime.jsx(
658
+ GeopointRadiusSelect,
659
+ {
660
+ api,
661
+ value: value || void 0,
662
+ onChange: readOnly ? void 0 : handleChange,
663
+ defaultLocation: config2.defaultLocation,
664
+ defaultRadiusZoom: config2.defaultRadiusZoom,
665
+ defaultRadius: config2.defaultRadius
666
+ }
667
+ ) }) })
668
+ }
669
+ )
670
+ ] });
671
+ }
672
+ class Arrow extends react.PureComponent {
673
+ line;
674
+ eventHandlers = {};
426
675
  componentDidMount() {
427
676
  const { from, to, api, map, zIndex, onClick, color, arrowRef } = this.props, lineSymbol = {
428
677
  path: api.SymbolPath.FORWARD_OPEN_ARROW
@@ -451,7 +700,7 @@ class Arrow extends react.PureComponent {
451
700
  }
452
701
  }
453
702
  function GeopointMove({ diff, api, map, label }) {
454
- const { fromValue: from, toValue: to } = diff, annotation = diff.isChanged ? diff.annotation : void 0, userColor = sanity.useUserColor(annotation ? annotation.author : null) || void 0, fromRef = react.useRef(), toRef = react.useRef();
703
+ const { fromValue: from, toValue: to } = diff, annotation = diff.isChanged ? diff.annotation : void 0, userColor = sanity.useUserColor(annotation ? annotation.author : null) || void 0, fromRef = react.useRef(void 0), toRef = react.useRef(void 0);
455
704
  return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
456
705
  from && /* @__PURE__ */ jsxRuntime.jsx(
457
706
  Marker,
@@ -505,7 +754,7 @@ function GeopointDiff$1({ api, diff }) {
505
754
  const fromValue = (diff.fromValue || []).filter(hasCoordinates), toValue = (diff.toValue || []).filter(hasCoordinates);
506
755
  if (fromValue.length === 0 && toValue.length === 0)
507
756
  return null;
508
- const bounds = getBounds$1(fromValue, toValue, api);
757
+ const bounds = getBounds$2(fromValue, toValue, api);
509
758
  return /* @__PURE__ */ jsxRuntime.jsx(
510
759
  GoogleMap,
511
760
  {
@@ -533,7 +782,7 @@ function isChangeDiff(diff) {
533
782
  function hasCoordinates(point) {
534
783
  return typeof point.lat == "number" && typeof point.lng == "number";
535
784
  }
536
- function getBounds$1(fromValue, toValue, api) {
785
+ function getBounds$2(fromValue, toValue, api) {
537
786
  const bounds = new api.LatLngBounds();
538
787
  return [...fromValue || [], ...toValue || []].forEach((point) => bounds.extend(point)), bounds;
539
788
  }
@@ -542,8 +791,8 @@ const GeopointFieldDiff = ({
542
791
  schemaType
543
792
  }) => /* @__PURE__ */ jsxRuntime.jsx(RootContainer, { children: /* @__PURE__ */ jsxRuntime.jsx(GoogleMapsLoadProxy, { config: getGeoConfig(), children: (api) => /* @__PURE__ */ jsxRuntime.jsx(GeopointDiff, { api, diff, schemaType }) }) });
544
793
  function GeopointDiff({ api, diff }) {
545
- const { fromValue, toValue } = diff, annotation = sanity.getAnnotationAtPath(diff, ["lat"]) || sanity.getAnnotationAtPath(diff, ["lng"]) || sanity.getAnnotationAtPath(diff, []), center = getCenter(diff, api), bounds = fromValue && toValue ? getBounds(fromValue, toValue, api) : void 0;
546
- return /* @__PURE__ */ jsxRuntime.jsx(sanity.DiffTooltip, { annotations: annotation ? [annotation] : [], description: getAction(diff), children: /* @__PURE__ */ jsxRuntime.jsx("div", { children: /* @__PURE__ */ jsxRuntime.jsx(
794
+ const { fromValue, toValue } = diff, annotation = sanity.getAnnotationAtPath(diff, ["lat"]) || sanity.getAnnotationAtPath(diff, ["lng"]) || sanity.getAnnotationAtPath(diff, []), center = getCenter$1(diff, api), bounds = fromValue && toValue ? getBounds$1(fromValue, toValue, api) : void 0;
795
+ return /* @__PURE__ */ jsxRuntime.jsx(sanity.DiffTooltip, { annotations: annotation ? [annotation] : [], description: getAction$1(diff), children: /* @__PURE__ */ jsxRuntime.jsx("div", { children: /* @__PURE__ */ jsxRuntime.jsx(
547
796
  GoogleMap,
548
797
  {
549
798
  api,
@@ -556,9 +805,117 @@ function GeopointDiff({ api, diff }) {
556
805
  }
557
806
  ) }) });
558
807
  }
559
- function getBounds(fromValue, toValue, api) {
808
+ function getBounds$1(fromValue, toValue, api) {
560
809
  return new api.LatLngBounds().extend(fromValue).extend(toValue);
561
810
  }
811
+ function getCenter$1(diff, api) {
812
+ const { fromValue, toValue } = diff;
813
+ if (fromValue && toValue)
814
+ return getBounds$1(fromValue, toValue, api).getCenter().toJSON();
815
+ if (fromValue)
816
+ return fromValue;
817
+ if (toValue)
818
+ return toValue;
819
+ throw new Error("Neither a from or a to value present");
820
+ }
821
+ function getAction$1(diff) {
822
+ const { fromValue, toValue } = diff;
823
+ return fromValue && toValue ? "Moved" : fromValue ? "Removed" : toValue ? "Added" : "Unchanged";
824
+ }
825
+ function GeopointRadiusMove({ diff, api, map, label }) {
826
+ const { fromValue: from, toValue: to } = diff, annotation = diff.isChanged ? diff.annotation : void 0, userColor = sanity.useUserColor(annotation ? annotation.author : null) || void 0, fromRef = react.useRef(void 0), toRef = react.useRef(void 0), fromCircleRef = react.useRef(void 0), toCircleRef = react.useRef(void 0);
827
+ return react.useEffect(() => {
828
+ const color = userColor?.background || "#4285F4";
829
+ return from && from.radius && (fromCircleRef.current = new api.Circle({
830
+ map,
831
+ center: { lat: from.lat, lng: from.lng },
832
+ radius: from.radius,
833
+ fillColor: color,
834
+ fillOpacity: 0.1,
835
+ strokeColor: color,
836
+ strokeOpacity: 0.3,
837
+ strokeWeight: 1,
838
+ zIndex: 0
839
+ })), to && to.radius && (toCircleRef.current = new api.Circle({
840
+ map,
841
+ center: { lat: to.lat, lng: to.lng },
842
+ radius: to.radius,
843
+ fillColor: color,
844
+ fillOpacity: 0.2,
845
+ strokeColor: color,
846
+ strokeOpacity: 0.8,
847
+ strokeWeight: 2,
848
+ zIndex: 2
849
+ })), () => {
850
+ fromCircleRef.current && fromCircleRef.current.setMap(null), toCircleRef.current && toCircleRef.current.setMap(null);
851
+ };
852
+ }, [api, map, from, to, userColor]), /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
853
+ from && /* @__PURE__ */ jsxRuntime.jsx(
854
+ Marker,
855
+ {
856
+ api,
857
+ map,
858
+ position: from,
859
+ zIndex: 0,
860
+ opacity: 0.55,
861
+ markerRef: fromRef,
862
+ color: userColor
863
+ }
864
+ ),
865
+ from && to && /* @__PURE__ */ jsxRuntime.jsx(Arrow, { api, map, from, to, zIndex: 1, color: userColor }),
866
+ to && /* @__PURE__ */ jsxRuntime.jsx(
867
+ Marker,
868
+ {
869
+ api,
870
+ map,
871
+ position: to,
872
+ zIndex: 2,
873
+ markerRef: toRef,
874
+ label,
875
+ color: userColor
876
+ }
877
+ )
878
+ ] });
879
+ }
880
+ const GeopointRadiusFieldDiff = ({
881
+ diff,
882
+ schemaType
883
+ }) => /* @__PURE__ */ jsxRuntime.jsx(RootContainer, { children: /* @__PURE__ */ jsxRuntime.jsx(GoogleMapsLoadProxy, { config: getGeoConfig(), children: (api) => /* @__PURE__ */ jsxRuntime.jsx(GeopointRadiusDiff, { api, diff, schemaType }) }) });
884
+ function GeopointRadiusDiff({ api, diff }) {
885
+ const { fromValue, toValue } = diff, annotation = sanity.getAnnotationAtPath(diff, ["lat"]) || sanity.getAnnotationAtPath(diff, ["lng"]) || sanity.getAnnotationAtPath(diff, ["radius"]) || sanity.getAnnotationAtPath(diff, []), center = getCenter(diff, api), bounds = fromValue && toValue ? getBounds(fromValue, toValue, api) : void 0;
886
+ return /* @__PURE__ */ jsxRuntime.jsx(sanity.DiffTooltip, { annotations: annotation ? [annotation] : [], description: getAction(diff), children: /* @__PURE__ */ jsxRuntime.jsx("div", { children: /* @__PURE__ */ jsxRuntime.jsx(
887
+ GoogleMap,
888
+ {
889
+ api,
890
+ location: center,
891
+ mapTypeControl: !1,
892
+ controlSize: 20,
893
+ bounds,
894
+ scrollWheel: !1,
895
+ children: (map) => /* @__PURE__ */ jsxRuntime.jsx(GeopointRadiusMove, { api, map, diff })
896
+ }
897
+ ) }) });
898
+ }
899
+ function getBounds(fromValue, toValue, api) {
900
+ const bounds = new api.LatLngBounds().extend(fromValue).extend(toValue), fromRadius = fromValue.radius || 0, toRadius = toValue.radius || 0, maxRadius = Math.max(fromRadius, toRadius);
901
+ if (maxRadius > 0) {
902
+ const radiusInDegrees = maxRadius / 111e3;
903
+ bounds.extend({
904
+ lat: fromValue.lat + radiusInDegrees,
905
+ lng: fromValue.lng + radiusInDegrees
906
+ }), bounds.extend({
907
+ lat: fromValue.lat - radiusInDegrees,
908
+ lng: fromValue.lng - radiusInDegrees
909
+ }), bounds.extend({
910
+ lat: toValue.lat + radiusInDegrees,
911
+ lng: toValue.lng + radiusInDegrees
912
+ }), bounds.extend({
913
+ lat: toValue.lat - radiusInDegrees,
914
+ lng: toValue.lng - radiusInDegrees
915
+ });
916
+ }
917
+ return bounds;
918
+ }
562
919
  function getCenter(diff, api) {
563
920
  const { fromValue, toValue } = diff;
564
921
  if (fromValue && toValue)
@@ -571,22 +928,70 @@ function getCenter(diff, api) {
571
928
  }
572
929
  function getAction(diff) {
573
930
  const { fromValue, toValue } = diff;
574
- return fromValue && toValue ? "Moved" : fromValue ? "Removed" : toValue ? "Added" : "Unchanged";
931
+ if (fromValue && toValue) {
932
+ const latChanged = fromValue.lat !== toValue.lat || fromValue.lng !== toValue.lng, radiusChanged = fromValue.radius !== toValue.radius;
933
+ return latChanged && radiusChanged ? "Moved and radius changed" : latChanged ? "Moved" : radiusChanged ? "Radius changed" : "Unchanged";
934
+ } else {
935
+ if (fromValue)
936
+ return "Removed";
937
+ if (toValue)
938
+ return "Added";
939
+ }
940
+ return "Unchanged";
575
941
  }
576
- var __defProp = Object.defineProperty, __defProps = Object.defineProperties, __getOwnPropDescs = Object.getOwnPropertyDescriptors, __getOwnPropSymbols = Object.getOwnPropertySymbols, __hasOwnProp = Object.prototype.hasOwnProperty, __propIsEnum = Object.prototype.propertyIsEnumerable, __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: !0, configurable: !0, writable: !0, value }) : obj[key] = value, __spreadValues = (a, b) => {
577
- for (var prop in b || (b = {}))
578
- __hasOwnProp.call(b, prop) && __defNormalProp(a, prop, b[prop]);
579
- if (__getOwnPropSymbols)
580
- for (var prop of __getOwnPropSymbols(b))
581
- __propIsEnum.call(b, prop) && __defNormalProp(a, prop, b[prop]);
582
- return a;
583
- }, __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
584
942
  const googleMapsInput = sanity.definePlugin((config2) => (setGeoConfig(config2), {
585
943
  name: "google-maps-input",
944
+ schema: {
945
+ types: [
946
+ {
947
+ name: "geopointRadius",
948
+ title: "Geopoint with Radius",
949
+ type: "object",
950
+ fields: [
951
+ {
952
+ name: "lat",
953
+ title: "Latitude",
954
+ type: "number",
955
+ validation: (Rule) => Rule.required().min(-90).max(90)
956
+ },
957
+ {
958
+ name: "lng",
959
+ title: "Longitude",
960
+ type: "number",
961
+ validation: (Rule) => Rule.required().min(-180).max(180)
962
+ },
963
+ {
964
+ name: "alt",
965
+ title: "Altitude",
966
+ type: "number"
967
+ },
968
+ {
969
+ name: "radius",
970
+ title: "Radius (meters)",
971
+ type: "number",
972
+ validation: (Rule) => Rule.required().min(1).max(5e4)
973
+ }
974
+ ],
975
+ preview: {
976
+ select: {
977
+ lat: "lat",
978
+ lng: "lng",
979
+ radius: "radius"
980
+ },
981
+ prepare({ lat, lng, radius }) {
982
+ return {
983
+ title: `${lat.toFixed(6)}, ${lng.toFixed(6)}`,
984
+ subtitle: radius ? `Radius: ${radius}m` : "No radius set"
985
+ };
986
+ }
987
+ }
988
+ }
989
+ ]
990
+ },
586
991
  form: {
587
992
  components: {
588
993
  input(props) {
589
- return isGeopoint(props.schemaType) ? /* @__PURE__ */ jsxRuntime.jsx(GeopointInput, __spreadProps(__spreadValues({}, props), { geoConfig: config2 })) : props.renderDefault(props);
994
+ return isGeopoint(props.schemaType) ? /* @__PURE__ */ jsxRuntime.jsx(GeopointInput, { ...props, geoConfig: config2 }) : isGeopointRadius(props.schemaType) ? /* @__PURE__ */ jsxRuntime.jsx(GeopointRadiusInput, { ...props, geoConfig: config2 }) : props.renderDefault(props);
590
995
  }
591
996
  }
592
997
  }
@@ -594,11 +999,16 @@ const googleMapsInput = sanity.definePlugin((config2) => (setGeoConfig(config2),
594
999
  function isGeopoint(schemaType) {
595
1000
  return isType("geopoint", schemaType);
596
1001
  }
1002
+ function isGeopointRadius(schemaType) {
1003
+ return isType("geopointRadius", schemaType);
1004
+ }
597
1005
  function isType(name, schema) {
598
- return (schema == null ? void 0 : schema.name) === name ? !0 : schema != null && schema.name ? isType(name, schema == null ? void 0 : schema.type) : !1;
1006
+ return schema?.name === name ? !0 : schema?.name ? isType(name, schema?.type) : !1;
599
1007
  }
600
1008
  exports.GeopointArrayDiff = GeopointArrayDiff;
601
1009
  exports.GeopointFieldDiff = GeopointFieldDiff;
602
1010
  exports.GeopointInput = GeopointInput;
1011
+ exports.GeopointRadiusFieldDiff = GeopointRadiusFieldDiff;
1012
+ exports.GeopointRadiusInput = GeopointRadiusInput;
603
1013
  exports.googleMapsInput = googleMapsInput;
604
1014
  //# sourceMappingURL=index.cjs.map