@facilitronworks/react-native-windows-maps
v0.1.0-pre.0
Published
The app-agnostic half of a react-native-windows map: Web Mercator projection maths, and a builder for the maplibre-gl page that renders inside a WebView2 island. Zero runtime dependencies.
Downloads
1,251
Maintainers
Readme
@facilitronworks/react-native-windows-maps
The app-agnostic half of a react-native-windows map surface: Web Mercator projection maths, and a builder for the maplibre-gl HTML page that renders inside a WebView2 island.
Zero runtime dependencies. Both modules are pure TypeScript with no imports.
What this is not
This package deliberately does not ship a <MapView> component or any basemap style resolution.
Style resolution reads EXPO_PUBLIC_* environment variables, and babel-preset-expo only inlines
those for files outside node_modules. A resolver living in this package would silently read
'' in every build: the map would fall back to raw OSM tiles and the dark-mode toggle would inject a
byte-identical style, doing nothing, with no error and no failing test. The host app owns styling and
passes the resolved style in.
Usage
import {
buildMapPage,
projectToViewport,
regionToZoom,
viewportToRegion,
type LatLng,
type Region,
} from '@facilitronworks/react-native-windows-maps';buildMapPage(options) returns a complete HTML document. Render it in a WebView that injects
window.ReactNativeWebView.postMessage before content load.
Bridge protocol
page → host, via window.ReactNativeWebView.postMessage:
| message | meaning |
| --- | --- |
| {type:'ready'} | maplibre constructed, first style loaded |
| {type:'viewport', center, zoom, css} | on every move and on resize |
| {type:'press', coordinate} | single click on the map surface |
| {type:'markerPress', id} | an in-page marker element was clicked |
| {type:'error', message} | script / style / tile failure |
host → page, via injectJavaScript against window.__worksMap:
| call | meaning |
| --- | --- |
| setRegion({center, zoom}, durationMs) | camera move (0 = jump) |
| setStyle(styleJsonOrUrl) | appearance change |
| setMarkers(list) | replace the in-page marker layer |
Markers render in the page, not over it
On react-native-windows the WebView2 island composites above all react-native content within its
bounds, regardless of sibling order or zIndex (verified against three independent layering
strategies). An RN overlay can therefore never be seen. The host still computes clusters and owns
every handler; the page only draws the bubbles it is handed via setMarkers and reports presses
back. Each entry is plain data — {id, latitude, longitude, kind:'cluster'|'pin', label, bg, fg,
border, size} — themed by the host.
maplibre-gl is pinned by version and SRI
The page loads maplibre-gl from unpkg pinned by version and by sha384 subresource integrity.
MAPLIBRE_JS_SRI / MAPLIBRE_CSS_SRI are the hashes of the exact artifacts in [email protected].
A tampered or substituted file fails the check, the script does not execute, and the page reports
{type:'error'} so the host can fall back.
maplibre-gl is declared as an optional peer dependency so a host on a different version gets an
install-time signal. If you bump it, the two SRI constants must be regenerated in the same change or
the map loads nothing.
Platform
Correct only under the windows platform, where Metro redirects react-native to
react-native-windows.
License
MIT
