react-gallimaps
Version:
A minimalist React wrapper for GalliMaps Vector Plugin - Easy integration for Nepal's mapping solution
2 lines (1 loc) • 5.91 kB
JavaScript
;var e=require("react/jsx-runtime"),t=require("react");const a=t.createContext(void 0),r=()=>{const e=t.useContext(a);if(void 0===e)throw Error("useGallimaps must be used within a GallimapsProvider");return e},n=e=>{const[a,r]=t.useState("idle");return t.useEffect(()=>{if(!e)return void r("error");let t=document.querySelector(`script[src="${e}"]`);if(t)r(t.getAttribute("data-status")||"ready");else{t=document.createElement("script"),t.src=e,t.async=!0,t.setAttribute("data-status","loading"),document.body.appendChild(t),r("loading");const a=e=>{const a="load"===e.type?"ready":"error";t.setAttribute("data-status",a),r(a)};t.addEventListener("load",a),t.addEventListener("error",a)}return()=>{t&&(t.removeEventListener("load",r),t.removeEventListener("error",r))}},[e]),a},s=t.createContext(null);function l(){return t.useContext(s)}const o=()=>{const{mapInstance:e}=r();return{displayPinMarker:t.useCallback(t=>{if(!e)return null;const a=e.getCenter?e.getCenter():null,r=(e=>({latLng:e.position,draggable:e.draggable,color:e.color}))(t),n=e.displayPinMarker(r);return a&&"function"==typeof e.setCenter&&setTimeout(()=>{"function"==typeof e.setCenter&&e.setCenter(a)},50),n},[e]),removePinMarker:t.useCallback(t=>{null==e||e.removePinMarker(t)},[e]),autoCompleteSearch:t.useCallback(t=>e?e.autoCompleteSearch(t):Promise.resolve([]),[e]),searchData:t.useCallback(t=>e?e.searchData(t):Promise.resolve(null),[e]),drawPolygon:t.useCallback(t=>{if(!e)return null;const a=(e=>{const{coordinates:t,name:a,type:r="Polygon",style:n={}}=e;let s;return"Polygon"===r?s=[t]:"LineString"===r?s=t:"Point"===r&&(s=t[0]||[0,0]),{name:a,color:n.color||"blue",opacity:n.opacity||.5,width:n.width,height:n.height,radius:n.radius,latLng:t[0]||[0,0],geoJson:{type:"Feature",geometry:{type:r,coordinates:s}}}})(t);return e.drawPolygon(a)},[e]),removePolygon:t.useCallback(t=>{null==e||e.removePolygon(t)},[e]),isReady:!!e}};exports.Gallimap=({accessToken:a,center:s=[27.7172,85.324],zoom:o=15,minZoom:i=5,maxZoom:c=25,clickable:u=!1,customClickFunctions:d=[],panoId:m,mapStyle:p={width:"100%",height:"400px"},panoStyle:g={width:"100%",height:"300px"},onMapInit:h,children:y})=>{const f=t.useRef(null),v=t.useRef(null),{mapInstance:x,setMapInstance:C}=r(),k=l(),[P,M]=t.useState(!1),S=n("https://gallimap.com/static/dist/js/gallimaps.vector.min.latest.js"),[b,w]=t.useState(!0),[j,E]=t.useState(null);t.useEffect(()=>(M(!0),()=>M(!1)),[]);const N=e=>{if(!e||!e.lngLat||!k)return;const{lat:t,lng:a}=e.lngLat,r=e=>e*Math.PI/180,n=(e,t)=>{const a=r(t[0]-e[0]),n=r(t[1]-e[1]),s=Math.sin(a/2)*Math.sin(a/2)+Math.cos(r(e[0]))*Math.cos(r(t[0]))*Math.sin(n/2)*Math.sin(n/2);return 12742e3*Math.atan2(Math.sqrt(s),Math.sqrt(1-s))};let s=null,l=40;for(const e of k.current.values()){const r=n([t,a],e.position);l>r&&(l=r,s=e)}s&&s.onClick&&s.onClick(s),d.forEach(t=>t(e))};return t.useEffect(()=>{if("ready"===S&&P&&f.current&&!x){w(!0);try{const e={accessToken:a,map:{container:"gallimap-"+Date.now(),center:s,zoom:o,minZoom:i,maxZoom:c,clickable:u},customClickFunctions:[N]};if(f.current.id=e.map.container,v.current){const t=m?"gallimap-pano-"+Date.now():"gallimap-pano-hidden-"+Date.now();v.current.id=t,e.pano={container:t}}const t=new window.GalliMapPlugin(e);C(t),E(null),h&&h(t)}catch(e){E(e instanceof Error?e.message:"Failed to initialize map")}finally{w(!1)}return()=>{x&&C(null)}}},[S,P,a,s,o,x,m]),e.jsxs("div",{className:"gallimap-container",children:[b&&e.jsx("div",{className:"map-loading",children:"Loading map..."}),j&&e.jsxs("div",{className:"map-error",children:["Error: ",j]}),e.jsx("div",{ref:f,style:p,className:"gallimap"}),m&&e.jsx("div",{ref:v,style:g,className:"gallimap-pano"}),!m&&e.jsx("div",{ref:v,style:{display:"none"},className:"gallimap-pano-hidden"}),y]})},exports.GallimapsProvider=({children:r})=>{const[n,s]=t.useState(null);return e.jsx(a.Provider,{value:{mapInstance:n,setMapInstance:s},children:r})},exports.Marker=({position:e,draggable:a,color:r,onClick:n,className:s,markerId:i})=>{const{displayPinMarker:c,removePinMarker:u,isReady:d}=o(),m=l(),p=t.useRef(null);return t.useEffect(()=>{if(d&&m){if(m.current.has(i)||p.current){const e=m.current.get(i);e&&m.current.set(i,{...e,onClick:n})}else{const t=c({position:e,draggable:a,color:r});p.current=t,m.current.set(i,{position:e,onClick:n})}return()=>{p.current&&(u(p.current),p.current=null),m.current.delete(i)}}},[d,i,e[0],e[1],a,r,n,c,u,m]),null},exports.MarkerRegistryProvider=function({children:a}){const r=t.useRef(new Map);return e.jsx(s.Provider,{value:r,children:a})},exports.Polygon=({coordinates:e,name:a,type:r="Polygon",style:n={},onPolygonClick:s})=>{const{drawPolygon:l,removePolygon:i,isReady:c}=o();return t.useEffect(()=>{if(c&&e.length)return l({coordinates:e,name:a,type:r,style:n}),()=>{i(a)}},[c,e,a,r,n,l,i,s]),null},exports.Search=({onSelect:a,onResults:r,placeholder:n="Search locations...",className:s})=>{const[l,i]=t.useState(""),[c,u]=t.useState([]),[d,m]=t.useState(!1),{autoCompleteSearch:p,searchData:g,isReady:h}=o(),y=t.useCallback(async e=>{if(h&&e.length>=3){m(!0);try{const t=await p(e),a=Array.isArray(t)?t:[];u(a),r&&r(a)}catch(e){u([]),r&&r([])}finally{m(!1)}}else u([])},[h,p,r]);return t.useEffect(()=>{const e=setTimeout(()=>{y(l)},300);return()=>clearTimeout(e)},[l,y]),e.jsxs("div",{className:"gallimap-search "+(s||""),children:[e.jsx("input",{type:"text",value:l,onChange:e=>i(e.target.value),placeholder:n,className:"gallimap-search-input"}),d&&e.jsx("div",{className:"gallimap-search-loading",children:"Searching..."}),c.length>0&&e.jsx("ul",{className:"gallimap-search-results",children:c.map((t,r)=>e.jsx("li",{onClick:()=>(async e=>{try{await g(e.name||e.toString()),a&&a(e)}catch(e){}i(e.name||e.toString()),u([])})(t),className:"gallimap-search-result",children:t.name||t.display_name||t.toString()},r))})]})},exports.useGallimaps=r,exports.useGallimapsAPI=o,exports.useScript=n;