UNPKG

@sanity/google-maps-input

Version:

Sanity plugin providing input handlers for geo-related input types using Google Maps

605 lines (602 loc) • 26.5 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: !0 }); var jsxRuntime = require("react/jsx-runtime"), react = require("react"), ui = require("@sanity/ui"), icons = require("@sanity/icons"), sanity = require("sanity"), styledComponents = require("styled-components"); const callbackName = "___sanity_googleMapsApiCallback", authFailureCallbackName = "gm_authFailure"; let AuthError$1 = class extends Error { }; function _loadGoogleMapsApi(config2) { return new Promise((resolve, reject) => { window[authFailureCallbackName] = () => { reject(new AuthError$1("Authentication error when loading Google Maps API.")); }, window[callbackName] = () => { resolve(window.google.maps); }; const script = document.createElement("script"); script.onerror = (event, source, lineno, colno, error) => reject(new Error(coeerceError(event, error))), script.src = `https://maps.googleapis.com/maps/api/js?key=${config2.apiKey}&libraries=places&callback=${callbackName}&language=${config2.locale}`, document.getElementsByTagName("head")[0].appendChild(script); }).finally(() => { delete window[callbackName], delete window[authFailureCallbackName]; }); } let memo = null; function loadGoogleMapsApi(config2) { return memo || (memo = _loadGoogleMapsApi(config2), memo.catch(() => { memo = null; }), memo); } function coeerceError(event, error) { return error ? error.message : typeof event == "string" ? event : isErrorEvent(event) ? event.message : "Failed to load Google Maps API"; } function isErrorEvent(event) { return typeof event != "object" || event === null || !("message" in event) ? !1 : typeof event.message == "string"; } function LoadError(props) { var _a; return /* @__PURE__ */ jsxRuntime.jsxs(ui.Card, { tone: "critical", radius: 1, children: [ /* @__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" }) }), /* @__PURE__ */ jsxRuntime.jsx(ui.Box, { paddingX: 4, paddingTop: 4, paddingBottom: 1, children: props.isAuthError ? /* @__PURE__ */ jsxRuntime.jsx(AuthError2, {}) : /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { as: "h3", children: "Error details:" }), /* @__PURE__ */ jsxRuntime.jsx("pre", { children: /* @__PURE__ */ jsxRuntime.jsx(ui.Code, { size: 1, children: "error" in props && ((_a = props.error) == null ? void 0 : _a.message) }) }) ] }) }) ] }); } function AuthError2() { return /* @__PURE__ */ jsxRuntime.jsxs(ui.Text, { children: [ /* @__PURE__ */ jsxRuntime.jsx("p", { children: "The error appears to be related to authentication" }), /* @__PURE__ */ jsxRuntime.jsx("p", { children: "Common causes include:" }), /* @__PURE__ */ jsxRuntime.jsxs("ul", { children: [ /* @__PURE__ */ jsxRuntime.jsx("li", { children: "Incorrect API key" }), /* @__PURE__ */ jsxRuntime.jsx("li", { children: "Referer not allowed" }), /* @__PURE__ */ jsxRuntime.jsx("li", { children: "Missing authentication scope" }) ] }), /* @__PURE__ */ jsxRuntime.jsx("p", { children: "Check the browser developer tools for more information." }) ] }); } const browserLocale = typeof window < "u" && window.navigator.language || "en"; function useLoadGoogleMapsApi(config2) { const locale = config2.defaultLocale || browserLocale || "en-US", [state, setState] = react.useState({ type: "loading" }); return react.useEffect(() => { typeof window > "u" || loadGoogleMapsApi({ locale, apiKey: config2.apiKey }).then( (api) => setState({ type: "loaded", api }), (err) => setState({ type: "error", error: { type: err instanceof AuthError$1 ? "authError" : "loadError", message: err.message } }) ); }, [locale, config2.apiKey]), state; } function GoogleMapsLoadProxy(props) { const loadState = useLoadGoogleMapsApi(props.config); switch (loadState.type) { case "error": return /* @__PURE__ */ jsxRuntime.jsx(LoadError, { error: loadState.error, isAuthError: loadState.error.type === "authError" }); case "loading": return /* @__PURE__ */ jsxRuntime.jsx("div", { children: "Loading Google Maps API" }); case "loaded": return props.children(loadState.api); default: return null; } } let config; function getGeoConfig() { return config; } function setGeoConfig(newConfig) { config = newConfig; } const PreviewImage = styledComponents.styled.img` width: 100%; height: auto; vertical-align: top; `, DialogInnerContainer = styledComponents.styled.div` height: 40rem; `, WrapperContainer = styledComponents.styled.div` position: absolute; right: 10px; top: 10px; width: 220px; `; 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); class SearchInput extends react.PureComponent { constructor() { super(...arguments), __publicField$3(this, "searchInputRef", react.createRef()), __publicField$3(this, "autoComplete"), __publicField$3(this, "handleChange", () => { this.autoComplete && (this.props.onChange(this.autoComplete.getPlace()), this.searchInputRef.current && (this.searchInputRef.current.value = "")); }); } componentDidMount() { const input = this.searchInputRef.current; if (!input) return; const { api, map } = this.props, { Circle, places, event } = api, searchBounds = new Circle({ center: map.getCenter(), radius: 100 }).getBounds(); this.autoComplete = new places.Autocomplete(input, { bounds: searchBounds, types: [] // return all kinds of places }), event.addListener(this.autoComplete, "place_changed", this.handleChange); } render() { return /* @__PURE__ */ jsxRuntime.jsx(WrapperContainer, { children: /* @__PURE__ */ jsxRuntime.jsx( ui.TextInput, { name: "place", ref: this.searchInputRef, placeholder: "Search for place or address", padding: 4 } ) }); } } function latLngAreEqual(latLng1, latLng2) { const lat1 = typeof latLng1.lat == "function" ? latLng1.lat() : latLng1.lat, lng1 = typeof latLng1.lng == "function" ? latLng1.lng() : latLng1.lng, lat2 = typeof latLng2.lat == "function" ? latLng2.lat() : latLng2.lat, lng2 = typeof latLng2.lng == "function" ? latLng2.lng() : latLng2.lng; return lat1 === lat2 && lng1 === lng2; } const MapContainer = styledComponents.styled.div` position: absolute; top: 0; left: 0; height: 100%; width: 100%; box-sizing: border-box; `; 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); class GoogleMap extends react.PureComponent { constructor() { 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", () => { const map = this.state.map; if (!map) return; const { api, onClick } = this.props, { event } = api; this.clickHandler && this.clickHandler.remove(), onClick && (this.clickHandler = event.addListener(map, "click", onClick)); }), __publicField$2(this, "setMapElement", (element) => { if (element && element !== this.mapEl) { const map = this.constructMap(element); this.setState({ map }, this.attachClickHandler); } this.mapEl = element; }); } componentDidMount() { this.attachClickHandler(); } componentDidUpdate(prevProps) { const map = this.state.map; if (!map) return; const { onClick, location, bounds } = this.props; prevProps.onClick !== onClick && this.attachClickHandler(), latLngAreEqual(prevProps.location, location) || map.panTo(this.getCenter()), bounds && (!prevProps.bounds || !bounds.equals(prevProps.bounds)) && map.fitBounds(bounds); } componentWillUnmount() { this.clickHandler && this.clickHandler.remove(); } getCenter() { const { location, api } = this.props; return new api.LatLng(location.lat, location.lng); } constructMap(el) { const { defaultZoom, api, mapTypeControl, controlSize, bounds, scrollWheel } = this.props, map = new api.Map(el, { zoom: defaultZoom, center: this.getCenter(), scrollwheel: scrollWheel, streetViewControl: !1, mapTypeControl, controlSize }); return bounds && map.fitBounds(bounds), map; } render() { const { children } = this.props, { map } = this.state; return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [ /* @__PURE__ */ jsxRuntime.jsx(MapContainer, { ref: this.setMapElement }), children && map ? children(map) : null ] }); } } __publicField$2(GoogleMap, "defaultProps", { defaultZoom: 8, scrollWheel: !0 }); 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); 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"; class Marker extends react.PureComponent { constructor() { super(...arguments), __publicField$1(this, "marker"), __publicField$1(this, "eventHandlers", {}); } componentDidMount() { const { position, api, map, onMove, zIndex, opacity, label, markerRef, color } = this.props, { Marker: GMarker } = api; let icon; color && (icon = { path: markerPath, fillOpacity: 1, fillColor: color.background, strokeColor: color.border, strokeWeight: 2, anchor: new api.Point(10, 35), labelOrigin: new api.Point(10, 11) }), this.marker = new GMarker({ draggable: !!onMove, position, map, zIndex, opacity, label, icon }), markerRef && (markerRef.current = this.marker), this.attachMoveHandler(), this.attachClickHandler(); } componentDidUpdate(prevProps) { if (!this.marker) return; const { position, onMove, label, zIndex, opacity, map } = this.props; prevProps.onMove !== onMove && this.attachMoveHandler(), latLngAreEqual(prevProps.position, position) || this.marker.setPosition(position), prevProps.label !== label && this.marker.setLabel(label || null), prevProps.zIndex !== zIndex && this.marker.setZIndex(zIndex || null), prevProps.opacity !== opacity && this.marker.setOpacity(opacity || null), prevProps.map !== map && this.marker.setMap(map); } componentWillUnmount() { this.eventHandlers.move && this.eventHandlers.move.remove(), this.marker && this.marker.setMap(null); } attachMoveHandler() { const { api, onMove } = this.props; this.eventHandlers.move && this.eventHandlers.move.remove(), this.marker && onMove && (this.eventHandlers.move = api.event.addListener(this.marker, "dragend", onMove)); } attachClickHandler() { const { api, onClick } = this.props; this.eventHandlers.click && this.eventHandlers.click.remove(), this.marker && onClick && (this.eventHandlers.click = api.event.addListener(this.marker, "click", onClick)); } // eslint-disable-next-line class-methods-use-this render() { return null; } } 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) => { for (var prop in b || (b = {})) __hasOwnProp$1.call(b, prop) && __defNormalProp$2(a, prop, b[prop]); if (__getOwnPropSymbols$1) for (var prop of __getOwnPropSymbols$1(b)) __propIsEnum$1.call(b, prop) && __defNormalProp$2(a, prop, b[prop]); return a; }; const fallbackLatLng = { lat: 40.7058254, lng: -74.1180863 }, GeopointSelect = ({ api, value, onChange, defaultLocation = { lng: 10.74609, lat: 59.91273 }, defaultZoom = 8 }) => { const getCenter2 = react.useCallback(() => __spreadValues$1(__spreadValues$1(__spreadValues$1({}, fallbackLatLng), defaultLocation), value), [value, defaultLocation]), setValue = react.useCallback( (geoPoint) => { onChange && onChange(geoPoint); }, [onChange] ), handlePlaceChanged = react.useCallback( (place) => { var _a; (_a = place.geometry) != null && _a.location && setValue(place.geometry.location); }, [setValue] ), handleMarkerDragEnd = react.useCallback( (event) => { event.latLng && setValue(event.latLng); }, [setValue] ), handleMapClick = react.useCallback( (event) => { event.latLng && setValue(event.latLng); }, [setValue] ); return /* @__PURE__ */ jsxRuntime.jsx(GoogleMap, { api, location: getCenter2(), onClick: handleMapClick, defaultZoom, children: (map) => /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [ /* @__PURE__ */ jsxRuntime.jsx(SearchInput, { api, map, onChange: handlePlaceChanged }), value && /* @__PURE__ */ jsxRuntime.jsx( Marker, { api, map, position: value, onMove: onChange ? handleMarkerDragEnd : void 0 } ) ] }) }); }, EMPTY_PATH = [], getStaticImageUrl = (value, apiKey) => { const loc = `${value.lat},${value.lng}`; return `https://maps.googleapis.com/maps/api/staticmap?${new URLSearchParams({ key: apiKey, center: loc, markers: loc, zoom: "13", scale: "2", size: "640x300" }).toString()}`; }; function GeopointInput(props) { const { changed, elementProps, focused, geoConfig: config2, onChange, onPathFocus, path, readOnly, schemaType, value } = props, { id, ref: inputRef, onBlur: handleBlur, onFocus: handleFocus, "aria-describedby": ariaDescribedBy } = elementProps, schemaTypeName = schemaType.name, dialogId = react.useId(), dialogRef = react.useRef(null), handleFocusButton = react.useCallback(() => { var _a; return (_a = inputRef == null ? void 0 : inputRef.current) == null ? void 0 : _a.focus(); }, [inputRef]), [modalOpen, setModalOpen] = react.useState(!1), handleCloseModal = react.useCallback(() => { dialogRef.current && dialogRef.current.blur(), setModalOpen(!1), handleFocusButton(); }, [setModalOpen, handleFocusButton]), handleToggleModal = react.useCallback( () => setModalOpen((currentState) => !currentState), [setModalOpen] ), handleChange = react.useCallback( (latLng) => { onChange([ sanity.setIfMissing({ _type: schemaTypeName }), sanity.set(latLng.lat(), ["lat"]), sanity.set(latLng.lng(), ["lng"]) ]); }, [schemaTypeName, onChange] ), handleClear = react.useCallback(() => { onChange(sanity.unset()); }, [onChange]); return react.useEffect(() => { modalOpen && onPathFocus(EMPTY_PATH); }, [modalOpen, onPathFocus]), !config2 || !config2.apiKey ? /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [ /* @__PURE__ */ jsxRuntime.jsxs("p", { children: [ "The ", /* @__PURE__ */ jsxRuntime.jsx("a", { href: "https://sanity.io/docs/schema-types/geopoint-type", children: "Geopoint type" }), " needs a Google Maps API key with access to:" ] }), /* @__PURE__ */ jsxRuntime.jsxs("ul", { children: [ /* @__PURE__ */ jsxRuntime.jsx("li", { children: "Google Maps JavaScript API" }), /* @__PURE__ */ jsxRuntime.jsx("li", { children: "Google Places API Web Service" }), /* @__PURE__ */ jsxRuntime.jsx("li", { children: "Google Static Maps API" }) ] }), /* @__PURE__ */ jsxRuntime.jsx("p", { children: "Please enter the API key with access to these services in your googleMapsInput plugin config." }) ] }) : /* @__PURE__ */ jsxRuntime.jsxs(ui.Stack, { space: 3, children: [ value && /* @__PURE__ */ jsxRuntime.jsx(sanity.ChangeIndicator, { path, isChanged: changed, hasFocus: !!focused, children: /* @__PURE__ */ jsxRuntime.jsx( PreviewImage, { src: getStaticImageUrl(value, config2.apiKey), alt: "Map location", onClick: handleFocusButton, onDoubleClick: handleToggleModal } ) }), /* @__PURE__ */ jsxRuntime.jsx(ui.Box, { children: /* @__PURE__ */ jsxRuntime.jsxs(ui.Grid, { columns: value ? 2 : 1, gap: 3, children: [ /* @__PURE__ */ jsxRuntime.jsx( ui.Button, { "aria-describedby": ariaDescribedBy, disabled: readOnly, icon: value && icons.EditIcon, id, mode: "ghost", onClick: handleToggleModal, onFocus: handleFocus, padding: 3, ref: inputRef, text: value ? "Edit" : "Set location" } ), value && /* @__PURE__ */ jsxRuntime.jsx( ui.Button, { disabled: readOnly, icon: icons.TrashIcon, mode: "ghost", onClick: handleClear, padding: 3, text: "Remove", tone: "critical" } ) ] }) }), modalOpen && /* @__PURE__ */ jsxRuntime.jsx( ui.Dialog, { header: "Place the marker on the map", id: `${dialogId}_dialog`, onBlur: handleBlur, onClose: handleCloseModal, ref: dialogRef, width: 1, children: /* @__PURE__ */ jsxRuntime.jsx(DialogInnerContainer, { children: /* @__PURE__ */ jsxRuntime.jsx(GoogleMapsLoadProxy, { config: getGeoConfig(), children: (api) => /* @__PURE__ */ jsxRuntime.jsx( GeopointSelect, { api, value: value || void 0, onChange: readOnly ? void 0 : handleChange, defaultLocation: config2.defaultLocation, defaultZoom: config2.defaultZoom } ) }) }) } ) ] }); } 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); class Arrow extends react.PureComponent { constructor() { super(...arguments), __publicField(this, "line"), __publicField(this, "eventHandlers", {}); } componentDidMount() { const { from, to, api, map, zIndex, onClick, color, arrowRef } = this.props, lineSymbol = { path: api.SymbolPath.FORWARD_OPEN_ARROW }; this.line = new api.Polyline({ map, zIndex, path: [from, to], icons: [{ icon: lineSymbol, offset: "50%" }], strokeOpacity: 0.55, strokeColor: color ? color.text : "black" }), onClick && (this.eventHandlers.click = api.event.addListener(this.line, "click", onClick)), arrowRef && (arrowRef.current = this.line); } componentDidUpdate(prevProps) { if (!this.line) return; const { from, to, map } = this.props; (!latLngAreEqual(prevProps.from, from) || !latLngAreEqual(prevProps.to, to)) && this.line.setPath([from, to]), prevProps.map !== map && this.line.setMap(map); } componentWillUnmount() { this.line && this.line.setMap(null), this.eventHandlers.click && this.eventHandlers.click.remove(); } // eslint-disable-next-line class-methods-use-this render() { return null; } } function GeopointMove({ diff, api, map, label }) { 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(); return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [ from && /* @__PURE__ */ jsxRuntime.jsx( Marker, { api, map, position: from, zIndex: 0, opacity: 0.55, markerRef: fromRef, color: userColor } ), from && to && /* @__PURE__ */ jsxRuntime.jsx(Arrow, { api, map, from, to, zIndex: 1, color: userColor }), to && /* @__PURE__ */ jsxRuntime.jsx( Marker, { api, map, position: to, zIndex: 2, markerRef: toRef, label, color: userColor } ) ] }); } const RootContainer = styledComponents.styled.div` position: relative; min-height: 200px; &:empty { background-color: var(--card-skeleton-color-from); display: table; width: 100%; } &:empty:after { content: 'Missing/invalid data'; display: table-cell; vertical-align: middle; text-align: center; position: relative; } `, GeopointArrayDiff = ({ diff, schemaType }) => /* @__PURE__ */ jsxRuntime.jsx(RootContainer, { children: /* @__PURE__ */ jsxRuntime.jsx(GoogleMapsLoadProxy, { config: getGeoConfig(), children: (api) => /* @__PURE__ */ jsxRuntime.jsx(GeopointDiff$1, { api, diff, schemaType }) }) }); function GeopointDiff$1({ api, diff }) { const fromValue = (diff.fromValue || []).filter(hasCoordinates), toValue = (diff.toValue || []).filter(hasCoordinates); if (fromValue.length === 0 && toValue.length === 0) return null; const bounds = getBounds$1(fromValue, toValue, api); return /* @__PURE__ */ jsxRuntime.jsx( GoogleMap, { api, location: bounds.getCenter().toJSON(), mapTypeControl: !1, controlSize: 20, bounds, children: (map) => /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: diff.items.map(({ toIndex, diff: pointDiff }) => isChangeDiff(pointDiff) ? /* @__PURE__ */ jsxRuntime.jsx( GeopointMove, { api, map, diff: pointDiff, label: `${toIndex}` }, toIndex ) : null) }) } ); } function isChangeDiff(diff) { return diff.action !== "unchanged" && diff.type === "object"; } function hasCoordinates(point) { return typeof point.lat == "number" && typeof point.lng == "number"; } function getBounds$1(fromValue, toValue, api) { const bounds = new api.LatLngBounds(); return [...fromValue || [], ...toValue || []].forEach((point) => bounds.extend(point)), bounds; } const GeopointFieldDiff = ({ diff, schemaType }) => /* @__PURE__ */ jsxRuntime.jsx(RootContainer, { children: /* @__PURE__ */ jsxRuntime.jsx(GoogleMapsLoadProxy, { config: getGeoConfig(), children: (api) => /* @__PURE__ */ jsxRuntime.jsx(GeopointDiff, { api, diff, schemaType }) }) }); function GeopointDiff({ api, diff }) { 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; return /* @__PURE__ */ jsxRuntime.jsx(sanity.DiffTooltip, { annotations: annotation ? [annotation] : [], description: getAction(diff), children: /* @__PURE__ */ jsxRuntime.jsx("div", { children: /* @__PURE__ */ jsxRuntime.jsx( GoogleMap, { api, location: center, mapTypeControl: !1, controlSize: 20, bounds, scrollWheel: !1, children: (map) => /* @__PURE__ */ jsxRuntime.jsx(GeopointMove, { api, map, diff }) } ) }) }); } function getBounds(fromValue, toValue, api) { return new api.LatLngBounds().extend(fromValue).extend(toValue); } function getCenter(diff, api) { const { fromValue, toValue } = diff; if (fromValue && toValue) return getBounds(fromValue, toValue, api).getCenter().toJSON(); if (fromValue) return fromValue; if (toValue) return toValue; throw new Error("Neither a from or a to value present"); } function getAction(diff) { const { fromValue, toValue } = diff; return fromValue && toValue ? "Moved" : fromValue ? "Removed" : toValue ? "Added" : "Unchanged"; } 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) => { for (var prop in b || (b = {})) __hasOwnProp.call(b, prop) && __defNormalProp(a, prop, b[prop]); if (__getOwnPropSymbols) for (var prop of __getOwnPropSymbols(b)) __propIsEnum.call(b, prop) && __defNormalProp(a, prop, b[prop]); return a; }, __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b)); const googleMapsInput = sanity.definePlugin((config2) => (setGeoConfig(config2), { name: "google-maps-input", form: { components: { input(props) { return isGeopoint(props.schemaType) ? /* @__PURE__ */ jsxRuntime.jsx(GeopointInput, __spreadProps(__spreadValues({}, props), { geoConfig: config2 })) : props.renderDefault(props); } } } })); function isGeopoint(schemaType) { return isType("geopoint", schemaType); } function isType(name, schema) { return (schema == null ? void 0 : schema.name) === name ? !0 : schema != null && schema.name ? isType(name, schema == null ? void 0 : schema.type) : !1; } exports.GeopointArrayDiff = GeopointArrayDiff; exports.GeopointFieldDiff = GeopointFieldDiff; exports.GeopointInput = GeopointInput; exports.googleMapsInput = googleMapsInput; //# sourceMappingURL=index.cjs.map