UNPKG

react-naver-maps

Version:

React Navermaps API integration for modern development.

433 lines (418 loc) 12.5 kB
"use strict"; var __create = Object.create; var __defProp = Object.defineProperty; var __getOwnPropDesc = Object.getOwnPropertyDescriptor; var __getOwnPropNames = Object.getOwnPropertyNames; var __getProtoOf = Object.getPrototypeOf; var __hasOwnProp = Object.prototype.hasOwnProperty; var __export = (target, all) => { for (var name in all) __defProp(target, name, { get: all[name], enumerable: true }); }; var __copyProps = (to, from, except, desc) => { if (from && typeof from === "object" || typeof from === "function") { for (let key of __getOwnPropNames(from)) if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); } return to; }; var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps( isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target, mod )); var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); // src/naver-map.tsx var naver_map_exports = {}; __export(naver_map_exports, { NaverMap: () => NaverMap }); module.exports = __toCommonJS(naver_map_exports); var import_lodash2 = __toESM(require("lodash.pick")); var import_lodash3 = __toESM(require("lodash.upperfirst")); var import_react9 = require("react"); // src/contexts/container.ts var import_react = require("react"); var ContainerContext = (0, import_react.createContext)({ element: null }); var useContainerContext = () => (0, import_react.useContext)(ContainerContext); // src/contexts/event-target.ts var import_react2 = require("react"); var EventTargetContext = (0, import_react2.createContext)(void 0); var useEventTarget = () => (0, import_react2.useContext)(EventTargetContext); // src/contexts/naver-map.ts var import_react3 = require("react"); var NaverMapContext = (0, import_react3.createContext)(void 0); // src/helpers/event.tsx var import_camelcase = __toESM(require("camelcase")); var import_lodash = __toESM(require("lodash.pick")); var import_react5 = require("react"); // src/listener.tsx var import_react4 = require("react"); function useListener(target, type, listener) { (0, import_react4.useEffect)(() => { const _listener = (...args) => listener(...args, target); const mapEventListener = naver.maps.Event.addListener(target, type, _listener); return () => { naver.maps.Event.removeListener(mapEventListener); }; }, [target, type, listener]); } var Listener = (props) => { const { target: propTarget, type, listener } = props; const contextTarget = useEventTarget(); const target = propTarget || contextTarget; if (!target) { throw new Error("react-naver-maps: No Target to add listener"); } useListener(target, type, listener); return null; }; // src/helpers/event.tsx var import_jsx_runtime = require("react/jsx-runtime"); function HandleEvents(props) { const { events: events2, listeners: _listeners } = props; const eventMap = (0, import_react5.useMemo)(() => createEventMap(events2), events2); const listeners = (0, import_lodash.default)(_listeners, Object.keys(eventMap)); return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_jsx_runtime.Fragment, { children: Object.keys(listeners).map((key) => { const eventName = eventMap[key]; const listener = listeners[key]; return listener ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Listener, { type: eventName, listener }, key) : null; }) }); } function createEventMap(events2) { return events2.reduce((acc, eventName) => { const key = (0, import_camelcase.default)(`on_${eventName}`); return { [key]: eventName, ...acc }; }, {}); } // src/hooks/use-previous.ts var import_react6 = require("react"); function usePrevious(state, deps) { const ref = (0, import_react6.useRef)(); (0, import_react6.useEffect)(() => { ref.current = state; }, deps); return ref.current; } // src/use-navermaps.ts var import_suspend_react = require("suspend-react"); // src/contexts/client-options.ts var import_react7 = require("react"); var ClientOptionsContext = (0, import_react7.createContext)({}); var useClientOptions = () => (0, import_react7.useContext)(ClientOptionsContext); // src/load-navermaps-script.tsx var import_react8 = require("react"); // src/utils/load-script.ts var import_load_script = __toESM(require("load-script")); function loadScript(src) { return new Promise((resolve, reject) => { (0, import_load_script.default)(src, (err, script) => { if (err) reject(err); else resolve(script); }); }); } // src/load-navermaps-script.tsx var import_jsx_runtime2 = require("react/jsx-runtime"); function loadNavermapsScript(options) { const url = makeUrl(options); const promise = loadScript(url).then(() => { const navermaps = window.naver.maps; if (navermaps.jsContentLoaded) { return navermaps; } return new Promise((resolve) => { navermaps.onJSContentLoaded = () => { resolve(navermaps); }; }); }); return promise; } function makeUrl(options) { const submodules = options.submodules; const clientIdQuery = "ncpKeyId" in options ? `ncpKeyId=${options.ncpKeyId}` : "ncpClientId" in options ? `ncpClientId=${options.ncpClientId}` : "govClientId" in options ? `govClientId=${options.govClientId}` : "finClientId" in options ? `finClientId=${options.finClientId}` : void 0; if (!clientIdQuery) { throw new Error("react-naver-maps: ncpKeyId, ncpClientId, govClientId or finClientId is required"); } let url = `https://oapi.map.naver.com/openapi/v3/maps.js?${clientIdQuery}`; if (submodules) { url += `&submodules=${submodules.join(",")}`; } return url; } // src/use-navermaps.ts async function load(options) { var _a; if (typeof window !== "undefined" && ((_a = window.naver) == null ? void 0 : _a.maps)) { return window.naver.maps; } if (!options) { throw new Error("react-naver-maps: set options with `useNavermaps.config`"); } return await loadNavermapsScript(options); } function useNavermaps() { var _a; if (typeof window === "undefined") { throw new Error("react-naver-maps: browser"); } if ((_a = window.naver) == null ? void 0 : _a.maps) { return window.naver.maps; } const options = useClientOptions(); return (0, import_suspend_react.suspend)(load, [options, "react-naver-maps/loadClient"]); } // src/naver-map.tsx var import_jsx_runtime3 = require("react/jsx-runtime"); var basicMapOptionKeys = [ "background", "baseTileOpacity", "disableDoubleClickZoom", "disableDoubleTapZoom", "disableKineticPan", "disableTwoFingerTapZoom", "draggable", "keyboardShortcuts", "logoControl", "logoControlOptions", "mapDataControl", "mapDataControlOptions", "mapTypeControl", "mapTypeControlOptions", "mapTypes", "maxBounds", "maxZoom", "minZoom", "padding", "pinchZoom", "resizeOrigin", "scaleControl", "scaleControlOptions", "scrollWheel", "overlayZoomEffect", "tileSpare", "tileTransition", "zoomControl", "zoomControlOptions", "zoomOrigin", "blankTileImage" ]; var kvoKeys = [ "mapTypeId", "size", "bounds", "center", "zoom", "centerPoint" ]; var kvoEvents = [ ...kvoKeys.map((key) => `${key}_changed`), "mapType_changed" ]; var uiEvents = [ "mousedown", "mouseup", "click", "dblclick", "rightclick", "mouseover", "mouseout", "mousemove", "dragstart", "drag", "dragend", "touchstart", "touchmove", "touchend", "pinchstart", "pinch", "pinchend", "tap", "longtap", "twofingertap", "doubletap" ]; var mapOnlyEvents = [ "addLayer", "idle", "init", "keydown", "keyup", "panning", "projection_changed", "removeLayer", "resize", "tilesloaded", "zooming" ]; var events = [...uiEvents, ...kvoEvents, ...mapOnlyEvents]; var defaultOptionKeyMap = { mapTypeId: "defaultMapTypeId", size: "defaultSize", bounds: "defaultBounds", center: "defaultCenter", zoom: "defaultZoom", centerPoint: "defaultCenterPoint" }; var NaverMap = (0, import_react9.forwardRef)(function NaverMap2(props, ref) { const navermaps = useNavermaps(); const { element: mapDiv } = useContainerContext(); const [nmap, setNmap] = (0, import_react9.useState)(); const nmapRef = (0, import_react9.useRef)(); (0, import_react9.useLayoutEffect)(() => { if (!mapDiv) { throw new Error("react-naver-maps: MapDiv is not found. Did you correctly wrap with `MapDiv`?"); } const basicMapOptions = (0, import_lodash2.default)(props, basicMapOptionKeys); const kvos = kvoKeys.reduce((acc, key) => { if (props[defaultOptionKeyMap[key]]) { return { ...acc, [key]: props[defaultOptionKeyMap[key]] }; } if (props[key]) { return { ...acc, [key]: props[key] }; } return acc; }, {}); const _nmap = new navermaps.Map(mapDiv, { ...basicMapOptions, ...kvos }); setNmap(_nmap); nmapRef.current = _nmap; return () => { _nmap.destroy(); }; }, []); const uncontrolledOmittedProps = Object.keys(props).reduce((acc, key) => { if (key in defaultOptionKeyMap && props[defaultOptionKeyMap[key]]) { return acc; } return { ...acc, [key]: props[key] }; }, {}); (0, import_react9.useImperativeHandle)(ref, () => nmapRef.current); return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_jsx_runtime3.Fragment, { children: nmap && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(NaverMapCore, { ...uncontrolledOmittedProps, nmap }) }); }); function NaverMapCore({ nmap, children, ...mapProps }) { const basicMapOptions = (0, import_lodash2.default)(mapProps, basicMapOptionKeys); const { mapTypeId, size, bounds, center, centerPoint, zoom } = mapProps; const prevKVOs = usePrevious({ mapTypeId, size, bounds, center, centerPoint, zoom }, [ mapTypeId, size, bounds, center, centerPoint, zoom ]); function getDirtyKVOs(keys) { return keys.reduce((acc, key) => { const currentValue = nmap[`get${(0, import_lodash3.default)(key)}`](); const propValue = mapProps[key]; if (!propValue || prevKVOs && prevKVOs[key] === propValue) { return acc; } const isEqual = typeof currentValue.equals === "function" ? currentValue.equals(propValue) : currentValue === propValue; if (isEqual) { return acc; } return { ...acc, [key]: propValue }; }, {}); } (0, import_react9.useLayoutEffect)(() => { nmap.setOptions(basicMapOptions); }, [Object.values(basicMapOptions)]); (0, import_react9.useLayoutEffect)(() => { const updated = getDirtyKVOs(["size"]).size; if (updated) { nmap.setSize(updated); } }, [size]); (0, import_react9.useLayoutEffect)(() => { const updated = getDirtyKVOs(["mapTypeId"]).mapTypeId; if (updated) { nmap.setMapTypeId(updated); } }, [mapTypeId]); (0, import_react9.useLayoutEffect)(() => { const dirties = getDirtyKVOs(["bounds", "center", "centerPoint", "zoom"]); if (dirties.bounds) { nmap.fitBounds(dirties.bounds); return; } if (dirties.center && dirties.zoom) { nmap.morph(dirties.center, dirties.zoom); return; } if (dirties.centerPoint) { nmap.setCenterPoint(dirties.centerPoint); } if (dirties.center) { nmap.panTo(dirties.center, {}); } if (dirties.zoom) { nmap.setZoom(dirties.zoom); } }, [bounds, center, centerPoint, zoom]); return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(NaverMapContext.Provider, { value: nmap, children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(EventTargetContext.Provider, { value: nmap, children: /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_jsx_runtime3.Fragment, { children: [ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(HandleEvents, { events, listeners: mapProps }), children ] }) }) }); } // Annotate the CommonJS export names for ESM import in node: 0 && (module.exports = { NaverMap }); //# sourceMappingURL=naver-map.js.map