google-maps-js-api-react
Version:
Fast, tree-shakable, and light-weight React components and hooks for integrating Google Maps API functionality
222 lines (220 loc) • 7.43 kB
JavaScript
import { handleRef_default } from './chunk-CEDFL5Z3.js';
import { PanesContext_default } from './chunk-EJQ2B6OM.js';
import { getConnectedEventsAndProps_default, handleHas_default, useHandlersAndProps_default } from './chunk-HVIYR2JS.js';
import { MAPS } from './chunk-IGDL35GK.js';
import { MapContext_default } from './chunk-ENX7YFEM.js';
import { forwardRef, useMemo, Suspense, useState } from 'react';
import setRef from 'react-helpful-utils/setRef';
import { GoogleMapsLoader } from 'google-maps-js-api-loader';
import noop from 'lodash.noop';
import { jsx } from 'react/jsx-runtime';
var MAX_LAT = Math.atan(Math.sinh(Math.PI)) * 180 / Math.PI;
var connectedEventsAndProps = getConnectedEventsAndProps_default([
"center",
"heading",
"mapTypeId",
"tilt",
"zoom",
"bounds"
]);
var isKeyOmitted = handleHas_default([
"className",
"style",
"id",
"children",
"defaultOptions",
"fallback"
]);
var mapsStorage = /* @__PURE__ */ new Map();
var GoogleMap = forwardRef(
(props, ref) => {
const { defaultOptions = {} } = props;
const key = `${defaultOptions.backgroundColor || ""},${defaultOptions.controlSize || 40},${defaultOptions.mapId || ""},${defaultOptions.renderingType || ""}`;
return useMemo(() => {
if (!mapsStorage.has(key)) {
mapsStorage.set(key, []);
}
const components = mapsStorage.get(key);
for (let i = 0; i < components.length; i++) {
const render2 = components[i];
if (render2._isFree) {
return render2;
}
}
let map;
let panes;
let mapPromise;
let resolveMap = noop;
let isPanesPending = true;
const Content = (props2) => {
const forceRerender = useState()[1];
if (panes) {
return /* @__PURE__ */ jsx(MapContext_default.Provider, { value: map, children: /* @__PURE__ */ jsx(PanesContext_default.Provider, { value: panes, children: props2.children }) });
}
if (isPanesPending) {
isPanesPending = false;
const overlayView = new (GoogleMapsLoader.get(MAPS)).OverlayView();
overlayView.onRemove = overlayView.draw = noop;
overlayView.onAdd = () => {
panes = overlayView.getPanes();
overlayView.setMap(null);
forceRerender(panes);
};
overlayView.setMap(map);
}
return null;
};
const SuspendedGoogleMap = (props2) => {
if (map) {
const { children } = props2;
useHandlersAndProps_default(
props2,
connectedEventsAndProps,
isKeyOmitted
)(map);
return children ? /* @__PURE__ */ jsx(Content, { children }) : null;
}
if (GoogleMapsLoader.getStatus(MAPS) == "error") {
throw GoogleMapsLoader.getError(MAPS);
}
if (!mapPromise) {
mapPromise = new Promise((resolve) => {
resolveMap = () => {
resolveMap = noop;
mapPromise = void 0;
resolve();
};
});
}
throw mapPromise;
};
const divRef = handleRef_default((el) => {
let isAlive = true;
const options = {
...props.defaultOptions,
...props
};
const _ref = ref;
props = ref = void 0;
if (map) {
map.setOptions(options);
map.moveCamera({});
el.prepend(map.getDiv());
setRef(_ref, map);
} else {
const handleMap = () => {
if (isAlive) {
const div = document.createElement("div");
div.style.width = div.style.height = "100%";
map = new (GoogleMapsLoader.get(MAPS)).Map(div, options);
resolveMap();
el.prepend(div);
setRef(_ref, map);
}
};
if (GoogleMapsLoader.getStatus(MAPS) == "loaded") {
handleMap();
} else {
GoogleMapsLoader.load(MAPS).then(handleMap, () => {
resolveMap();
});
}
}
return () => {
isAlive = false;
render._isFree = true;
resolveMap();
if (map) {
const { ControlPosition, MapTypeId } = google.maps;
map.setOptions({
clickableIcons: true,
disableDefaultUI: false,
disableDoubleClickZoom: false,
draggable: true,
draggableCursor: null,
draggingCursor: null,
fullscreenControl: true,
fullscreenControlOptions: {
position: ControlPosition.INLINE_END_BLOCK_START
},
gestureHandling: "auto",
headingInteractionEnabled: false,
isFractionalZoomEnabled: map.getRenderingType() == google.maps.RenderingType.VECTOR,
keyboardShortcuts: true,
mapTypeControl: true,
mapTypeControlOptions: {
mapTypeIds: [
MapTypeId.ROADMAP,
MapTypeId.SATELLITE,
MapTypeId.HYBRID,
MapTypeId.TERRAIN
],
position: ControlPosition.BLOCK_START_INLINE_START,
style: google.maps.MapTypeControlStyle.DEFAULT
},
mapTypeId: MapTypeId.ROADMAP,
maxZoom: null,
minZoom: null,
noClear: false,
panControl: false,
panControlOptions: {
position: ControlPosition.INLINE_END_BLOCK_END
},
restriction: {
latLngBounds: {
west: -180,
east: 180,
north: MAX_LAT,
south: -MAX_LAT
},
strictBounds: false
},
rotateControl: false,
rotateControlOptions: {
position: ControlPosition.INLINE_END_BLOCK_END
},
scaleControl: false,
scaleControlOptions: {
style: google.maps.ScaleControlStyle.DEFAULT
},
scrollwheel: true,
streetView: null,
streetViewControl: true,
styles: null,
tiltInteractionEnabled: false,
zoomControl: true,
zoomControlOptions: {
position: ControlPosition.INLINE_END_BLOCK_END
}
});
map.moveCamera({ tilt: 0, heading: 0 });
setRef(_ref, null);
}
};
});
const render = (_props, _ref) => {
if (render._isFree) {
props = _props;
ref = _ref;
render._isFree = false;
}
return /* @__PURE__ */ jsx(
"div",
{
ref: divRef,
className: _props.className,
style: _props.style,
id: _props.id,
children: /* @__PURE__ */ jsx(Suspense, { fallback: _props.fallback || null, children: jsx(SuspendedGoogleMap, _props) })
}
);
};
components.push(render);
return render;
}, [key])(props, ref);
}
);
var GoogleMap_default = GoogleMap;
export { GoogleMap_default };
//# sourceMappingURL=chunk-OBFPDSVZ.js.map
//# sourceMappingURL=chunk-OBFPDSVZ.js.map