@gradeui/ui 3.0.0 → 3.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/components/ui/button.md +11 -7
- package/components/ui/combobox.md +46 -0
- package/components/ui/data-view.md +59 -0
- package/components/ui/dropdown-menu.md +1 -0
- package/components/ui/logo.md +8 -6
- package/components/ui/map.md +9 -0
- package/components/ui/media-surface.md +1 -0
- package/components/ui/property-list.md +43 -0
- package/components/ui/sidebar.md +2 -1
- package/components/ui/swatch.md +88 -0
- package/dist/contracts.js +6 -6
- package/dist/contracts.js.map +1 -1
- package/dist/contracts.mjs +6 -6
- package/dist/contracts.mjs.map +1 -1
- package/dist/index.d.mts +902 -415
- package/dist/index.d.ts +902 -415
- package/dist/index.js +609 -72
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +609 -72
- package/dist/index.mjs.map +1 -1
- package/dist/map/google.d.mts +1 -1
- package/dist/map/google.d.ts +1 -1
- package/dist/map/google.js +1 -1
- package/dist/map/google.js.map +1 -1
- package/dist/map/google.mjs +1 -1
- package/dist/map/google.mjs.map +1 -1
- package/dist/map/leaflet.d.mts +1 -1
- package/dist/map/leaflet.d.ts +1 -1
- package/dist/map/leaflet.js +2 -2
- package/dist/map/leaflet.js.map +1 -1
- package/dist/map/leaflet.mjs +2 -2
- package/dist/map/leaflet.mjs.map +1 -1
- package/dist/map/mapbox.d.mts +1 -1
- package/dist/map/mapbox.d.ts +1 -1
- package/dist/map/mapbox.js +2 -2
- package/dist/map/mapbox.js.map +1 -1
- package/dist/map/mapbox.mjs +2 -2
- package/dist/map/mapbox.mjs.map +1 -1
- package/dist/map/maplibre.d.mts +1 -1
- package/dist/map/maplibre.d.ts +1 -1
- package/dist/map/maplibre.js +1 -1
- package/dist/map/maplibre.js.map +1 -1
- package/dist/map/maplibre.mjs +1 -1
- package/dist/map/maplibre.mjs.map +1 -1
- package/dist/styles.css +1 -1
- package/dist/{types-BxywIwvG.d.mts → types-B45Uirkp.d.mts} +23 -0
- package/dist/{types-BxywIwvG.d.ts → types-B45Uirkp.d.ts} +23 -0
- package/package.json +2 -1
- package/styles/globals.css +306 -95
package/dist/map/google.d.mts
CHANGED
package/dist/map/google.d.ts
CHANGED
package/dist/map/google.js
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
"use client";
|
|
2
|
-
'use strict';var
|
|
2
|
+
'use strict';var M=[{featureType:"poi",stylers:[{visibility:"off"}]},{featureType:"transit",stylers:[{visibility:"simplified"}]}],L=[{elementType:"geometry",stylers:[{color:"#1a1a1a"}]},{elementType:"labels.text.stroke",stylers:[{color:"#1a1a1a"}]},{elementType:"labels.text.fill",stylers:[{color:"#9ca3af"}]},{featureType:"poi",stylers:[{visibility:"off"}]},{featureType:"road",elementType:"geometry",stylers:[{color:"#262626"}]},{featureType:"road",elementType:"labels.text.fill",stylers:[{color:"#9ca3af"}]},{featureType:"water",elementType:"geometry",stylers:[{color:"#0f172a"}]},{featureType:"transit",stylers:[{visibility:"simplified"},{color:"#3a3a3a"}]}],c=y=>y==="dark"?L:M,h=async(y,t,i)=>{if(!t.apiKey)throw i.onError({code:"api-key-missing",message:'@gradeui/ui Map: provider="google" requires an `apiKey` prop.'}),new Error("google apiKey missing");let g;try{let e=await import('@googlemaps/js-api-loader');g=e.Loader??e.default?.Loader;}catch(e){throw i.onError({code:"sdk-missing",message:'@gradeui/ui Map: `@googlemaps/js-api-loader` is not installed. Run `pnpm add @googlemaps/js-api-loader` to use provider="google".',cause:e}),e}let f=new g({apiKey:t.apiKey,version:"weekly",libraries:["maps","marker"]}),a;try{a=await f.load();}catch(e){throw i.onError({code:"provider-init-failed",message:"@gradeui/ui Map: Google Maps loader failed.",cause:e}),e}let u=t.appearance==="satellite",T=t.tools==="zoom"||t.tools==="auto"&&t.interactive,v={"top-left":a.maps.ControlPosition.LEFT_TOP,"top-right":a.maps.ControlPosition.RIGHT_TOP,"bottom-left":a.maps.ControlPosition.LEFT_BOTTOM,"bottom-right":a.maps.ControlPosition.RIGHT_BOTTOM},o=new a.maps.Map(y,{center:{lat:t.center[1],lng:t.center[0]},zoom:t.zoom,mapTypeId:u?a.maps.MapTypeId.HYBRID:a.maps.MapTypeId.ROADMAP,mapId:t.mapId,styles:u?void 0:c(t.appearance==="dark"?"dark":"light"),disableDefaultUI:true,zoomControl:T,zoomControlOptions:{position:v[t.toolsPosition]},gestureHandling:t.interactive?"auto":"none",keyboardShortcuts:t.interactive});if(t.bounds){let e=new a.maps.LatLngBounds({lat:t.bounds[0][1],lng:t.bounds[0][0]},{lat:t.bounds[1][1],lng:t.bounds[1][0]});o.fitBounds(e);}await new Promise(e=>{a.maps.event.addListenerOnce(o,"idle",()=>e());}),i.onLoad();let p=new globalThis.Map;return {setCenter:e=>o.setCenter({lat:e[1],lng:e[0]}),setZoom:e=>o.setZoom(e),setBounds:(e,n)=>{let s=new a.maps.LatLngBounds({lat:e[1],lng:e[0]},{lat:n[1],lng:n[0]});o.fitBounds(s);},setAppearance:e=>{e==="satellite"?(o.setMapTypeId(a.maps.MapTypeId.HYBRID),o.setOptions({styles:void 0})):(o.setMapTypeId(a.maps.MapTypeId.ROADMAP),o.setOptions({styles:c(e)}));},setInteractive:e=>{o.setOptions({zoomControl:t.tools==="zoom"||t.tools==="auto"&&e,gestureHandling:e?"auto":"none",keyboardShortcuts:e});},flyTo:(e,n)=>{o.panTo({lat:e[1],lng:e[0]}),n?.zoom!=null&&o.setZoom(n.zoom);},panTo:e=>o.panTo({lat:e[1],lng:e[0]}),fitBounds:(e,n)=>{if(e.length===0)return;let s=new a.maps.LatLngBounds;for(let[r,d]of e)s.extend({lat:d,lng:r});o.fitBounds(s,n?.paddingPx??40);},getCenter:()=>{let e=o.getCenter();return e?[e.lng(),e.lat()]:[0,0]},getZoom:()=>o.getZoom()??0,getBounds:()=>{let e=o.getBounds();if(!e)return [[0,0],[0,0]];let n=e.getSouthWest(),s=e.getNorthEast();return [[n.lng(),n.lat()],[s.lng(),s.lat()]]},addMarker:(e,n,s)=>{let r=document.createElement("div");r.dataset.gdsPart="map-marker",r.dataset.gdsState="idle",r.style.cursor="pointer",s==="center"&&(r.style.transform="translateY(50%)"),r.addEventListener("mouseenter",()=>i.onMarkerHover(e)),r.addEventListener("mouseleave",()=>i.onMarkerHover(null)),r.addEventListener("click",l=>{i.onMarkerClick(e,m.coords,l);});let d=new a.maps.marker.AdvancedMarkerElement({map:o,position:{lat:n[1],lng:n[0]},content:r}),m={element:r,coords:n,setHovered:l=>{r.dataset.gdsState=l?"hovered":"idle",d.zIndex=l?10:1;},setPosition:l=>{m.coords=l,d.position={lat:l[1],lng:l[0]};},remove:()=>{d.map=null,p.delete(e);}};return p.set(e,{marker:d,handle:m}),m},destroy:()=>{p.forEach(({marker:e})=>{e.map=null;}),p.clear();},instance:o}};exports.createGoogleAdapter=h;//# sourceMappingURL=google.js.map
|
|
3
3
|
//# sourceMappingURL=google.js.map
|
package/dist/map/google.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../components/ui/map/adapters/google.ts"],"names":["GOOGLE_LIGHT_STYLES","GOOGLE_DARK_STYLES","stylesFor","appearance","createGoogleAdapter","container","opts","callbacks","LoaderCtor","mod","err","loader","google","isSat","map","b","resolve","markers","coords","zoom","sw","ne","enabled","fopts","list","fbopts","lng","lat","c","id","anchor","element","e","handle","marker","hovered","next"],"mappings":"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","file":"google.js","sourcesContent":["import type {\n AdapterFactory,\n AdapterInstance,\n Coords,\n MarkerHandle,\n} from \"../types\";\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\ntype AnyStyles = any[];\n\nconst GOOGLE_LIGHT_STYLES: AnyStyles = [\n // Neutral light preset — POIs hidden, transit muted.\n { featureType: \"poi\", stylers: [{ visibility: \"off\" }] },\n { featureType: \"transit\", stylers: [{ visibility: \"simplified\" }] },\n];\n\nconst GOOGLE_DARK_STYLES: AnyStyles = [\n { elementType: \"geometry\", stylers: [{ color: \"#1a1a1a\" }] },\n { elementType: \"labels.text.stroke\", stylers: [{ color: \"#1a1a1a\" }] },\n { elementType: \"labels.text.fill\", stylers: [{ color: \"#9ca3af\" }] },\n { featureType: \"poi\", stylers: [{ visibility: \"off\" }] },\n {\n featureType: \"road\",\n elementType: \"geometry\",\n stylers: [{ color: \"#262626\" }],\n },\n {\n featureType: \"road\",\n elementType: \"labels.text.fill\",\n stylers: [{ color: \"#9ca3af\" }],\n },\n {\n featureType: \"water\",\n elementType: \"geometry\",\n stylers: [{ color: \"#0f172a\" }],\n },\n {\n featureType: \"transit\",\n stylers: [{ visibility: \"simplified\" }, { color: \"#3a3a3a\" }],\n },\n];\n\nconst stylesFor = (appearance: \"light\" | \"dark\"): AnyStyles =>\n appearance === \"dark\" ? GOOGLE_DARK_STYLES : GOOGLE_LIGHT_STYLES;\n\nexport const createGoogleAdapter: AdapterFactory = async (\n container,\n opts,\n callbacks\n) => {\n if (!opts.apiKey) {\n callbacks.onError({\n code: \"api-key-missing\",\n message:\n '@gradeui/ui Map: provider=\"google\" requires an `apiKey` prop.',\n });\n throw new Error(\"google apiKey missing\");\n }\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n let LoaderCtor: any;\n try {\n const mod = await import(\"@googlemaps/js-api-loader\");\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n LoaderCtor = (mod as any).Loader ?? (mod as any).default?.Loader;\n } catch (err) {\n callbacks.onError({\n code: \"sdk-missing\",\n message:\n '@gradeui/ui Map: `@googlemaps/js-api-loader` is not installed. Run `pnpm add @googlemaps/js-api-loader` to use provider=\"google\".',\n cause: err,\n });\n throw err;\n }\n\n const loader = new LoaderCtor({\n apiKey: opts.apiKey,\n version: \"weekly\",\n libraries: [\"maps\", \"marker\"],\n });\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n let google: any;\n try {\n google = await loader.load();\n } catch (err) {\n callbacks.onError({\n code: \"provider-init-failed\",\n message: \"@gradeui/ui Map: Google Maps loader failed.\",\n cause: err,\n });\n throw err;\n }\n\n const isSat = opts.appearance === \"satellite\";\n\n const map = new google.maps.Map(container, {\n center: { lat: opts.center[1], lng: opts.center[0] },\n zoom: opts.zoom,\n mapTypeId: isSat\n ? google.maps.MapTypeId.HYBRID\n : google.maps.MapTypeId.ROADMAP,\n mapId: opts.mapId,\n styles: isSat\n ? undefined\n : stylesFor(opts.appearance === \"dark\" ? \"dark\" : \"light\"),\n disableDefaultUI: !opts.interactive,\n gestureHandling: opts.interactive ? \"auto\" : \"none\",\n keyboardShortcuts: opts.interactive,\n });\n\n if (opts.bounds) {\n const b = new google.maps.LatLngBounds(\n { lat: opts.bounds[0][1], lng: opts.bounds[0][0] },\n { lat: opts.bounds[1][1], lng: opts.bounds[1][0] }\n );\n map.fitBounds(b);\n }\n\n await new Promise<void>((resolve) => {\n google.maps.event.addListenerOnce(map, \"idle\", () => resolve());\n });\n callbacks.onLoad();\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const markers = new globalThis.Map<string, { marker: any; handle: MarkerHandle }>();\n\n const adapter: AdapterInstance = {\n setCenter: (coords) =>\n map.setCenter({ lat: coords[1], lng: coords[0] }),\n setZoom: (zoom) => map.setZoom(zoom),\n setBounds: (sw, ne) => {\n const b = new google.maps.LatLngBounds(\n { lat: sw[1], lng: sw[0] },\n { lat: ne[1], lng: ne[0] }\n );\n map.fitBounds(b);\n },\n setAppearance: (appearance) => {\n if (appearance === \"satellite\") {\n map.setMapTypeId(google.maps.MapTypeId.HYBRID);\n map.setOptions({ styles: undefined });\n } else {\n map.setMapTypeId(google.maps.MapTypeId.ROADMAP);\n map.setOptions({ styles: stylesFor(appearance) });\n }\n },\n setInteractive: (enabled) => {\n map.setOptions({\n disableDefaultUI: !enabled,\n gestureHandling: enabled ? \"auto\" : \"none\",\n keyboardShortcuts: enabled,\n });\n },\n flyTo: (coords, fopts) => {\n map.panTo({ lat: coords[1], lng: coords[0] });\n if (fopts?.zoom != null) map.setZoom(fopts.zoom);\n },\n panTo: (coords) => map.panTo({ lat: coords[1], lng: coords[0] }),\n fitBounds: (list, fbopts) => {\n if (list.length === 0) return;\n const b = new google.maps.LatLngBounds();\n for (const [lng, lat] of list) b.extend({ lat, lng });\n map.fitBounds(b, fbopts?.paddingPx ?? 40);\n },\n getCenter: () => {\n const c = map.getCenter();\n return c ? [c.lng(), c.lat()] : [0, 0];\n },\n getZoom: () => map.getZoom() ?? 0,\n getBounds: () => {\n const b = map.getBounds();\n if (!b) return [\n [0, 0],\n [0, 0],\n ];\n const sw = b.getSouthWest();\n const ne = b.getNorthEast();\n return [\n [sw.lng(), sw.lat()],\n [ne.lng(), ne.lat()],\n ];\n },\n addMarker: (id, coords, anchor) => {\n const element = document.createElement(\"div\");\n element.dataset.gdsPart = \"map-marker\";\n element.dataset.gdsState = \"idle\";\n element.style.cursor = \"pointer\";\n // Google AdvancedMarker anchors the *bottom-center* of `content` to\n // the coord by default. For \"center\" anchor, shift content down so\n // the visual midpoint lands on the coord.\n if (anchor === \"center\") {\n element.style.transform = \"translateY(50%)\";\n }\n\n element.addEventListener(\"mouseenter\", () => callbacks.onMarkerHover(id));\n element.addEventListener(\"mouseleave\", () => callbacks.onMarkerHover(null));\n element.addEventListener(\"click\", (e) => {\n callbacks.onMarkerClick(id, handle.coords, e);\n });\n\n const marker = new google.maps.marker.AdvancedMarkerElement({\n map,\n position: { lat: coords[1], lng: coords[0] },\n content: element,\n });\n\n const handle: MarkerHandle = {\n element,\n coords,\n setHovered: (hovered) => {\n element.dataset.gdsState = hovered ? \"hovered\" : \"idle\";\n marker.zIndex = hovered ? 10 : 1;\n },\n setPosition: (next) => {\n handle.coords = next;\n marker.position = { lat: next[1], lng: next[0] };\n },\n remove: () => {\n marker.map = null;\n markers.delete(id);\n },\n };\n\n markers.set(id, { marker, handle });\n return handle;\n },\n destroy: () => {\n markers.forEach(({ marker }) => {\n marker.map = null;\n });\n markers.clear();\n // Google Map has no explicit destroy(); GC handles it once the\n // container DOM node is removed.\n },\n instance: map,\n };\n\n return adapter;\n};\n"]}
|
|
1
|
+
{"version":3,"sources":["../../components/ui/map/adapters/google.ts"],"names":["GOOGLE_LIGHT_STYLES","GOOGLE_DARK_STYLES","stylesFor","appearance","createGoogleAdapter","container","opts","callbacks","LoaderCtor","mod","err","loader","google","isSat","showZoom","googleCorner","map","b","resolve","markers","coords","zoom","sw","ne","enabled","fopts","list","fbopts","lng","lat","c","id","anchor","element","e","handle","marker","hovered","next"],"mappings":"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","file":"google.js","sourcesContent":["import type {\n AdapterFactory,\n AdapterInstance,\n Coords,\n MarkerHandle,\n} from \"../types\";\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\ntype AnyStyles = any[];\n\nconst GOOGLE_LIGHT_STYLES: AnyStyles = [\n // Neutral light preset — POIs hidden, transit muted.\n { featureType: \"poi\", stylers: [{ visibility: \"off\" }] },\n { featureType: \"transit\", stylers: [{ visibility: \"simplified\" }] },\n];\n\nconst GOOGLE_DARK_STYLES: AnyStyles = [\n { elementType: \"geometry\", stylers: [{ color: \"#1a1a1a\" }] },\n { elementType: \"labels.text.stroke\", stylers: [{ color: \"#1a1a1a\" }] },\n { elementType: \"labels.text.fill\", stylers: [{ color: \"#9ca3af\" }] },\n { featureType: \"poi\", stylers: [{ visibility: \"off\" }] },\n {\n featureType: \"road\",\n elementType: \"geometry\",\n stylers: [{ color: \"#262626\" }],\n },\n {\n featureType: \"road\",\n elementType: \"labels.text.fill\",\n stylers: [{ color: \"#9ca3af\" }],\n },\n {\n featureType: \"water\",\n elementType: \"geometry\",\n stylers: [{ color: \"#0f172a\" }],\n },\n {\n featureType: \"transit\",\n stylers: [{ visibility: \"simplified\" }, { color: \"#3a3a3a\" }],\n },\n];\n\nconst stylesFor = (appearance: \"light\" | \"dark\"): AnyStyles =>\n appearance === \"dark\" ? GOOGLE_DARK_STYLES : GOOGLE_LIGHT_STYLES;\n\nexport const createGoogleAdapter: AdapterFactory = async (\n container,\n opts,\n callbacks\n) => {\n if (!opts.apiKey) {\n callbacks.onError({\n code: \"api-key-missing\",\n message:\n '@gradeui/ui Map: provider=\"google\" requires an `apiKey` prop.',\n });\n throw new Error(\"google apiKey missing\");\n }\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n let LoaderCtor: any;\n try {\n const mod = await import(\"@googlemaps/js-api-loader\");\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n LoaderCtor = (mod as any).Loader ?? (mod as any).default?.Loader;\n } catch (err) {\n callbacks.onError({\n code: \"sdk-missing\",\n message:\n '@gradeui/ui Map: `@googlemaps/js-api-loader` is not installed. Run `pnpm add @googlemaps/js-api-loader` to use provider=\"google\".',\n cause: err,\n });\n throw err;\n }\n\n const loader = new LoaderCtor({\n apiKey: opts.apiKey,\n version: \"weekly\",\n libraries: [\"maps\", \"marker\"],\n });\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n let google: any;\n try {\n google = await loader.load();\n } catch (err) {\n callbacks.onError({\n code: \"provider-init-failed\",\n message: \"@gradeui/ui Map: Google Maps loader failed.\",\n cause: err,\n });\n throw err;\n }\n\n const isSat = opts.appearance === \"satellite\";\n\n // Tools — shared vocabulary (types.ts). Google's default UI is loud\n // (map-type switcher, street view, fullscreen), so the Grade contract\n // disables ALL of it and adds back only the zoom control, docked via\n // ControlPosition. This also makes Google match the other providers'\n // quiet chrome instead of its own kitchen sink.\n const showZoom =\n opts.tools === \"zoom\" || (opts.tools === \"auto\" && opts.interactive);\n const googleCorner: Record<string, google.maps.ControlPosition> = {\n \"top-left\": google.maps.ControlPosition.LEFT_TOP,\n \"top-right\": google.maps.ControlPosition.RIGHT_TOP,\n \"bottom-left\": google.maps.ControlPosition.LEFT_BOTTOM,\n \"bottom-right\": google.maps.ControlPosition.RIGHT_BOTTOM,\n };\n\n const map = new google.maps.Map(container, {\n center: { lat: opts.center[1], lng: opts.center[0] },\n zoom: opts.zoom,\n mapTypeId: isSat\n ? google.maps.MapTypeId.HYBRID\n : google.maps.MapTypeId.ROADMAP,\n mapId: opts.mapId,\n styles: isSat\n ? undefined\n : stylesFor(opts.appearance === \"dark\" ? \"dark\" : \"light\"),\n disableDefaultUI: true,\n zoomControl: showZoom,\n zoomControlOptions: {\n position: googleCorner[opts.toolsPosition],\n },\n gestureHandling: opts.interactive ? \"auto\" : \"none\",\n keyboardShortcuts: opts.interactive,\n });\n\n if (opts.bounds) {\n const b = new google.maps.LatLngBounds(\n { lat: opts.bounds[0][1], lng: opts.bounds[0][0] },\n { lat: opts.bounds[1][1], lng: opts.bounds[1][0] }\n );\n map.fitBounds(b);\n }\n\n await new Promise<void>((resolve) => {\n google.maps.event.addListenerOnce(map, \"idle\", () => resolve());\n });\n callbacks.onLoad();\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const markers = new globalThis.Map<string, { marker: any; handle: MarkerHandle }>();\n\n const adapter: AdapterInstance = {\n setCenter: (coords) =>\n map.setCenter({ lat: coords[1], lng: coords[0] }),\n setZoom: (zoom) => map.setZoom(zoom),\n setBounds: (sw, ne) => {\n const b = new google.maps.LatLngBounds(\n { lat: sw[1], lng: sw[0] },\n { lat: ne[1], lng: ne[0] }\n );\n map.fitBounds(b);\n },\n setAppearance: (appearance) => {\n if (appearance === \"satellite\") {\n map.setMapTypeId(google.maps.MapTypeId.HYBRID);\n map.setOptions({ styles: undefined });\n } else {\n map.setMapTypeId(google.maps.MapTypeId.ROADMAP);\n map.setOptions({ styles: stylesFor(appearance) });\n }\n },\n setInteractive: (enabled) => {\n // disableDefaultUI stays true permanently (Grade owns the chrome);\n // only the zoom control follows interactivity under tools=\"auto\".\n map.setOptions({\n zoomControl:\n opts.tools === \"zoom\" || (opts.tools === \"auto\" && enabled),\n gestureHandling: enabled ? \"auto\" : \"none\",\n keyboardShortcuts: enabled,\n });\n },\n flyTo: (coords, fopts) => {\n map.panTo({ lat: coords[1], lng: coords[0] });\n if (fopts?.zoom != null) map.setZoom(fopts.zoom);\n },\n panTo: (coords) => map.panTo({ lat: coords[1], lng: coords[0] }),\n fitBounds: (list, fbopts) => {\n if (list.length === 0) return;\n const b = new google.maps.LatLngBounds();\n for (const [lng, lat] of list) b.extend({ lat, lng });\n map.fitBounds(b, fbopts?.paddingPx ?? 40);\n },\n getCenter: () => {\n const c = map.getCenter();\n return c ? [c.lng(), c.lat()] : [0, 0];\n },\n getZoom: () => map.getZoom() ?? 0,\n getBounds: () => {\n const b = map.getBounds();\n if (!b) return [\n [0, 0],\n [0, 0],\n ];\n const sw = b.getSouthWest();\n const ne = b.getNorthEast();\n return [\n [sw.lng(), sw.lat()],\n [ne.lng(), ne.lat()],\n ];\n },\n addMarker: (id, coords, anchor) => {\n const element = document.createElement(\"div\");\n element.dataset.gdsPart = \"map-marker\";\n element.dataset.gdsState = \"idle\";\n element.style.cursor = \"pointer\";\n // Google AdvancedMarker anchors the *bottom-center* of `content` to\n // the coord by default. For \"center\" anchor, shift content down so\n // the visual midpoint lands on the coord.\n if (anchor === \"center\") {\n element.style.transform = \"translateY(50%)\";\n }\n\n element.addEventListener(\"mouseenter\", () => callbacks.onMarkerHover(id));\n element.addEventListener(\"mouseleave\", () => callbacks.onMarkerHover(null));\n element.addEventListener(\"click\", (e) => {\n callbacks.onMarkerClick(id, handle.coords, e);\n });\n\n const marker = new google.maps.marker.AdvancedMarkerElement({\n map,\n position: { lat: coords[1], lng: coords[0] },\n content: element,\n });\n\n const handle: MarkerHandle = {\n element,\n coords,\n setHovered: (hovered) => {\n element.dataset.gdsState = hovered ? \"hovered\" : \"idle\";\n marker.zIndex = hovered ? 10 : 1;\n },\n setPosition: (next) => {\n handle.coords = next;\n marker.position = { lat: next[1], lng: next[0] };\n },\n remove: () => {\n marker.map = null;\n markers.delete(id);\n },\n };\n\n markers.set(id, { marker, handle });\n return handle;\n },\n destroy: () => {\n markers.forEach(({ marker }) => {\n marker.map = null;\n });\n markers.clear();\n // Google Map has no explicit destroy(); GC handles it once the\n // container DOM node is removed.\n },\n instance: map,\n };\n\n return adapter;\n};\n"]}
|
package/dist/map/google.mjs
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
"use client";
|
|
2
|
-
var
|
|
2
|
+
var M=[{featureType:"poi",stylers:[{visibility:"off"}]},{featureType:"transit",stylers:[{visibility:"simplified"}]}],L=[{elementType:"geometry",stylers:[{color:"#1a1a1a"}]},{elementType:"labels.text.stroke",stylers:[{color:"#1a1a1a"}]},{elementType:"labels.text.fill",stylers:[{color:"#9ca3af"}]},{featureType:"poi",stylers:[{visibility:"off"}]},{featureType:"road",elementType:"geometry",stylers:[{color:"#262626"}]},{featureType:"road",elementType:"labels.text.fill",stylers:[{color:"#9ca3af"}]},{featureType:"water",elementType:"geometry",stylers:[{color:"#0f172a"}]},{featureType:"transit",stylers:[{visibility:"simplified"},{color:"#3a3a3a"}]}],c=y=>y==="dark"?L:M,h=async(y,t,i)=>{if(!t.apiKey)throw i.onError({code:"api-key-missing",message:'@gradeui/ui Map: provider="google" requires an `apiKey` prop.'}),new Error("google apiKey missing");let g;try{let e=await import('@googlemaps/js-api-loader');g=e.Loader??e.default?.Loader;}catch(e){throw i.onError({code:"sdk-missing",message:'@gradeui/ui Map: `@googlemaps/js-api-loader` is not installed. Run `pnpm add @googlemaps/js-api-loader` to use provider="google".',cause:e}),e}let f=new g({apiKey:t.apiKey,version:"weekly",libraries:["maps","marker"]}),a;try{a=await f.load();}catch(e){throw i.onError({code:"provider-init-failed",message:"@gradeui/ui Map: Google Maps loader failed.",cause:e}),e}let u=t.appearance==="satellite",T=t.tools==="zoom"||t.tools==="auto"&&t.interactive,v={"top-left":a.maps.ControlPosition.LEFT_TOP,"top-right":a.maps.ControlPosition.RIGHT_TOP,"bottom-left":a.maps.ControlPosition.LEFT_BOTTOM,"bottom-right":a.maps.ControlPosition.RIGHT_BOTTOM},o=new a.maps.Map(y,{center:{lat:t.center[1],lng:t.center[0]},zoom:t.zoom,mapTypeId:u?a.maps.MapTypeId.HYBRID:a.maps.MapTypeId.ROADMAP,mapId:t.mapId,styles:u?void 0:c(t.appearance==="dark"?"dark":"light"),disableDefaultUI:true,zoomControl:T,zoomControlOptions:{position:v[t.toolsPosition]},gestureHandling:t.interactive?"auto":"none",keyboardShortcuts:t.interactive});if(t.bounds){let e=new a.maps.LatLngBounds({lat:t.bounds[0][1],lng:t.bounds[0][0]},{lat:t.bounds[1][1],lng:t.bounds[1][0]});o.fitBounds(e);}await new Promise(e=>{a.maps.event.addListenerOnce(o,"idle",()=>e());}),i.onLoad();let p=new globalThis.Map;return {setCenter:e=>o.setCenter({lat:e[1],lng:e[0]}),setZoom:e=>o.setZoom(e),setBounds:(e,n)=>{let s=new a.maps.LatLngBounds({lat:e[1],lng:e[0]},{lat:n[1],lng:n[0]});o.fitBounds(s);},setAppearance:e=>{e==="satellite"?(o.setMapTypeId(a.maps.MapTypeId.HYBRID),o.setOptions({styles:void 0})):(o.setMapTypeId(a.maps.MapTypeId.ROADMAP),o.setOptions({styles:c(e)}));},setInteractive:e=>{o.setOptions({zoomControl:t.tools==="zoom"||t.tools==="auto"&&e,gestureHandling:e?"auto":"none",keyboardShortcuts:e});},flyTo:(e,n)=>{o.panTo({lat:e[1],lng:e[0]}),n?.zoom!=null&&o.setZoom(n.zoom);},panTo:e=>o.panTo({lat:e[1],lng:e[0]}),fitBounds:(e,n)=>{if(e.length===0)return;let s=new a.maps.LatLngBounds;for(let[r,d]of e)s.extend({lat:d,lng:r});o.fitBounds(s,n?.paddingPx??40);},getCenter:()=>{let e=o.getCenter();return e?[e.lng(),e.lat()]:[0,0]},getZoom:()=>o.getZoom()??0,getBounds:()=>{let e=o.getBounds();if(!e)return [[0,0],[0,0]];let n=e.getSouthWest(),s=e.getNorthEast();return [[n.lng(),n.lat()],[s.lng(),s.lat()]]},addMarker:(e,n,s)=>{let r=document.createElement("div");r.dataset.gdsPart="map-marker",r.dataset.gdsState="idle",r.style.cursor="pointer",s==="center"&&(r.style.transform="translateY(50%)"),r.addEventListener("mouseenter",()=>i.onMarkerHover(e)),r.addEventListener("mouseleave",()=>i.onMarkerHover(null)),r.addEventListener("click",l=>{i.onMarkerClick(e,m.coords,l);});let d=new a.maps.marker.AdvancedMarkerElement({map:o,position:{lat:n[1],lng:n[0]},content:r}),m={element:r,coords:n,setHovered:l=>{r.dataset.gdsState=l?"hovered":"idle",d.zIndex=l?10:1;},setPosition:l=>{m.coords=l,d.position={lat:l[1],lng:l[0]};},remove:()=>{d.map=null,p.delete(e);}};return p.set(e,{marker:d,handle:m}),m},destroy:()=>{p.forEach(({marker:e})=>{e.map=null;}),p.clear();},instance:o}};export{h as createGoogleAdapter};//# sourceMappingURL=google.mjs.map
|
|
3
3
|
//# sourceMappingURL=google.mjs.map
|
package/dist/map/google.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../components/ui/map/adapters/google.ts"],"names":["GOOGLE_LIGHT_STYLES","GOOGLE_DARK_STYLES","stylesFor","appearance","createGoogleAdapter","container","opts","callbacks","LoaderCtor","mod","err","loader","google","isSat","map","b","resolve","markers","coords","zoom","sw","ne","enabled","fopts","list","fbopts","lng","lat","c","id","anchor","element","e","handle","marker","hovered","next"],"mappings":"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","file":"google.mjs","sourcesContent":["import type {\n AdapterFactory,\n AdapterInstance,\n Coords,\n MarkerHandle,\n} from \"../types\";\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\ntype AnyStyles = any[];\n\nconst GOOGLE_LIGHT_STYLES: AnyStyles = [\n // Neutral light preset — POIs hidden, transit muted.\n { featureType: \"poi\", stylers: [{ visibility: \"off\" }] },\n { featureType: \"transit\", stylers: [{ visibility: \"simplified\" }] },\n];\n\nconst GOOGLE_DARK_STYLES: AnyStyles = [\n { elementType: \"geometry\", stylers: [{ color: \"#1a1a1a\" }] },\n { elementType: \"labels.text.stroke\", stylers: [{ color: \"#1a1a1a\" }] },\n { elementType: \"labels.text.fill\", stylers: [{ color: \"#9ca3af\" }] },\n { featureType: \"poi\", stylers: [{ visibility: \"off\" }] },\n {\n featureType: \"road\",\n elementType: \"geometry\",\n stylers: [{ color: \"#262626\" }],\n },\n {\n featureType: \"road\",\n elementType: \"labels.text.fill\",\n stylers: [{ color: \"#9ca3af\" }],\n },\n {\n featureType: \"water\",\n elementType: \"geometry\",\n stylers: [{ color: \"#0f172a\" }],\n },\n {\n featureType: \"transit\",\n stylers: [{ visibility: \"simplified\" }, { color: \"#3a3a3a\" }],\n },\n];\n\nconst stylesFor = (appearance: \"light\" | \"dark\"): AnyStyles =>\n appearance === \"dark\" ? GOOGLE_DARK_STYLES : GOOGLE_LIGHT_STYLES;\n\nexport const createGoogleAdapter: AdapterFactory = async (\n container,\n opts,\n callbacks\n) => {\n if (!opts.apiKey) {\n callbacks.onError({\n code: \"api-key-missing\",\n message:\n '@gradeui/ui Map: provider=\"google\" requires an `apiKey` prop.',\n });\n throw new Error(\"google apiKey missing\");\n }\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n let LoaderCtor: any;\n try {\n const mod = await import(\"@googlemaps/js-api-loader\");\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n LoaderCtor = (mod as any).Loader ?? (mod as any).default?.Loader;\n } catch (err) {\n callbacks.onError({\n code: \"sdk-missing\",\n message:\n '@gradeui/ui Map: `@googlemaps/js-api-loader` is not installed. Run `pnpm add @googlemaps/js-api-loader` to use provider=\"google\".',\n cause: err,\n });\n throw err;\n }\n\n const loader = new LoaderCtor({\n apiKey: opts.apiKey,\n version: \"weekly\",\n libraries: [\"maps\", \"marker\"],\n });\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n let google: any;\n try {\n google = await loader.load();\n } catch (err) {\n callbacks.onError({\n code: \"provider-init-failed\",\n message: \"@gradeui/ui Map: Google Maps loader failed.\",\n cause: err,\n });\n throw err;\n }\n\n const isSat = opts.appearance === \"satellite\";\n\n const map = new google.maps.Map(container, {\n center: { lat: opts.center[1], lng: opts.center[0] },\n zoom: opts.zoom,\n mapTypeId: isSat\n ? google.maps.MapTypeId.HYBRID\n : google.maps.MapTypeId.ROADMAP,\n mapId: opts.mapId,\n styles: isSat\n ? undefined\n : stylesFor(opts.appearance === \"dark\" ? \"dark\" : \"light\"),\n disableDefaultUI: !opts.interactive,\n gestureHandling: opts.interactive ? \"auto\" : \"none\",\n keyboardShortcuts: opts.interactive,\n });\n\n if (opts.bounds) {\n const b = new google.maps.LatLngBounds(\n { lat: opts.bounds[0][1], lng: opts.bounds[0][0] },\n { lat: opts.bounds[1][1], lng: opts.bounds[1][0] }\n );\n map.fitBounds(b);\n }\n\n await new Promise<void>((resolve) => {\n google.maps.event.addListenerOnce(map, \"idle\", () => resolve());\n });\n callbacks.onLoad();\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const markers = new globalThis.Map<string, { marker: any; handle: MarkerHandle }>();\n\n const adapter: AdapterInstance = {\n setCenter: (coords) =>\n map.setCenter({ lat: coords[1], lng: coords[0] }),\n setZoom: (zoom) => map.setZoom(zoom),\n setBounds: (sw, ne) => {\n const b = new google.maps.LatLngBounds(\n { lat: sw[1], lng: sw[0] },\n { lat: ne[1], lng: ne[0] }\n );\n map.fitBounds(b);\n },\n setAppearance: (appearance) => {\n if (appearance === \"satellite\") {\n map.setMapTypeId(google.maps.MapTypeId.HYBRID);\n map.setOptions({ styles: undefined });\n } else {\n map.setMapTypeId(google.maps.MapTypeId.ROADMAP);\n map.setOptions({ styles: stylesFor(appearance) });\n }\n },\n setInteractive: (enabled) => {\n map.setOptions({\n disableDefaultUI: !enabled,\n gestureHandling: enabled ? \"auto\" : \"none\",\n keyboardShortcuts: enabled,\n });\n },\n flyTo: (coords, fopts) => {\n map.panTo({ lat: coords[1], lng: coords[0] });\n if (fopts?.zoom != null) map.setZoom(fopts.zoom);\n },\n panTo: (coords) => map.panTo({ lat: coords[1], lng: coords[0] }),\n fitBounds: (list, fbopts) => {\n if (list.length === 0) return;\n const b = new google.maps.LatLngBounds();\n for (const [lng, lat] of list) b.extend({ lat, lng });\n map.fitBounds(b, fbopts?.paddingPx ?? 40);\n },\n getCenter: () => {\n const c = map.getCenter();\n return c ? [c.lng(), c.lat()] : [0, 0];\n },\n getZoom: () => map.getZoom() ?? 0,\n getBounds: () => {\n const b = map.getBounds();\n if (!b) return [\n [0, 0],\n [0, 0],\n ];\n const sw = b.getSouthWest();\n const ne = b.getNorthEast();\n return [\n [sw.lng(), sw.lat()],\n [ne.lng(), ne.lat()],\n ];\n },\n addMarker: (id, coords, anchor) => {\n const element = document.createElement(\"div\");\n element.dataset.gdsPart = \"map-marker\";\n element.dataset.gdsState = \"idle\";\n element.style.cursor = \"pointer\";\n // Google AdvancedMarker anchors the *bottom-center* of `content` to\n // the coord by default. For \"center\" anchor, shift content down so\n // the visual midpoint lands on the coord.\n if (anchor === \"center\") {\n element.style.transform = \"translateY(50%)\";\n }\n\n element.addEventListener(\"mouseenter\", () => callbacks.onMarkerHover(id));\n element.addEventListener(\"mouseleave\", () => callbacks.onMarkerHover(null));\n element.addEventListener(\"click\", (e) => {\n callbacks.onMarkerClick(id, handle.coords, e);\n });\n\n const marker = new google.maps.marker.AdvancedMarkerElement({\n map,\n position: { lat: coords[1], lng: coords[0] },\n content: element,\n });\n\n const handle: MarkerHandle = {\n element,\n coords,\n setHovered: (hovered) => {\n element.dataset.gdsState = hovered ? \"hovered\" : \"idle\";\n marker.zIndex = hovered ? 10 : 1;\n },\n setPosition: (next) => {\n handle.coords = next;\n marker.position = { lat: next[1], lng: next[0] };\n },\n remove: () => {\n marker.map = null;\n markers.delete(id);\n },\n };\n\n markers.set(id, { marker, handle });\n return handle;\n },\n destroy: () => {\n markers.forEach(({ marker }) => {\n marker.map = null;\n });\n markers.clear();\n // Google Map has no explicit destroy(); GC handles it once the\n // container DOM node is removed.\n },\n instance: map,\n };\n\n return adapter;\n};\n"]}
|
|
1
|
+
{"version":3,"sources":["../../components/ui/map/adapters/google.ts"],"names":["GOOGLE_LIGHT_STYLES","GOOGLE_DARK_STYLES","stylesFor","appearance","createGoogleAdapter","container","opts","callbacks","LoaderCtor","mod","err","loader","google","isSat","showZoom","googleCorner","map","b","resolve","markers","coords","zoom","sw","ne","enabled","fopts","list","fbopts","lng","lat","c","id","anchor","element","e","handle","marker","hovered","next"],"mappings":"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","file":"google.mjs","sourcesContent":["import type {\n AdapterFactory,\n AdapterInstance,\n Coords,\n MarkerHandle,\n} from \"../types\";\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\ntype AnyStyles = any[];\n\nconst GOOGLE_LIGHT_STYLES: AnyStyles = [\n // Neutral light preset — POIs hidden, transit muted.\n { featureType: \"poi\", stylers: [{ visibility: \"off\" }] },\n { featureType: \"transit\", stylers: [{ visibility: \"simplified\" }] },\n];\n\nconst GOOGLE_DARK_STYLES: AnyStyles = [\n { elementType: \"geometry\", stylers: [{ color: \"#1a1a1a\" }] },\n { elementType: \"labels.text.stroke\", stylers: [{ color: \"#1a1a1a\" }] },\n { elementType: \"labels.text.fill\", stylers: [{ color: \"#9ca3af\" }] },\n { featureType: \"poi\", stylers: [{ visibility: \"off\" }] },\n {\n featureType: \"road\",\n elementType: \"geometry\",\n stylers: [{ color: \"#262626\" }],\n },\n {\n featureType: \"road\",\n elementType: \"labels.text.fill\",\n stylers: [{ color: \"#9ca3af\" }],\n },\n {\n featureType: \"water\",\n elementType: \"geometry\",\n stylers: [{ color: \"#0f172a\" }],\n },\n {\n featureType: \"transit\",\n stylers: [{ visibility: \"simplified\" }, { color: \"#3a3a3a\" }],\n },\n];\n\nconst stylesFor = (appearance: \"light\" | \"dark\"): AnyStyles =>\n appearance === \"dark\" ? GOOGLE_DARK_STYLES : GOOGLE_LIGHT_STYLES;\n\nexport const createGoogleAdapter: AdapterFactory = async (\n container,\n opts,\n callbacks\n) => {\n if (!opts.apiKey) {\n callbacks.onError({\n code: \"api-key-missing\",\n message:\n '@gradeui/ui Map: provider=\"google\" requires an `apiKey` prop.',\n });\n throw new Error(\"google apiKey missing\");\n }\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n let LoaderCtor: any;\n try {\n const mod = await import(\"@googlemaps/js-api-loader\");\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n LoaderCtor = (mod as any).Loader ?? (mod as any).default?.Loader;\n } catch (err) {\n callbacks.onError({\n code: \"sdk-missing\",\n message:\n '@gradeui/ui Map: `@googlemaps/js-api-loader` is not installed. Run `pnpm add @googlemaps/js-api-loader` to use provider=\"google\".',\n cause: err,\n });\n throw err;\n }\n\n const loader = new LoaderCtor({\n apiKey: opts.apiKey,\n version: \"weekly\",\n libraries: [\"maps\", \"marker\"],\n });\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n let google: any;\n try {\n google = await loader.load();\n } catch (err) {\n callbacks.onError({\n code: \"provider-init-failed\",\n message: \"@gradeui/ui Map: Google Maps loader failed.\",\n cause: err,\n });\n throw err;\n }\n\n const isSat = opts.appearance === \"satellite\";\n\n // Tools — shared vocabulary (types.ts). Google's default UI is loud\n // (map-type switcher, street view, fullscreen), so the Grade contract\n // disables ALL of it and adds back only the zoom control, docked via\n // ControlPosition. This also makes Google match the other providers'\n // quiet chrome instead of its own kitchen sink.\n const showZoom =\n opts.tools === \"zoom\" || (opts.tools === \"auto\" && opts.interactive);\n const googleCorner: Record<string, google.maps.ControlPosition> = {\n \"top-left\": google.maps.ControlPosition.LEFT_TOP,\n \"top-right\": google.maps.ControlPosition.RIGHT_TOP,\n \"bottom-left\": google.maps.ControlPosition.LEFT_BOTTOM,\n \"bottom-right\": google.maps.ControlPosition.RIGHT_BOTTOM,\n };\n\n const map = new google.maps.Map(container, {\n center: { lat: opts.center[1], lng: opts.center[0] },\n zoom: opts.zoom,\n mapTypeId: isSat\n ? google.maps.MapTypeId.HYBRID\n : google.maps.MapTypeId.ROADMAP,\n mapId: opts.mapId,\n styles: isSat\n ? undefined\n : stylesFor(opts.appearance === \"dark\" ? \"dark\" : \"light\"),\n disableDefaultUI: true,\n zoomControl: showZoom,\n zoomControlOptions: {\n position: googleCorner[opts.toolsPosition],\n },\n gestureHandling: opts.interactive ? \"auto\" : \"none\",\n keyboardShortcuts: opts.interactive,\n });\n\n if (opts.bounds) {\n const b = new google.maps.LatLngBounds(\n { lat: opts.bounds[0][1], lng: opts.bounds[0][0] },\n { lat: opts.bounds[1][1], lng: opts.bounds[1][0] }\n );\n map.fitBounds(b);\n }\n\n await new Promise<void>((resolve) => {\n google.maps.event.addListenerOnce(map, \"idle\", () => resolve());\n });\n callbacks.onLoad();\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const markers = new globalThis.Map<string, { marker: any; handle: MarkerHandle }>();\n\n const adapter: AdapterInstance = {\n setCenter: (coords) =>\n map.setCenter({ lat: coords[1], lng: coords[0] }),\n setZoom: (zoom) => map.setZoom(zoom),\n setBounds: (sw, ne) => {\n const b = new google.maps.LatLngBounds(\n { lat: sw[1], lng: sw[0] },\n { lat: ne[1], lng: ne[0] }\n );\n map.fitBounds(b);\n },\n setAppearance: (appearance) => {\n if (appearance === \"satellite\") {\n map.setMapTypeId(google.maps.MapTypeId.HYBRID);\n map.setOptions({ styles: undefined });\n } else {\n map.setMapTypeId(google.maps.MapTypeId.ROADMAP);\n map.setOptions({ styles: stylesFor(appearance) });\n }\n },\n setInteractive: (enabled) => {\n // disableDefaultUI stays true permanently (Grade owns the chrome);\n // only the zoom control follows interactivity under tools=\"auto\".\n map.setOptions({\n zoomControl:\n opts.tools === \"zoom\" || (opts.tools === \"auto\" && enabled),\n gestureHandling: enabled ? \"auto\" : \"none\",\n keyboardShortcuts: enabled,\n });\n },\n flyTo: (coords, fopts) => {\n map.panTo({ lat: coords[1], lng: coords[0] });\n if (fopts?.zoom != null) map.setZoom(fopts.zoom);\n },\n panTo: (coords) => map.panTo({ lat: coords[1], lng: coords[0] }),\n fitBounds: (list, fbopts) => {\n if (list.length === 0) return;\n const b = new google.maps.LatLngBounds();\n for (const [lng, lat] of list) b.extend({ lat, lng });\n map.fitBounds(b, fbopts?.paddingPx ?? 40);\n },\n getCenter: () => {\n const c = map.getCenter();\n return c ? [c.lng(), c.lat()] : [0, 0];\n },\n getZoom: () => map.getZoom() ?? 0,\n getBounds: () => {\n const b = map.getBounds();\n if (!b) return [\n [0, 0],\n [0, 0],\n ];\n const sw = b.getSouthWest();\n const ne = b.getNorthEast();\n return [\n [sw.lng(), sw.lat()],\n [ne.lng(), ne.lat()],\n ];\n },\n addMarker: (id, coords, anchor) => {\n const element = document.createElement(\"div\");\n element.dataset.gdsPart = \"map-marker\";\n element.dataset.gdsState = \"idle\";\n element.style.cursor = \"pointer\";\n // Google AdvancedMarker anchors the *bottom-center* of `content` to\n // the coord by default. For \"center\" anchor, shift content down so\n // the visual midpoint lands on the coord.\n if (anchor === \"center\") {\n element.style.transform = \"translateY(50%)\";\n }\n\n element.addEventListener(\"mouseenter\", () => callbacks.onMarkerHover(id));\n element.addEventListener(\"mouseleave\", () => callbacks.onMarkerHover(null));\n element.addEventListener(\"click\", (e) => {\n callbacks.onMarkerClick(id, handle.coords, e);\n });\n\n const marker = new google.maps.marker.AdvancedMarkerElement({\n map,\n position: { lat: coords[1], lng: coords[0] },\n content: element,\n });\n\n const handle: MarkerHandle = {\n element,\n coords,\n setHovered: (hovered) => {\n element.dataset.gdsState = hovered ? \"hovered\" : \"idle\";\n marker.zIndex = hovered ? 10 : 1;\n },\n setPosition: (next) => {\n handle.coords = next;\n marker.position = { lat: next[1], lng: next[0] };\n },\n remove: () => {\n marker.map = null;\n markers.delete(id);\n },\n };\n\n markers.set(id, { marker, handle });\n return handle;\n },\n destroy: () => {\n markers.forEach(({ marker }) => {\n marker.map = null;\n });\n markers.clear();\n // Google Map has no explicit destroy(); GC handles it once the\n // container DOM node is removed.\n },\n instance: map,\n };\n\n return adapter;\n};\n"]}
|
package/dist/map/leaflet.d.mts
CHANGED
package/dist/map/leaflet.d.ts
CHANGED
package/dist/map/leaflet.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
"use client";
|
|
2
|
-
'use strict';var
|
|
3
|
-
exports.createLeafletAdapter=
|
|
2
|
+
'use strict';var E="https://unpkg.com/leaflet@1.9.4/dist/leaflet.css",y="gds-leaflet-css";function z(){if(typeof document>"u"||globalThis.__gradeLeafletCssBundled||document.getElementById(y))return;let s=document.createElement("link");s.id=y,s.rel="stylesheet",s.href=E,document.head.appendChild(s);}var b={light:"rastertiles/voyager",dark:"rastertiles/dark_all",satellite:"rastertiles/voyager"},S=s=>`https://{s}.basemaps.cartocdn.com/${s}/{z}/{x}/{y}{r}.png`,Z="\xA9 OpenStreetMap contributors \xA9 CARTO",M=async(s,a,c)=>{z();let i;try{i=await import('leaflet'),i.default&&(i=i.default);}catch(e){throw c.onError({code:"sdk-missing",message:"@gradeui/ui Map: `leaflet` is not installed. Run `pnpm add leaflet` to use the worker-free Leaflet adapter.",cause:e}),e}let n=e=>[e[1],e[0]],k=a.tools==="zoom"||a.tools==="auto"&&a.interactive,L={"top-left":"topleft","top-right":"topright","bottom-left":"bottomleft","bottom-right":"bottomright"},t=i.map(s,{center:n(a.center),zoom:a.zoom,zoomControl:false,attributionControl:true,dragging:a.interactive,scrollWheelZoom:a.interactive,doubleClickZoom:a.interactive,boxZoom:a.interactive,keyboard:a.interactive,touchZoom:a.interactive});k&&i.control.zoom({position:L[a.toolsPosition]??"topleft"}).addTo(t);let h=e=>{let o=i.tileLayer(S(b[e]??b.light),{maxZoom:20,subdomains:"abcd",detectRetina:true,attribution:Z,crossOrigin:true});return o.on("tileerror",()=>c.onError({code:"tile-load-failed",message:"map tile failed to load (is the tile host allowed by CSP?)"})),o.addTo(t),o},p=h(a.appearance),C=e=>{p&&t.removeLayer(p),p=h(e);};a.bounds&&t.fitBounds([n(a.bounds[0]),n(a.bounds[1])],{animate:false}),c.onLoad();let v=typeof ResizeObserver<"u"?new ResizeObserver(()=>t.invalidateSize(false)):null;v?.observe(s),requestAnimationFrame(()=>t.invalidateSize(false)),window.setTimeout(()=>t.invalidateSize(false),200),window.setTimeout(()=>t.invalidateSize(false),600);let u=new globalThis.Map;return {setCenter:e=>t.panTo(n(e),{animate:false}),setZoom:e=>t.setZoom(e),setBounds:(e,o)=>t.fitBounds([n(e),n(o)],{animate:false}),setAppearance:e=>C(e),setInteractive:e=>{let o=["dragging","scrollWheelZoom","doubleClickZoom","boxZoom","keyboard","touchZoom"];for(let l of o){let r=t[l];r&&(e?r.enable():r.disable());}},flyTo:(e,o)=>t.flyTo(n(e),o?.zoom??t.getZoom(),{duration:(o?.durationMs??800)/1e3}),panTo:(e,o)=>t.panTo(n(e),{duration:(o?.durationMs??600)/1e3}),fitBounds:(e,o)=>{if(e.length===0)return;let l=o?.paddingPx??40;t.fitBounds(e.map(n),{padding:[l,l],duration:(o?.durationMs??800)/1e3});},getCenter:()=>{let e=t.getCenter();return [e.lng,e.lat]},getZoom:()=>t.getZoom(),getBounds:()=>{let e=t.getBounds(),o=e.getSouthWest(),l=e.getNorthEast();return [[o.lng,o.lat],[l.lng,l.lat]]},addMarker:(e,o,l)=>{let r=document.createElement("div");r.dataset.gdsPart="map-marker",r.dataset.gdsState="idle",r.style.position="absolute",r.style.cursor="pointer",r.style.transform=l==="center"?"translate(-50%, -50%)":"translate(-50%, -100%)",r.addEventListener("mouseenter",()=>c.onMarkerHover(e)),r.addEventListener("mouseleave",()=>c.onMarkerHover(null)),r.addEventListener("click",d=>c.onMarkerClick(e,g.coords,d));let T=i.divIcon({className:"gds-leaflet-marker",html:"",iconSize:[0,0],iconAnchor:[0,0]}),f=i.marker(n(o),{icon:T,interactive:true,keyboard:false}).addTo(t),m=f.getElement();m&&(m.style.pointerEvents="auto",m.appendChild(r));let g={element:r,coords:o,setHovered:d=>{r.dataset.gdsState=d?"hovered":"idle",m&&(m.style.zIndex=d?"1000":"");},setPosition:d=>{g.coords=d,f.setLatLng(n(d));},remove:()=>{t.removeLayer(f),u.delete(e);}};return u.set(e,{marker:f,handle:g}),g},destroy:()=>{v?.disconnect(),u.forEach(({marker:e})=>t.removeLayer(e)),u.clear(),t.remove();},instance:t}};
|
|
3
|
+
exports.createLeafletAdapter=M;//# sourceMappingURL=leaflet.js.map
|
|
4
4
|
//# sourceMappingURL=leaflet.js.map
|
package/dist/map/leaflet.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../components/ui/map/adapters/leaflet.ts"],"names":["LEAFLET_CSS_HREF","CSS_LINK_ID","ensureLeafletCss","link","CARTO_STYLE","cartoUrl","style","CARTO_ATTRIBUTION","createLeafletAdapter","container","opts","callbacks","L","err","toLatLng","c","map","addTiles","appearance","layer","tiles","applyAppearance","resizeObserver","markers","z","sw","ne","a","enabled","handlers","k","ctl","o","list","pad","b","id","coords","anchor","element","e","handle","icon","marker","iconEl","hovered","next"],"mappings":"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","file":"leaflet.js","sourcesContent":["import type {\n AdapterFactory,\n AdapterInstance,\n Coords,\n MarkerHandle,\n} from \"../types\";\n\n/**\n * Leaflet adapter — a WORKER-FREE raster-tile renderer.\n *\n * Why this exists alongside the maplibre adapter: maplibre-gl does all of its\n * rendering in a Web Worker (spawned from a `blob:` URL). Inside a strictly\n * sandboxed MCP App panel the default CSP is `default-src 'none'`, workers\n * fall back to that, and the MCP Apps CSP vocabulary has no `worker-src`\n * knob — so maplibre simply cannot run there. Leaflet paints raster tiles as\n * plain `<img>` elements on the main thread (no worker), so it runs fine; the\n * only thing it needs is network access to the tile host, which IS grantable\n * via the resource's `connectDomains` / `resourceDomains`.\n *\n * Keyless: OSM raster tiles, no API key, no referrer lock. The MCP View\n * forces this adapter (see the provider override in map.tsx); Studio and the\n * embed keep maplibre.\n */\n\nconst LEAFLET_CSS_HREF = \"https://unpkg.com/leaflet@1.9.4/dist/leaflet.css\";\nconst CSS_LINK_ID = \"gds-leaflet-css\";\n\nfunction ensureLeafletCss() {\n if (typeof document === \"undefined\") return;\n // The MCP View bundles Leaflet's CSS inline and sets this flag, so we skip\n // the network <link> there (it would be CSP-blocked anyway).\n if ((globalThis as { __gradeLeafletCssBundled?: boolean }).__gradeLeafletCssBundled)\n return;\n if (document.getElementById(CSS_LINK_ID)) return;\n const link = document.createElement(\"link\");\n link.id = CSS_LINK_ID;\n link.rel = \"stylesheet\";\n link.href = LEAFLET_CSS_HREF;\n document.head.appendChild(link);\n}\n\n// Keyless CARTO raster basemaps (built on OSM data). Much closer to Google\n// Maps' default look than raw OSM: `voyager` is the light, road-forward style;\n// `dark_all` is a real dark style (no CSS-invert hack). Served from the\n// a–d.basemaps.cartocdn.com CDN; those hosts are declared in the MCP View's\n// resource CSP. Free with attribution.\nconst CARTO_STYLE: Record<\"light\" | \"dark\" | \"satellite\", string> = {\n light: \"rastertiles/voyager\",\n dark: \"rastertiles/dark_all\",\n satellite: \"rastertiles/voyager\",\n};\nconst cartoUrl = (style: string) =>\n `https://{s}.basemaps.cartocdn.com/${style}/{z}/{x}/{y}{r}.png`;\nconst CARTO_ATTRIBUTION = \"© OpenStreetMap contributors © CARTO\";\n\nexport const createLeafletAdapter: AdapterFactory = async (\n container,\n opts,\n callbacks\n) => {\n ensureLeafletCss();\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n let L: any;\n try {\n // leaflet is resolved + bundled by the consumer (the MCP preview View);\n // it's intentionally NOT a dependency of @gradeui/ui, so the dts build\n // can't resolve its types here. The value is `any`, so suppress the\n // module-resolution error rather than pull leaflet into this package.\n // @ts-ignore -- optional peer, resolved by the bundling consumer\n L = await import(\"leaflet\");\n if (L.default) L = L.default;\n } catch (err) {\n callbacks.onError({\n code: \"sdk-missing\",\n message:\n '@gradeui/ui Map: `leaflet` is not installed. Run `pnpm add leaflet` to use the worker-free Leaflet adapter.',\n cause: err,\n });\n throw err;\n }\n\n // Grade coords are [lng, lat]; Leaflet wants [lat, lng].\n const toLatLng = (c: Coords): [number, number] => [c[1], c[0]];\n\n const map = L.map(container, {\n center: toLatLng(opts.center),\n zoom: opts.zoom,\n zoomControl: opts.interactive,\n attributionControl: true,\n dragging: opts.interactive,\n scrollWheelZoom: opts.interactive,\n doubleClickZoom: opts.interactive,\n boxZoom: opts.interactive,\n keyboard: opts.interactive,\n touchZoom: opts.interactive,\n });\n\n // Appearance is a different tile STYLE (not a CSS filter), so switching it\n // swaps the layer. `{r}` is Leaflet's retina suffix; `detectRetina` fills it.\n const addTiles = (appearance: \"light\" | \"dark\" | \"satellite\") => {\n const layer = L.tileLayer(cartoUrl(CARTO_STYLE[appearance] ?? CARTO_STYLE.light), {\n maxZoom: 20,\n subdomains: \"abcd\",\n detectRetina: true,\n attribution: CARTO_ATTRIBUTION,\n crossOrigin: true,\n });\n layer.on(\"tileerror\", () =>\n callbacks.onError({\n code: \"tile-load-failed\",\n message: \"map tile failed to load (is the tile host allowed by CSP?)\",\n })\n );\n layer.addTo(map);\n return layer;\n };\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n let tiles: any = addTiles(opts.appearance);\n const applyAppearance = (appearance: \"light\" | \"dark\" | \"satellite\") => {\n if (tiles) map.removeLayer(tiles);\n tiles = addTiles(appearance);\n };\n\n if (opts.bounds) {\n map.fitBounds([toLatLng(opts.bounds[0]), toLatLng(opts.bounds[1])], {\n animate: false,\n });\n }\n\n // Leaflet initialises synchronously — signal ready immediately.\n callbacks.onLoad();\n\n // CRITICAL for sandboxed/absolute-inset containers (the MCP preview panel):\n // the iframe is frequently sized AFTER the map mounts, so Leaflet's initial\n // measurement is 0×0 and it renders NOTHING — no tiles, no markers. Re-measure\n // on the next frames and whenever the container resizes.\n const resizeObserver =\n typeof ResizeObserver !== \"undefined\"\n ? new ResizeObserver(() => map.invalidateSize(false))\n : null;\n resizeObserver?.observe(container);\n requestAnimationFrame(() => map.invalidateSize(false));\n window.setTimeout(() => map.invalidateSize(false), 200);\n window.setTimeout(() => map.invalidateSize(false), 600);\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const markers = new globalThis.Map<string, { marker: any; handle: MarkerHandle }>();\n\n const adapter: AdapterInstance = {\n setCenter: (c) => map.panTo(toLatLng(c), { animate: false }),\n setZoom: (z) => map.setZoom(z),\n setBounds: (sw, ne) =>\n map.fitBounds([toLatLng(sw), toLatLng(ne)], { animate: false }),\n setAppearance: (a) => applyAppearance(a),\n setInteractive: (enabled) => {\n const handlers = [\n \"dragging\",\n \"scrollWheelZoom\",\n \"doubleClickZoom\",\n \"boxZoom\",\n \"keyboard\",\n \"touchZoom\",\n ] as const;\n for (const k of handlers) {\n const ctl = map[k];\n if (ctl) (enabled ? ctl.enable() : ctl.disable());\n }\n },\n flyTo: (c, o) =>\n map.flyTo(toLatLng(c), o?.zoom ?? map.getZoom(), {\n duration: (o?.durationMs ?? 800) / 1000,\n }),\n panTo: (c, o) =>\n map.panTo(toLatLng(c), { duration: (o?.durationMs ?? 600) / 1000 }),\n fitBounds: (list, o) => {\n if (list.length === 0) return;\n const pad = o?.paddingPx ?? 40;\n map.fitBounds(list.map(toLatLng), {\n padding: [pad, pad],\n duration: (o?.durationMs ?? 800) / 1000,\n });\n },\n getCenter: () => {\n const c = map.getCenter();\n return [c.lng, c.lat];\n },\n getZoom: () => map.getZoom(),\n getBounds: () => {\n const b = map.getBounds();\n const sw = b.getSouthWest();\n const ne = b.getNorthEast();\n return [\n [sw.lng, sw.lat],\n [ne.lng, ne.lat],\n ];\n },\n addMarker: (id, coords, anchor) => {\n // Live DOM marker: <MapMarker> portals its React children into\n // `element`. Leaflet positions the icon container's top-left at the\n // coord (iconAnchor [0,0]); our absolutely-positioned element then\n // offsets via transform so its bottom-centre (or centre) sits on the\n // point — matching the maplibre adapter's anchor semantics.\n const element = document.createElement(\"div\");\n element.dataset.gdsPart = \"map-marker\";\n element.dataset.gdsState = \"idle\";\n element.style.position = \"absolute\";\n element.style.cursor = \"pointer\";\n element.style.transform =\n anchor === \"center\"\n ? \"translate(-50%, -50%)\"\n : \"translate(-50%, -100%)\";\n\n element.addEventListener(\"mouseenter\", () => callbacks.onMarkerHover(id));\n element.addEventListener(\"mouseleave\", () => callbacks.onMarkerHover(null));\n element.addEventListener(\"click\", (e) =>\n callbacks.onMarkerClick(id, handle.coords, e)\n );\n\n const icon = L.divIcon({\n className: \"gds-leaflet-marker\",\n html: \"\",\n iconSize: [0, 0],\n iconAnchor: [0, 0],\n });\n const marker = L.marker(toLatLng(coords), {\n icon,\n interactive: true,\n keyboard: false,\n }).addTo(map);\n\n const iconEl: HTMLElement | undefined = marker.getElement();\n if (iconEl) {\n iconEl.style.pointerEvents = \"auto\";\n iconEl.appendChild(element);\n }\n\n const handle: MarkerHandle = {\n element,\n coords,\n setHovered: (hovered) => {\n element.dataset.gdsState = hovered ? \"hovered\" : \"idle\";\n if (iconEl) iconEl.style.zIndex = hovered ? \"1000\" : \"\";\n },\n setPosition: (next) => {\n handle.coords = next;\n marker.setLatLng(toLatLng(next));\n },\n remove: () => {\n map.removeLayer(marker);\n markers.delete(id);\n },\n };\n\n markers.set(id, { marker, handle });\n return handle;\n },\n destroy: () => {\n resizeObserver?.disconnect();\n markers.forEach(({ marker }) => map.removeLayer(marker));\n markers.clear();\n map.remove();\n },\n instance: map,\n };\n\n return adapter;\n};\n"]}
|
|
1
|
+
{"version":3,"sources":["../../components/ui/map/adapters/leaflet.ts"],"names":["LEAFLET_CSS_HREF","CSS_LINK_ID","ensureLeafletCss","link","CARTO_STYLE","cartoUrl","style","CARTO_ATTRIBUTION","createLeafletAdapter","container","opts","callbacks","L","err","toLatLng","c","showZoom","leafletCorner","map","addTiles","appearance","layer","tiles","applyAppearance","resizeObserver","markers","z","sw","ne","a","enabled","handlers","k","ctl","list","pad","b","id","coords","anchor","element","e","handle","icon","marker","iconEl","hovered","next"],"mappings":"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","file":"leaflet.js","sourcesContent":["import type {\n AdapterFactory,\n AdapterInstance,\n Coords,\n MarkerHandle,\n} from \"../types\";\n\n/**\n * Leaflet adapter — a WORKER-FREE raster-tile renderer.\n *\n * Why this exists alongside the maplibre adapter: maplibre-gl does all of its\n * rendering in a Web Worker (spawned from a `blob:` URL). Inside a strictly\n * sandboxed MCP App panel the default CSP is `default-src 'none'`, workers\n * fall back to that, and the MCP Apps CSP vocabulary has no `worker-src`\n * knob — so maplibre simply cannot run there. Leaflet paints raster tiles as\n * plain `<img>` elements on the main thread (no worker), so it runs fine; the\n * only thing it needs is network access to the tile host, which IS grantable\n * via the resource's `connectDomains` / `resourceDomains`.\n *\n * Keyless: OSM raster tiles, no API key, no referrer lock. The MCP View\n * forces this adapter (see the provider override in map.tsx); Studio and the\n * embed keep maplibre.\n */\n\nconst LEAFLET_CSS_HREF = \"https://unpkg.com/leaflet@1.9.4/dist/leaflet.css\";\nconst CSS_LINK_ID = \"gds-leaflet-css\";\n\nfunction ensureLeafletCss() {\n if (typeof document === \"undefined\") return;\n // The MCP View bundles Leaflet's CSS inline and sets this flag, so we skip\n // the network <link> there (it would be CSP-blocked anyway).\n if ((globalThis as { __gradeLeafletCssBundled?: boolean }).__gradeLeafletCssBundled)\n return;\n if (document.getElementById(CSS_LINK_ID)) return;\n const link = document.createElement(\"link\");\n link.id = CSS_LINK_ID;\n link.rel = \"stylesheet\";\n link.href = LEAFLET_CSS_HREF;\n document.head.appendChild(link);\n}\n\n// Keyless CARTO raster basemaps (built on OSM data). Much closer to Google\n// Maps' default look than raw OSM: `voyager` is the light, road-forward style;\n// `dark_all` is a real dark style (no CSS-invert hack). Served from the\n// a–d.basemaps.cartocdn.com CDN; those hosts are declared in the MCP View's\n// resource CSP. Free with attribution.\nconst CARTO_STYLE: Record<\"light\" | \"dark\" | \"satellite\", string> = {\n light: \"rastertiles/voyager\",\n dark: \"rastertiles/dark_all\",\n satellite: \"rastertiles/voyager\",\n};\nconst cartoUrl = (style: string) =>\n `https://{s}.basemaps.cartocdn.com/${style}/{z}/{x}/{y}{r}.png`;\nconst CARTO_ATTRIBUTION = \"© OpenStreetMap contributors © CARTO\";\n\nexport const createLeafletAdapter: AdapterFactory = async (\n container,\n opts,\n callbacks\n) => {\n ensureLeafletCss();\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n let L: any;\n try {\n // leaflet is resolved + bundled by the consumer (the MCP preview View);\n // it's intentionally NOT a dependency of @gradeui/ui, so the dts build\n // can't resolve its types here. The value is `any`, so suppress the\n // module-resolution error rather than pull leaflet into this package.\n // @ts-ignore -- optional peer, resolved by the bundling consumer\n L = await import(\"leaflet\");\n if (L.default) L = L.default;\n } catch (err) {\n callbacks.onError({\n code: \"sdk-missing\",\n message:\n '@gradeui/ui Map: `leaflet` is not installed. Run `pnpm add leaflet` to use the worker-free Leaflet adapter.',\n cause: err,\n });\n throw err;\n }\n\n // Grade coords are [lng, lat]; Leaflet wants [lat, lng].\n const toLatLng = (c: Coords): [number, number] => [c[1], c[0]];\n\n // Tools — one vocabulary across providers (see MapTools/MapToolsPosition\n // in types.ts). \"auto\" follows `interactive`; the position maps to\n // Leaflet's squashed corner names. Zoom is added as an explicit control\n // (zoomControl: false at init) so it can dock to any corner.\n const showZoom =\n opts.tools === \"zoom\" || (opts.tools === \"auto\" && opts.interactive);\n const leafletCorner: Record<string, string> = {\n \"top-left\": \"topleft\",\n \"top-right\": \"topright\",\n \"bottom-left\": \"bottomleft\",\n \"bottom-right\": \"bottomright\",\n };\n\n const map = L.map(container, {\n center: toLatLng(opts.center),\n zoom: opts.zoom,\n zoomControl: false,\n attributionControl: true,\n dragging: opts.interactive,\n scrollWheelZoom: opts.interactive,\n doubleClickZoom: opts.interactive,\n boxZoom: opts.interactive,\n keyboard: opts.interactive,\n touchZoom: opts.interactive,\n });\n\n if (showZoom) {\n L.control\n .zoom({ position: leafletCorner[opts.toolsPosition] ?? \"topleft\" })\n .addTo(map);\n }\n\n // Appearance is a different tile STYLE (not a CSS filter), so switching it\n // swaps the layer. `{r}` is Leaflet's retina suffix; `detectRetina` fills it.\n const addTiles = (appearance: \"light\" | \"dark\" | \"satellite\") => {\n const layer = L.tileLayer(cartoUrl(CARTO_STYLE[appearance] ?? CARTO_STYLE.light), {\n maxZoom: 20,\n subdomains: \"abcd\",\n detectRetina: true,\n attribution: CARTO_ATTRIBUTION,\n crossOrigin: true,\n });\n layer.on(\"tileerror\", () =>\n callbacks.onError({\n code: \"tile-load-failed\",\n message: \"map tile failed to load (is the tile host allowed by CSP?)\",\n })\n );\n layer.addTo(map);\n return layer;\n };\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n let tiles: any = addTiles(opts.appearance);\n const applyAppearance = (appearance: \"light\" | \"dark\" | \"satellite\") => {\n if (tiles) map.removeLayer(tiles);\n tiles = addTiles(appearance);\n };\n\n if (opts.bounds) {\n map.fitBounds([toLatLng(opts.bounds[0]), toLatLng(opts.bounds[1])], {\n animate: false,\n });\n }\n\n // Leaflet initialises synchronously — signal ready immediately.\n callbacks.onLoad();\n\n // CRITICAL for sandboxed/absolute-inset containers (the MCP preview panel):\n // the iframe is frequently sized AFTER the map mounts, so Leaflet's initial\n // measurement is 0×0 and it renders NOTHING — no tiles, no markers. Re-measure\n // on the next frames and whenever the container resizes.\n const resizeObserver =\n typeof ResizeObserver !== \"undefined\"\n ? new ResizeObserver(() => map.invalidateSize(false))\n : null;\n resizeObserver?.observe(container);\n requestAnimationFrame(() => map.invalidateSize(false));\n window.setTimeout(() => map.invalidateSize(false), 200);\n window.setTimeout(() => map.invalidateSize(false), 600);\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const markers = new globalThis.Map<string, { marker: any; handle: MarkerHandle }>();\n\n const adapter: AdapterInstance = {\n setCenter: (c) => map.panTo(toLatLng(c), { animate: false }),\n setZoom: (z) => map.setZoom(z),\n setBounds: (sw, ne) =>\n map.fitBounds([toLatLng(sw), toLatLng(ne)], { animate: false }),\n setAppearance: (a) => applyAppearance(a),\n setInteractive: (enabled) => {\n const handlers = [\n \"dragging\",\n \"scrollWheelZoom\",\n \"doubleClickZoom\",\n \"boxZoom\",\n \"keyboard\",\n \"touchZoom\",\n ] as const;\n for (const k of handlers) {\n const ctl = map[k];\n if (ctl) (enabled ? ctl.enable() : ctl.disable());\n }\n },\n flyTo: (c, o) =>\n map.flyTo(toLatLng(c), o?.zoom ?? map.getZoom(), {\n duration: (o?.durationMs ?? 800) / 1000,\n }),\n panTo: (c, o) =>\n map.panTo(toLatLng(c), { duration: (o?.durationMs ?? 600) / 1000 }),\n fitBounds: (list, o) => {\n if (list.length === 0) return;\n const pad = o?.paddingPx ?? 40;\n map.fitBounds(list.map(toLatLng), {\n padding: [pad, pad],\n duration: (o?.durationMs ?? 800) / 1000,\n });\n },\n getCenter: () => {\n const c = map.getCenter();\n return [c.lng, c.lat];\n },\n getZoom: () => map.getZoom(),\n getBounds: () => {\n const b = map.getBounds();\n const sw = b.getSouthWest();\n const ne = b.getNorthEast();\n return [\n [sw.lng, sw.lat],\n [ne.lng, ne.lat],\n ];\n },\n addMarker: (id, coords, anchor) => {\n // Live DOM marker: <MapMarker> portals its React children into\n // `element`. Leaflet positions the icon container's top-left at the\n // coord (iconAnchor [0,0]); our absolutely-positioned element then\n // offsets via transform so its bottom-centre (or centre) sits on the\n // point — matching the maplibre adapter's anchor semantics.\n const element = document.createElement(\"div\");\n element.dataset.gdsPart = \"map-marker\";\n element.dataset.gdsState = \"idle\";\n element.style.position = \"absolute\";\n element.style.cursor = \"pointer\";\n element.style.transform =\n anchor === \"center\"\n ? \"translate(-50%, -50%)\"\n : \"translate(-50%, -100%)\";\n\n element.addEventListener(\"mouseenter\", () => callbacks.onMarkerHover(id));\n element.addEventListener(\"mouseleave\", () => callbacks.onMarkerHover(null));\n element.addEventListener(\"click\", (e) =>\n callbacks.onMarkerClick(id, handle.coords, e)\n );\n\n const icon = L.divIcon({\n className: \"gds-leaflet-marker\",\n html: \"\",\n iconSize: [0, 0],\n iconAnchor: [0, 0],\n });\n const marker = L.marker(toLatLng(coords), {\n icon,\n interactive: true,\n keyboard: false,\n }).addTo(map);\n\n const iconEl: HTMLElement | undefined = marker.getElement();\n if (iconEl) {\n iconEl.style.pointerEvents = \"auto\";\n iconEl.appendChild(element);\n }\n\n const handle: MarkerHandle = {\n element,\n coords,\n setHovered: (hovered) => {\n element.dataset.gdsState = hovered ? \"hovered\" : \"idle\";\n if (iconEl) iconEl.style.zIndex = hovered ? \"1000\" : \"\";\n },\n setPosition: (next) => {\n handle.coords = next;\n marker.setLatLng(toLatLng(next));\n },\n remove: () => {\n map.removeLayer(marker);\n markers.delete(id);\n },\n };\n\n markers.set(id, { marker, handle });\n return handle;\n },\n destroy: () => {\n resizeObserver?.disconnect();\n markers.forEach(({ marker }) => map.removeLayer(marker));\n markers.clear();\n map.remove();\n },\n instance: map,\n };\n\n return adapter;\n};\n"]}
|
package/dist/map/leaflet.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
"use client";
|
|
2
|
-
var
|
|
3
|
-
export{
|
|
2
|
+
var E="https://unpkg.com/leaflet@1.9.4/dist/leaflet.css",y="gds-leaflet-css";function z(){if(typeof document>"u"||globalThis.__gradeLeafletCssBundled||document.getElementById(y))return;let s=document.createElement("link");s.id=y,s.rel="stylesheet",s.href=E,document.head.appendChild(s);}var b={light:"rastertiles/voyager",dark:"rastertiles/dark_all",satellite:"rastertiles/voyager"},S=s=>`https://{s}.basemaps.cartocdn.com/${s}/{z}/{x}/{y}{r}.png`,Z="\xA9 OpenStreetMap contributors \xA9 CARTO",M=async(s,a,c)=>{z();let i;try{i=await import('leaflet'),i.default&&(i=i.default);}catch(e){throw c.onError({code:"sdk-missing",message:"@gradeui/ui Map: `leaflet` is not installed. Run `pnpm add leaflet` to use the worker-free Leaflet adapter.",cause:e}),e}let n=e=>[e[1],e[0]],k=a.tools==="zoom"||a.tools==="auto"&&a.interactive,L={"top-left":"topleft","top-right":"topright","bottom-left":"bottomleft","bottom-right":"bottomright"},t=i.map(s,{center:n(a.center),zoom:a.zoom,zoomControl:false,attributionControl:true,dragging:a.interactive,scrollWheelZoom:a.interactive,doubleClickZoom:a.interactive,boxZoom:a.interactive,keyboard:a.interactive,touchZoom:a.interactive});k&&i.control.zoom({position:L[a.toolsPosition]??"topleft"}).addTo(t);let h=e=>{let o=i.tileLayer(S(b[e]??b.light),{maxZoom:20,subdomains:"abcd",detectRetina:true,attribution:Z,crossOrigin:true});return o.on("tileerror",()=>c.onError({code:"tile-load-failed",message:"map tile failed to load (is the tile host allowed by CSP?)"})),o.addTo(t),o},p=h(a.appearance),C=e=>{p&&t.removeLayer(p),p=h(e);};a.bounds&&t.fitBounds([n(a.bounds[0]),n(a.bounds[1])],{animate:false}),c.onLoad();let v=typeof ResizeObserver<"u"?new ResizeObserver(()=>t.invalidateSize(false)):null;v?.observe(s),requestAnimationFrame(()=>t.invalidateSize(false)),window.setTimeout(()=>t.invalidateSize(false),200),window.setTimeout(()=>t.invalidateSize(false),600);let u=new globalThis.Map;return {setCenter:e=>t.panTo(n(e),{animate:false}),setZoom:e=>t.setZoom(e),setBounds:(e,o)=>t.fitBounds([n(e),n(o)],{animate:false}),setAppearance:e=>C(e),setInteractive:e=>{let o=["dragging","scrollWheelZoom","doubleClickZoom","boxZoom","keyboard","touchZoom"];for(let l of o){let r=t[l];r&&(e?r.enable():r.disable());}},flyTo:(e,o)=>t.flyTo(n(e),o?.zoom??t.getZoom(),{duration:(o?.durationMs??800)/1e3}),panTo:(e,o)=>t.panTo(n(e),{duration:(o?.durationMs??600)/1e3}),fitBounds:(e,o)=>{if(e.length===0)return;let l=o?.paddingPx??40;t.fitBounds(e.map(n),{padding:[l,l],duration:(o?.durationMs??800)/1e3});},getCenter:()=>{let e=t.getCenter();return [e.lng,e.lat]},getZoom:()=>t.getZoom(),getBounds:()=>{let e=t.getBounds(),o=e.getSouthWest(),l=e.getNorthEast();return [[o.lng,o.lat],[l.lng,l.lat]]},addMarker:(e,o,l)=>{let r=document.createElement("div");r.dataset.gdsPart="map-marker",r.dataset.gdsState="idle",r.style.position="absolute",r.style.cursor="pointer",r.style.transform=l==="center"?"translate(-50%, -50%)":"translate(-50%, -100%)",r.addEventListener("mouseenter",()=>c.onMarkerHover(e)),r.addEventListener("mouseleave",()=>c.onMarkerHover(null)),r.addEventListener("click",d=>c.onMarkerClick(e,g.coords,d));let T=i.divIcon({className:"gds-leaflet-marker",html:"",iconSize:[0,0],iconAnchor:[0,0]}),f=i.marker(n(o),{icon:T,interactive:true,keyboard:false}).addTo(t),m=f.getElement();m&&(m.style.pointerEvents="auto",m.appendChild(r));let g={element:r,coords:o,setHovered:d=>{r.dataset.gdsState=d?"hovered":"idle",m&&(m.style.zIndex=d?"1000":"");},setPosition:d=>{g.coords=d,f.setLatLng(n(d));},remove:()=>{t.removeLayer(f),u.delete(e);}};return u.set(e,{marker:f,handle:g}),g},destroy:()=>{v?.disconnect(),u.forEach(({marker:e})=>t.removeLayer(e)),u.clear(),t.remove();},instance:t}};
|
|
3
|
+
export{M as createLeafletAdapter};//# sourceMappingURL=leaflet.mjs.map
|
|
4
4
|
//# sourceMappingURL=leaflet.mjs.map
|
package/dist/map/leaflet.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../components/ui/map/adapters/leaflet.ts"],"names":["LEAFLET_CSS_HREF","CSS_LINK_ID","ensureLeafletCss","link","CARTO_STYLE","cartoUrl","style","CARTO_ATTRIBUTION","createLeafletAdapter","container","opts","callbacks","L","err","toLatLng","c","map","addTiles","appearance","layer","tiles","applyAppearance","resizeObserver","markers","z","sw","ne","a","enabled","handlers","k","ctl","o","list","pad","b","id","coords","anchor","element","e","handle","icon","marker","iconEl","hovered","next"],"mappings":"AAwBA,IAAMA,EAAmB,kDAAA,CACnBC,CAAAA,CAAc,iBAAA,CAEpB,SAASC,GAAmB,CAM1B,GALI,OAAO,QAAA,CAAa,KAGnB,UAAA,CAAsD,wBAAA,EAEvD,SAAS,cAAA,CAAeD,CAAW,EAAG,OAC1C,IAAME,CAAAA,CAAO,QAAA,CAAS,cAAc,MAAM,CAAA,CAC1CA,EAAK,EAAA,CAAKF,CAAAA,CACVE,EAAK,GAAA,CAAM,YAAA,CACXA,CAAAA,CAAK,IAAA,CAAOH,EACZ,QAAA,CAAS,IAAA,CAAK,YAAYG,CAAI,EAChC,CAOA,IAAMC,CAAAA,CAA8D,CAClE,KAAA,CAAO,sBACP,IAAA,CAAM,sBAAA,CACN,UAAW,qBACb,CAAA,CACMC,EAAYC,CAAAA,EAChB,CAAA,kCAAA,EAAqCA,CAAK,CAAA,mBAAA,CAAA,CACtCC,EAAoB,4CAAA,CAEbC,CAAAA,CAAuC,MAClDC,CAAAA,CACAC,CAAAA,CACAC,IACG,CACHT,CAAAA,EAAiB,CAGjB,IAAIU,EACJ,GAAI,CAMFA,EAAI,MAAM,OAAO,SAAS,CAAA,CACtBA,CAAAA,CAAE,OAAA,GAASA,CAAAA,CAAIA,EAAE,OAAA,EACvB,CAAA,MAASC,EAAK,CACZ,MAAAF,EAAU,OAAA,CAAQ,CAChB,IAAA,CAAM,aAAA,CACN,QACE,6GAAA,CACF,KAAA,CAAOE,CACT,CAAC,EACKA,CACR,CAGA,IAAMC,CAAAA,CAAYC,GAAgC,CAACA,CAAAA,CAAE,CAAC,CAAA,CAAGA,CAAAA,CAAE,CAAC,CAAC,CAAA,CAEvDC,CAAAA,CAAMJ,CAAAA,CAAE,IAAIH,CAAAA,CAAW,CAC3B,OAAQK,CAAAA,CAASJ,CAAAA,CAAK,MAAM,CAAA,CAC5B,IAAA,CAAMA,CAAAA,CAAK,IAAA,CACX,YAAaA,CAAAA,CAAK,WAAA,CAClB,mBAAoB,IAAA,CACpB,QAAA,CAAUA,EAAK,WAAA,CACf,eAAA,CAAiBA,CAAAA,CAAK,WAAA,CACtB,gBAAiBA,CAAAA,CAAK,WAAA,CACtB,QAASA,CAAAA,CAAK,WAAA,CACd,SAAUA,CAAAA,CAAK,WAAA,CACf,SAAA,CAAWA,CAAAA,CAAK,WAClB,CAAC,CAAA,CAIKO,EAAYC,CAAAA,EAA+C,CAC/D,IAAMC,CAAAA,CAAQP,CAAAA,CAAE,SAAA,CAAUP,CAAAA,CAASD,EAAYc,CAAU,CAAA,EAAKd,EAAY,KAAK,CAAA,CAAG,CAChF,OAAA,CAAS,EAAA,CACT,UAAA,CAAY,MAAA,CACZ,aAAc,IAAA,CACd,WAAA,CAAaG,EACb,WAAA,CAAa,IACf,CAAC,CAAA,CACD,OAAAY,CAAAA,CAAM,EAAA,CAAG,YAAa,IACpBR,CAAAA,CAAU,OAAA,CAAQ,CAChB,KAAM,kBAAA,CACN,OAAA,CAAS,4DACX,CAAC,CACH,CAAA,CACAQ,CAAAA,CAAM,MAAMH,CAAG,CAAA,CACRG,CACT,CAAA,CAGIC,CAAAA,CAAaH,CAAAA,CAASP,CAAAA,CAAK,UAAU,CAAA,CACnCW,CAAAA,CAAmBH,GAA+C,CAClEE,CAAAA,EAAOJ,EAAI,WAAA,CAAYI,CAAK,CAAA,CAChCA,CAAAA,CAAQH,EAASC,CAAU,EAC7B,EAEIR,CAAAA,CAAK,MAAA,EACPM,EAAI,SAAA,CAAU,CAACF,CAAAA,CAASJ,CAAAA,CAAK,OAAO,CAAC,CAAC,EAAGI,CAAAA,CAASJ,CAAAA,CAAK,OAAO,CAAC,CAAC,CAAC,CAAA,CAAG,CAClE,OAAA,CAAS,KACX,CAAC,CAAA,CAIHC,CAAAA,CAAU,QAAO,CAMjB,IAAMW,CAAAA,CACJ,OAAO,eAAmB,GAAA,CACtB,IAAI,eAAe,IAAMN,CAAAA,CAAI,eAAe,KAAK,CAAC,CAAA,CAClD,IAAA,CACNM,GAAgB,OAAA,CAAQb,CAAS,EACjC,qBAAA,CAAsB,IAAMO,EAAI,cAAA,CAAe,KAAK,CAAC,CAAA,CACrD,OAAO,UAAA,CAAW,IAAMA,EAAI,cAAA,CAAe,KAAK,EAAG,GAAG,CAAA,CACtD,MAAA,CAAO,UAAA,CAAW,IAAMA,CAAAA,CAAI,cAAA,CAAe,KAAK,CAAA,CAAG,GAAG,EAGtD,IAAMO,CAAAA,CAAU,IAAI,UAAA,CAAW,IAuH/B,OArHiC,CAC/B,UAAYR,CAAAA,EAAMC,CAAAA,CAAI,MAAMF,CAAAA,CAASC,CAAC,CAAA,CAAG,CAAE,QAAS,KAAM,CAAC,EAC3D,OAAA,CAAUS,CAAAA,EAAMR,EAAI,OAAA,CAAQQ,CAAC,CAAA,CAC7B,SAAA,CAAW,CAACC,CAAAA,CAAIC,CAAAA,GACdV,EAAI,SAAA,CAAU,CAACF,EAASW,CAAE,CAAA,CAAGX,CAAAA,CAASY,CAAE,CAAC,CAAA,CAAG,CAAE,QAAS,KAAM,CAAC,EAChE,aAAA,CAAgBC,CAAAA,EAAMN,CAAAA,CAAgBM,CAAC,EACvC,cAAA,CAAiBC,CAAAA,EAAY,CAC3B,IAAMC,CAAAA,CAAW,CACf,UAAA,CACA,iBAAA,CACA,iBAAA,CACA,SAAA,CACA,WACA,WACF,CAAA,CACA,QAAWC,CAAAA,IAAKD,CAAAA,CAAU,CACxB,IAAME,CAAAA,CAAMf,CAAAA,CAAIc,CAAC,EACbC,CAAAA,GAAMH,CAAAA,CAAUG,CAAAA,CAAI,MAAA,GAAWA,CAAAA,CAAI,OAAA,EAAQ,EACjD,CACF,EACA,KAAA,CAAO,CAAChB,EAAGiB,CAAAA,GACThB,CAAAA,CAAI,MAAMF,CAAAA,CAASC,CAAC,CAAA,CAAGiB,CAAAA,EAAG,MAAQhB,CAAAA,CAAI,OAAA,GAAW,CAC/C,QAAA,CAAA,CAAWgB,GAAG,UAAA,EAAc,GAAA,EAAO,GACrC,CAAC,EACH,KAAA,CAAO,CAACjB,EAAGiB,CAAAA,GACThB,CAAAA,CAAI,MAAMF,CAAAA,CAASC,CAAC,CAAA,CAAG,CAAE,UAAWiB,CAAAA,EAAG,UAAA,EAAc,KAAO,GAAK,CAAC,EACpE,SAAA,CAAW,CAACC,CAAAA,CAAMD,CAAAA,GAAM,CACtB,GAAIC,CAAAA,CAAK,SAAW,CAAA,CAAG,OACvB,IAAMC,CAAAA,CAAMF,CAAAA,EAAG,SAAA,EAAa,EAAA,CAC5BhB,EAAI,SAAA,CAAUiB,CAAAA,CAAK,IAAInB,CAAQ,CAAA,CAAG,CAChC,OAAA,CAAS,CAACoB,CAAAA,CAAKA,CAAG,EAClB,QAAA,CAAA,CAAWF,CAAAA,EAAG,YAAc,GAAA,EAAO,GACrC,CAAC,EACH,CAAA,CACA,SAAA,CAAW,IAAM,CACf,IAAMjB,CAAAA,CAAIC,CAAAA,CAAI,SAAA,GACd,OAAO,CAACD,CAAAA,CAAE,GAAA,CAAKA,EAAE,GAAG,CACtB,EACA,OAAA,CAAS,IAAMC,EAAI,OAAA,EAAQ,CAC3B,SAAA,CAAW,IAAM,CACf,IAAMmB,CAAAA,CAAInB,EAAI,SAAA,EAAU,CAClBS,EAAKU,CAAAA,CAAE,YAAA,EAAa,CACpBT,CAAAA,CAAKS,EAAE,YAAA,EAAa,CAC1B,OAAO,CACL,CAACV,EAAG,GAAA,CAAKA,CAAAA,CAAG,GAAG,CAAA,CACf,CAACC,CAAAA,CAAG,GAAA,CAAKA,EAAG,GAAG,CACjB,CACF,CAAA,CACA,SAAA,CAAW,CAACU,CAAAA,CAAIC,EAAQC,CAAAA,GAAW,CAMjC,IAAMC,CAAAA,CAAU,QAAA,CAAS,cAAc,KAAK,CAAA,CAC5CA,CAAAA,CAAQ,OAAA,CAAQ,QAAU,YAAA,CAC1BA,CAAAA,CAAQ,QAAQ,QAAA,CAAW,MAAA,CAC3BA,EAAQ,KAAA,CAAM,QAAA,CAAW,UAAA,CACzBA,CAAAA,CAAQ,MAAM,MAAA,CAAS,SAAA,CACvBA,EAAQ,KAAA,CAAM,SAAA,CACZD,IAAW,QAAA,CACP,uBAAA,CACA,wBAAA,CAENC,CAAAA,CAAQ,iBAAiB,YAAA,CAAc,IAAM5B,CAAAA,CAAU,aAAA,CAAcyB,CAAE,CAAC,CAAA,CACxEG,CAAAA,CAAQ,gBAAA,CAAiB,aAAc,IAAM5B,CAAAA,CAAU,cAAc,IAAI,CAAC,EAC1E4B,CAAAA,CAAQ,gBAAA,CAAiB,OAAA,CAAUC,CAAAA,EACjC7B,EAAU,aAAA,CAAcyB,CAAAA,CAAIK,EAAO,MAAA,CAAQD,CAAC,CAC9C,CAAA,CAEA,IAAME,CAAAA,CAAO9B,CAAAA,CAAE,QAAQ,CACrB,SAAA,CAAW,qBACX,IAAA,CAAM,EAAA,CACN,SAAU,CAAC,CAAA,CAAG,CAAC,CAAA,CACf,WAAY,CAAC,CAAA,CAAG,CAAC,CACnB,CAAC,EACK+B,CAAAA,CAAS/B,CAAAA,CAAE,MAAA,CAAOE,CAAAA,CAASuB,CAAM,CAAA,CAAG,CACxC,KAAAK,CAAAA,CACA,WAAA,CAAa,KACb,QAAA,CAAU,KACZ,CAAC,CAAA,CAAE,MAAM1B,CAAG,CAAA,CAEN4B,EAAkCD,CAAAA,CAAO,UAAA,GAC3CC,CAAAA,GACFA,CAAAA,CAAO,KAAA,CAAM,aAAA,CAAgB,OAC7BA,CAAAA,CAAO,WAAA,CAAYL,CAAO,CAAA,CAAA,CAG5B,IAAME,EAAuB,CAC3B,OAAA,CAAAF,CAAAA,CACA,MAAA,CAAAF,EACA,UAAA,CAAaQ,CAAAA,EAAY,CACvBN,CAAAA,CAAQ,OAAA,CAAQ,SAAWM,CAAAA,CAAU,SAAA,CAAY,MAAA,CAC7CD,CAAAA,GAAQA,EAAO,KAAA,CAAM,MAAA,CAASC,EAAU,MAAA,CAAS,EAAA,EACvD,EACA,WAAA,CAAcC,CAAAA,EAAS,CACrBL,CAAAA,CAAO,OAASK,CAAAA,CAChBH,CAAAA,CAAO,UAAU7B,CAAAA,CAASgC,CAAI,CAAC,EACjC,CAAA,CACA,MAAA,CAAQ,IAAM,CACZ9B,CAAAA,CAAI,WAAA,CAAY2B,CAAM,CAAA,CACtBpB,CAAAA,CAAQ,OAAOa,CAAE,EACnB,CACF,CAAA,CAEA,OAAAb,CAAAA,CAAQ,GAAA,CAAIa,EAAI,CAAE,MAAA,CAAAO,EAAQ,MAAA,CAAAF,CAAO,CAAC,CAAA,CAC3BA,CACT,CAAA,CACA,OAAA,CAAS,IAAM,CACbnB,CAAAA,EAAgB,YAAW,CAC3BC,CAAAA,CAAQ,OAAA,CAAQ,CAAC,CAAE,MAAA,CAAAoB,CAAO,IAAM3B,CAAAA,CAAI,WAAA,CAAY2B,CAAM,CAAC,CAAA,CACvDpB,CAAAA,CAAQ,KAAA,GACRP,CAAAA,CAAI,MAAA,GACN,CAAA,CACA,QAAA,CAAUA,CACZ,CAGF","file":"leaflet.mjs","sourcesContent":["import type {\n AdapterFactory,\n AdapterInstance,\n Coords,\n MarkerHandle,\n} from \"../types\";\n\n/**\n * Leaflet adapter — a WORKER-FREE raster-tile renderer.\n *\n * Why this exists alongside the maplibre adapter: maplibre-gl does all of its\n * rendering in a Web Worker (spawned from a `blob:` URL). Inside a strictly\n * sandboxed MCP App panel the default CSP is `default-src 'none'`, workers\n * fall back to that, and the MCP Apps CSP vocabulary has no `worker-src`\n * knob — so maplibre simply cannot run there. Leaflet paints raster tiles as\n * plain `<img>` elements on the main thread (no worker), so it runs fine; the\n * only thing it needs is network access to the tile host, which IS grantable\n * via the resource's `connectDomains` / `resourceDomains`.\n *\n * Keyless: OSM raster tiles, no API key, no referrer lock. The MCP View\n * forces this adapter (see the provider override in map.tsx); Studio and the\n * embed keep maplibre.\n */\n\nconst LEAFLET_CSS_HREF = \"https://unpkg.com/leaflet@1.9.4/dist/leaflet.css\";\nconst CSS_LINK_ID = \"gds-leaflet-css\";\n\nfunction ensureLeafletCss() {\n if (typeof document === \"undefined\") return;\n // The MCP View bundles Leaflet's CSS inline and sets this flag, so we skip\n // the network <link> there (it would be CSP-blocked anyway).\n if ((globalThis as { __gradeLeafletCssBundled?: boolean }).__gradeLeafletCssBundled)\n return;\n if (document.getElementById(CSS_LINK_ID)) return;\n const link = document.createElement(\"link\");\n link.id = CSS_LINK_ID;\n link.rel = \"stylesheet\";\n link.href = LEAFLET_CSS_HREF;\n document.head.appendChild(link);\n}\n\n// Keyless CARTO raster basemaps (built on OSM data). Much closer to Google\n// Maps' default look than raw OSM: `voyager` is the light, road-forward style;\n// `dark_all` is a real dark style (no CSS-invert hack). Served from the\n// a–d.basemaps.cartocdn.com CDN; those hosts are declared in the MCP View's\n// resource CSP. Free with attribution.\nconst CARTO_STYLE: Record<\"light\" | \"dark\" | \"satellite\", string> = {\n light: \"rastertiles/voyager\",\n dark: \"rastertiles/dark_all\",\n satellite: \"rastertiles/voyager\",\n};\nconst cartoUrl = (style: string) =>\n `https://{s}.basemaps.cartocdn.com/${style}/{z}/{x}/{y}{r}.png`;\nconst CARTO_ATTRIBUTION = \"© OpenStreetMap contributors © CARTO\";\n\nexport const createLeafletAdapter: AdapterFactory = async (\n container,\n opts,\n callbacks\n) => {\n ensureLeafletCss();\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n let L: any;\n try {\n // leaflet is resolved + bundled by the consumer (the MCP preview View);\n // it's intentionally NOT a dependency of @gradeui/ui, so the dts build\n // can't resolve its types here. The value is `any`, so suppress the\n // module-resolution error rather than pull leaflet into this package.\n // @ts-ignore -- optional peer, resolved by the bundling consumer\n L = await import(\"leaflet\");\n if (L.default) L = L.default;\n } catch (err) {\n callbacks.onError({\n code: \"sdk-missing\",\n message:\n '@gradeui/ui Map: `leaflet` is not installed. Run `pnpm add leaflet` to use the worker-free Leaflet adapter.',\n cause: err,\n });\n throw err;\n }\n\n // Grade coords are [lng, lat]; Leaflet wants [lat, lng].\n const toLatLng = (c: Coords): [number, number] => [c[1], c[0]];\n\n const map = L.map(container, {\n center: toLatLng(opts.center),\n zoom: opts.zoom,\n zoomControl: opts.interactive,\n attributionControl: true,\n dragging: opts.interactive,\n scrollWheelZoom: opts.interactive,\n doubleClickZoom: opts.interactive,\n boxZoom: opts.interactive,\n keyboard: opts.interactive,\n touchZoom: opts.interactive,\n });\n\n // Appearance is a different tile STYLE (not a CSS filter), so switching it\n // swaps the layer. `{r}` is Leaflet's retina suffix; `detectRetina` fills it.\n const addTiles = (appearance: \"light\" | \"dark\" | \"satellite\") => {\n const layer = L.tileLayer(cartoUrl(CARTO_STYLE[appearance] ?? CARTO_STYLE.light), {\n maxZoom: 20,\n subdomains: \"abcd\",\n detectRetina: true,\n attribution: CARTO_ATTRIBUTION,\n crossOrigin: true,\n });\n layer.on(\"tileerror\", () =>\n callbacks.onError({\n code: \"tile-load-failed\",\n message: \"map tile failed to load (is the tile host allowed by CSP?)\",\n })\n );\n layer.addTo(map);\n return layer;\n };\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n let tiles: any = addTiles(opts.appearance);\n const applyAppearance = (appearance: \"light\" | \"dark\" | \"satellite\") => {\n if (tiles) map.removeLayer(tiles);\n tiles = addTiles(appearance);\n };\n\n if (opts.bounds) {\n map.fitBounds([toLatLng(opts.bounds[0]), toLatLng(opts.bounds[1])], {\n animate: false,\n });\n }\n\n // Leaflet initialises synchronously — signal ready immediately.\n callbacks.onLoad();\n\n // CRITICAL for sandboxed/absolute-inset containers (the MCP preview panel):\n // the iframe is frequently sized AFTER the map mounts, so Leaflet's initial\n // measurement is 0×0 and it renders NOTHING — no tiles, no markers. Re-measure\n // on the next frames and whenever the container resizes.\n const resizeObserver =\n typeof ResizeObserver !== \"undefined\"\n ? new ResizeObserver(() => map.invalidateSize(false))\n : null;\n resizeObserver?.observe(container);\n requestAnimationFrame(() => map.invalidateSize(false));\n window.setTimeout(() => map.invalidateSize(false), 200);\n window.setTimeout(() => map.invalidateSize(false), 600);\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const markers = new globalThis.Map<string, { marker: any; handle: MarkerHandle }>();\n\n const adapter: AdapterInstance = {\n setCenter: (c) => map.panTo(toLatLng(c), { animate: false }),\n setZoom: (z) => map.setZoom(z),\n setBounds: (sw, ne) =>\n map.fitBounds([toLatLng(sw), toLatLng(ne)], { animate: false }),\n setAppearance: (a) => applyAppearance(a),\n setInteractive: (enabled) => {\n const handlers = [\n \"dragging\",\n \"scrollWheelZoom\",\n \"doubleClickZoom\",\n \"boxZoom\",\n \"keyboard\",\n \"touchZoom\",\n ] as const;\n for (const k of handlers) {\n const ctl = map[k];\n if (ctl) (enabled ? ctl.enable() : ctl.disable());\n }\n },\n flyTo: (c, o) =>\n map.flyTo(toLatLng(c), o?.zoom ?? map.getZoom(), {\n duration: (o?.durationMs ?? 800) / 1000,\n }),\n panTo: (c, o) =>\n map.panTo(toLatLng(c), { duration: (o?.durationMs ?? 600) / 1000 }),\n fitBounds: (list, o) => {\n if (list.length === 0) return;\n const pad = o?.paddingPx ?? 40;\n map.fitBounds(list.map(toLatLng), {\n padding: [pad, pad],\n duration: (o?.durationMs ?? 800) / 1000,\n });\n },\n getCenter: () => {\n const c = map.getCenter();\n return [c.lng, c.lat];\n },\n getZoom: () => map.getZoom(),\n getBounds: () => {\n const b = map.getBounds();\n const sw = b.getSouthWest();\n const ne = b.getNorthEast();\n return [\n [sw.lng, sw.lat],\n [ne.lng, ne.lat],\n ];\n },\n addMarker: (id, coords, anchor) => {\n // Live DOM marker: <MapMarker> portals its React children into\n // `element`. Leaflet positions the icon container's top-left at the\n // coord (iconAnchor [0,0]); our absolutely-positioned element then\n // offsets via transform so its bottom-centre (or centre) sits on the\n // point — matching the maplibre adapter's anchor semantics.\n const element = document.createElement(\"div\");\n element.dataset.gdsPart = \"map-marker\";\n element.dataset.gdsState = \"idle\";\n element.style.position = \"absolute\";\n element.style.cursor = \"pointer\";\n element.style.transform =\n anchor === \"center\"\n ? \"translate(-50%, -50%)\"\n : \"translate(-50%, -100%)\";\n\n element.addEventListener(\"mouseenter\", () => callbacks.onMarkerHover(id));\n element.addEventListener(\"mouseleave\", () => callbacks.onMarkerHover(null));\n element.addEventListener(\"click\", (e) =>\n callbacks.onMarkerClick(id, handle.coords, e)\n );\n\n const icon = L.divIcon({\n className: \"gds-leaflet-marker\",\n html: \"\",\n iconSize: [0, 0],\n iconAnchor: [0, 0],\n });\n const marker = L.marker(toLatLng(coords), {\n icon,\n interactive: true,\n keyboard: false,\n }).addTo(map);\n\n const iconEl: HTMLElement | undefined = marker.getElement();\n if (iconEl) {\n iconEl.style.pointerEvents = \"auto\";\n iconEl.appendChild(element);\n }\n\n const handle: MarkerHandle = {\n element,\n coords,\n setHovered: (hovered) => {\n element.dataset.gdsState = hovered ? \"hovered\" : \"idle\";\n if (iconEl) iconEl.style.zIndex = hovered ? \"1000\" : \"\";\n },\n setPosition: (next) => {\n handle.coords = next;\n marker.setLatLng(toLatLng(next));\n },\n remove: () => {\n map.removeLayer(marker);\n markers.delete(id);\n },\n };\n\n markers.set(id, { marker, handle });\n return handle;\n },\n destroy: () => {\n resizeObserver?.disconnect();\n markers.forEach(({ marker }) => map.removeLayer(marker));\n markers.clear();\n map.remove();\n },\n instance: map,\n };\n\n return adapter;\n};\n"]}
|
|
1
|
+
{"version":3,"sources":["../../components/ui/map/adapters/leaflet.ts"],"names":["LEAFLET_CSS_HREF","CSS_LINK_ID","ensureLeafletCss","link","CARTO_STYLE","cartoUrl","style","CARTO_ATTRIBUTION","createLeafletAdapter","container","opts","callbacks","L","err","toLatLng","c","showZoom","leafletCorner","map","addTiles","appearance","layer","tiles","applyAppearance","resizeObserver","markers","z","sw","ne","a","enabled","handlers","k","ctl","list","pad","b","id","coords","anchor","element","e","handle","icon","marker","iconEl","hovered","next"],"mappings":"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","file":"leaflet.mjs","sourcesContent":["import type {\n AdapterFactory,\n AdapterInstance,\n Coords,\n MarkerHandle,\n} from \"../types\";\n\n/**\n * Leaflet adapter — a WORKER-FREE raster-tile renderer.\n *\n * Why this exists alongside the maplibre adapter: maplibre-gl does all of its\n * rendering in a Web Worker (spawned from a `blob:` URL). Inside a strictly\n * sandboxed MCP App panel the default CSP is `default-src 'none'`, workers\n * fall back to that, and the MCP Apps CSP vocabulary has no `worker-src`\n * knob — so maplibre simply cannot run there. Leaflet paints raster tiles as\n * plain `<img>` elements on the main thread (no worker), so it runs fine; the\n * only thing it needs is network access to the tile host, which IS grantable\n * via the resource's `connectDomains` / `resourceDomains`.\n *\n * Keyless: OSM raster tiles, no API key, no referrer lock. The MCP View\n * forces this adapter (see the provider override in map.tsx); Studio and the\n * embed keep maplibre.\n */\n\nconst LEAFLET_CSS_HREF = \"https://unpkg.com/leaflet@1.9.4/dist/leaflet.css\";\nconst CSS_LINK_ID = \"gds-leaflet-css\";\n\nfunction ensureLeafletCss() {\n if (typeof document === \"undefined\") return;\n // The MCP View bundles Leaflet's CSS inline and sets this flag, so we skip\n // the network <link> there (it would be CSP-blocked anyway).\n if ((globalThis as { __gradeLeafletCssBundled?: boolean }).__gradeLeafletCssBundled)\n return;\n if (document.getElementById(CSS_LINK_ID)) return;\n const link = document.createElement(\"link\");\n link.id = CSS_LINK_ID;\n link.rel = \"stylesheet\";\n link.href = LEAFLET_CSS_HREF;\n document.head.appendChild(link);\n}\n\n// Keyless CARTO raster basemaps (built on OSM data). Much closer to Google\n// Maps' default look than raw OSM: `voyager` is the light, road-forward style;\n// `dark_all` is a real dark style (no CSS-invert hack). Served from the\n// a–d.basemaps.cartocdn.com CDN; those hosts are declared in the MCP View's\n// resource CSP. Free with attribution.\nconst CARTO_STYLE: Record<\"light\" | \"dark\" | \"satellite\", string> = {\n light: \"rastertiles/voyager\",\n dark: \"rastertiles/dark_all\",\n satellite: \"rastertiles/voyager\",\n};\nconst cartoUrl = (style: string) =>\n `https://{s}.basemaps.cartocdn.com/${style}/{z}/{x}/{y}{r}.png`;\nconst CARTO_ATTRIBUTION = \"© OpenStreetMap contributors © CARTO\";\n\nexport const createLeafletAdapter: AdapterFactory = async (\n container,\n opts,\n callbacks\n) => {\n ensureLeafletCss();\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n let L: any;\n try {\n // leaflet is resolved + bundled by the consumer (the MCP preview View);\n // it's intentionally NOT a dependency of @gradeui/ui, so the dts build\n // can't resolve its types here. The value is `any`, so suppress the\n // module-resolution error rather than pull leaflet into this package.\n // @ts-ignore -- optional peer, resolved by the bundling consumer\n L = await import(\"leaflet\");\n if (L.default) L = L.default;\n } catch (err) {\n callbacks.onError({\n code: \"sdk-missing\",\n message:\n '@gradeui/ui Map: `leaflet` is not installed. Run `pnpm add leaflet` to use the worker-free Leaflet adapter.',\n cause: err,\n });\n throw err;\n }\n\n // Grade coords are [lng, lat]; Leaflet wants [lat, lng].\n const toLatLng = (c: Coords): [number, number] => [c[1], c[0]];\n\n // Tools — one vocabulary across providers (see MapTools/MapToolsPosition\n // in types.ts). \"auto\" follows `interactive`; the position maps to\n // Leaflet's squashed corner names. Zoom is added as an explicit control\n // (zoomControl: false at init) so it can dock to any corner.\n const showZoom =\n opts.tools === \"zoom\" || (opts.tools === \"auto\" && opts.interactive);\n const leafletCorner: Record<string, string> = {\n \"top-left\": \"topleft\",\n \"top-right\": \"topright\",\n \"bottom-left\": \"bottomleft\",\n \"bottom-right\": \"bottomright\",\n };\n\n const map = L.map(container, {\n center: toLatLng(opts.center),\n zoom: opts.zoom,\n zoomControl: false,\n attributionControl: true,\n dragging: opts.interactive,\n scrollWheelZoom: opts.interactive,\n doubleClickZoom: opts.interactive,\n boxZoom: opts.interactive,\n keyboard: opts.interactive,\n touchZoom: opts.interactive,\n });\n\n if (showZoom) {\n L.control\n .zoom({ position: leafletCorner[opts.toolsPosition] ?? \"topleft\" })\n .addTo(map);\n }\n\n // Appearance is a different tile STYLE (not a CSS filter), so switching it\n // swaps the layer. `{r}` is Leaflet's retina suffix; `detectRetina` fills it.\n const addTiles = (appearance: \"light\" | \"dark\" | \"satellite\") => {\n const layer = L.tileLayer(cartoUrl(CARTO_STYLE[appearance] ?? CARTO_STYLE.light), {\n maxZoom: 20,\n subdomains: \"abcd\",\n detectRetina: true,\n attribution: CARTO_ATTRIBUTION,\n crossOrigin: true,\n });\n layer.on(\"tileerror\", () =>\n callbacks.onError({\n code: \"tile-load-failed\",\n message: \"map tile failed to load (is the tile host allowed by CSP?)\",\n })\n );\n layer.addTo(map);\n return layer;\n };\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n let tiles: any = addTiles(opts.appearance);\n const applyAppearance = (appearance: \"light\" | \"dark\" | \"satellite\") => {\n if (tiles) map.removeLayer(tiles);\n tiles = addTiles(appearance);\n };\n\n if (opts.bounds) {\n map.fitBounds([toLatLng(opts.bounds[0]), toLatLng(opts.bounds[1])], {\n animate: false,\n });\n }\n\n // Leaflet initialises synchronously — signal ready immediately.\n callbacks.onLoad();\n\n // CRITICAL for sandboxed/absolute-inset containers (the MCP preview panel):\n // the iframe is frequently sized AFTER the map mounts, so Leaflet's initial\n // measurement is 0×0 and it renders NOTHING — no tiles, no markers. Re-measure\n // on the next frames and whenever the container resizes.\n const resizeObserver =\n typeof ResizeObserver !== \"undefined\"\n ? new ResizeObserver(() => map.invalidateSize(false))\n : null;\n resizeObserver?.observe(container);\n requestAnimationFrame(() => map.invalidateSize(false));\n window.setTimeout(() => map.invalidateSize(false), 200);\n window.setTimeout(() => map.invalidateSize(false), 600);\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const markers = new globalThis.Map<string, { marker: any; handle: MarkerHandle }>();\n\n const adapter: AdapterInstance = {\n setCenter: (c) => map.panTo(toLatLng(c), { animate: false }),\n setZoom: (z) => map.setZoom(z),\n setBounds: (sw, ne) =>\n map.fitBounds([toLatLng(sw), toLatLng(ne)], { animate: false }),\n setAppearance: (a) => applyAppearance(a),\n setInteractive: (enabled) => {\n const handlers = [\n \"dragging\",\n \"scrollWheelZoom\",\n \"doubleClickZoom\",\n \"boxZoom\",\n \"keyboard\",\n \"touchZoom\",\n ] as const;\n for (const k of handlers) {\n const ctl = map[k];\n if (ctl) (enabled ? ctl.enable() : ctl.disable());\n }\n },\n flyTo: (c, o) =>\n map.flyTo(toLatLng(c), o?.zoom ?? map.getZoom(), {\n duration: (o?.durationMs ?? 800) / 1000,\n }),\n panTo: (c, o) =>\n map.panTo(toLatLng(c), { duration: (o?.durationMs ?? 600) / 1000 }),\n fitBounds: (list, o) => {\n if (list.length === 0) return;\n const pad = o?.paddingPx ?? 40;\n map.fitBounds(list.map(toLatLng), {\n padding: [pad, pad],\n duration: (o?.durationMs ?? 800) / 1000,\n });\n },\n getCenter: () => {\n const c = map.getCenter();\n return [c.lng, c.lat];\n },\n getZoom: () => map.getZoom(),\n getBounds: () => {\n const b = map.getBounds();\n const sw = b.getSouthWest();\n const ne = b.getNorthEast();\n return [\n [sw.lng, sw.lat],\n [ne.lng, ne.lat],\n ];\n },\n addMarker: (id, coords, anchor) => {\n // Live DOM marker: <MapMarker> portals its React children into\n // `element`. Leaflet positions the icon container's top-left at the\n // coord (iconAnchor [0,0]); our absolutely-positioned element then\n // offsets via transform so its bottom-centre (or centre) sits on the\n // point — matching the maplibre adapter's anchor semantics.\n const element = document.createElement(\"div\");\n element.dataset.gdsPart = \"map-marker\";\n element.dataset.gdsState = \"idle\";\n element.style.position = \"absolute\";\n element.style.cursor = \"pointer\";\n element.style.transform =\n anchor === \"center\"\n ? \"translate(-50%, -50%)\"\n : \"translate(-50%, -100%)\";\n\n element.addEventListener(\"mouseenter\", () => callbacks.onMarkerHover(id));\n element.addEventListener(\"mouseleave\", () => callbacks.onMarkerHover(null));\n element.addEventListener(\"click\", (e) =>\n callbacks.onMarkerClick(id, handle.coords, e)\n );\n\n const icon = L.divIcon({\n className: \"gds-leaflet-marker\",\n html: \"\",\n iconSize: [0, 0],\n iconAnchor: [0, 0],\n });\n const marker = L.marker(toLatLng(coords), {\n icon,\n interactive: true,\n keyboard: false,\n }).addTo(map);\n\n const iconEl: HTMLElement | undefined = marker.getElement();\n if (iconEl) {\n iconEl.style.pointerEvents = \"auto\";\n iconEl.appendChild(element);\n }\n\n const handle: MarkerHandle = {\n element,\n coords,\n setHovered: (hovered) => {\n element.dataset.gdsState = hovered ? \"hovered\" : \"idle\";\n if (iconEl) iconEl.style.zIndex = hovered ? \"1000\" : \"\";\n },\n setPosition: (next) => {\n handle.coords = next;\n marker.setLatLng(toLatLng(next));\n },\n remove: () => {\n map.removeLayer(marker);\n markers.delete(id);\n },\n };\n\n markers.set(id, { marker, handle });\n return handle;\n },\n destroy: () => {\n resizeObserver?.disconnect();\n markers.forEach(({ marker }) => map.removeLayer(marker));\n markers.clear();\n map.remove();\n },\n instance: map,\n };\n\n return adapter;\n};\n"]}
|
package/dist/map/mapbox.d.mts
CHANGED
package/dist/map/mapbox.d.ts
CHANGED
package/dist/map/mapbox.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
"use client";
|
|
2
|
-
'use strict';var p={light:"mapbox://styles/mapbox/light-v11",dark:"mapbox://styles/mapbox/dark-v11",satellite:"mapbox://styles/mapbox/satellite-streets-v12"},
|
|
3
|
-
exports.createMapboxAdapter=
|
|
2
|
+
'use strict';var p={light:"mapbox://styles/mapbox/light-v11",dark:"mapbox://styles/mapbox/dark-v11",satellite:"mapbox://styles/mapbox/satellite-streets-v12"},h="https://unpkg.com/mapbox-gl@3/dist/mapbox-gl.css",f="gds-mapbox-gl-css";function k(){if(typeof document>"u"||document.getElementById(f))return;let m=document.createElement("link");m.id=f,m.rel="stylesheet",m.href=h,document.head.appendChild(m);}var b=async(m,r,l)=>{if(!r.accessToken)throw l.onError({code:"api-key-missing",message:'@gradeui/ui Map: provider="mapbox" requires an `accessToken` prop.'}),new Error("mapbox accessToken missing");k();let d;try{d=await import('mapbox-gl'),d.default&&(d=d.default);}catch(e){throw l.onError({code:"sdk-missing",message:'@gradeui/ui Map: `mapbox-gl` is not installed. Run `pnpm add mapbox-gl` to use provider="mapbox".',cause:e}),e}d.accessToken=r.accessToken;let y=r.styleUrl??p[r.appearance],o=new d.Map({container:m,style:y,center:r.center,zoom:r.zoom,interactive:r.interactive});(r.tools==="zoom"||r.tools==="auto"&&r.interactive)&&o.addControl(new d.NavigationControl({showCompass:false}),r.toolsPosition),r.bounds&&o.fitBounds([r.bounds[0],r.bounds[1]],{animate:false}),await new Promise(e=>{o.once("load",()=>e());}),l.onLoad(),o.on("error",e=>{let t=String(e?.error?.message??e?.message??"Mapbox error"),s=t.toLowerCase().includes("style");l.onError({code:s?"style-load-failed":"tile-load-failed",message:t,cause:e?.error??e});});let u=new globalThis.Map;return {setCenter:e=>o.setCenter(e),setZoom:e=>o.setZoom(e),setBounds:(e,t)=>o.fitBounds([e,t],{animate:false}),setAppearance:e=>{let t=r.styleUrl??p[e];o.setStyle(t,{diff:false});},setInteractive:e=>{let t=["scrollZoom","boxZoom","dragRotate","dragPan","keyboard","doubleClickZoom","touchZoomRotate"];for(let s of t){let n=o[s];n&&(e?n.enable():n.disable());}},flyTo:(e,t)=>o.flyTo({center:e,zoom:t?.zoom,duration:t?.durationMs??800}),panTo:(e,t)=>o.panTo(e,{duration:t?.durationMs??600}),fitBounds:(e,t)=>{if(e.length===0)return;let s=1/0,n=1/0,c=-1/0,i=-1/0;for(let[a,g]of e)a<s&&(s=a),g<n&&(n=g),a>c&&(c=a),g>i&&(i=g);o.fitBounds([[s,n],[c,i]],{padding:t?.paddingPx??40,duration:t?.durationMs??800});},getCenter:()=>{let e=o.getCenter();return [e.lng,e.lat]},getZoom:()=>o.getZoom(),getBounds:()=>{let e=o.getBounds();return [[e.getWest(),e.getSouth()],[e.getEast(),e.getNorth()]]},addMarker:(e,t,s)=>{let n=document.createElement("div");n.dataset.gdsPart="map-marker",n.dataset.gdsState="idle",n.style.cursor="pointer",n.addEventListener("mouseenter",()=>l.onMarkerHover(e)),n.addEventListener("mouseleave",()=>l.onMarkerHover(null)),n.addEventListener("click",a=>{l.onMarkerClick(e,i.coords,a);});let c=new d.Marker({element:n,anchor:s==="center"?"center":"bottom"}).setLngLat(t).addTo(o),i={element:n,coords:t,setHovered:a=>{n.dataset.gdsState=a?"hovered":"idle",n.style.zIndex=a?"10":"1";},setPosition:a=>{i.coords=a,c.setLngLat(a);},remove:()=>{c.remove(),u.delete(e);}};return u.set(e,{marker:c,handle:i}),i},destroy:()=>{u.forEach(({marker:e})=>e.remove()),u.clear(),o.remove();},instance:o}};
|
|
3
|
+
exports.createMapboxAdapter=b;//# sourceMappingURL=mapbox.js.map
|
|
4
4
|
//# sourceMappingURL=mapbox.js.map
|