UNPKG

react-gallimaps

Version:

A minimalist React wrapper for GalliMaps Vector Plugin - Easy integration for Nepal's mapping solution

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