@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
JavaScript
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
;