A typed bridge between React Native and a WebView for Wovvmap maps. It provides: - WebViewScreen wrapper for React Native WebView - BridgeService helpers to send events to the WebView - Zustand store (useBridgeStorage) that keeps incoming state in sync -
npm install wovvmap-webview-bridgeA typed bridge between React Native and a WebView for Wovvmap maps. It provides:
- WebViewScreen wrapper for React Native WebView
- BridgeService helpers to send events to the WebView
- Zustand store (useBridgeStorage) that keeps incoming state in sync
- Strongly typed message contracts
``bash`
npm install react-native-webview zustandor
yarn add react-native-webview zustand
Use the web entrypoint so you don't need react-native or react-native-webview in your web app.
`tsx
import React from "react";
import { WebIframeScreen } from "wovvmap-webview-bridge/web";
export default function App() {
return (
origin="https://your-map-app-url.com"
onload={() => console.log("iframe loaded")}
style={{ width: "100%", height: "100vh" }}
/>
);
}
`
You can also attach to your own iframe ref:
`tsx
import React, { useEffect, useRef } from "react";
import {
attachIframeBridge,
registerBridgeHandler,
sendStartPointToBridge,
} from "wovvmap-webview-bridge/web";
export default function App() {
const iframeRef = useRef
useEffect(() => {
if (!iframeRef.current) return;
const cleanup = attachIframeBridge({
iframe: iframeRef.current,
origin: "https://your-map-app-url.com",
onLoad: () => sendStartPointToBridge("A1"),
});
registerBridgeHandler("isSceneClick", (payload) => {
console.log("Scene clicked", payload);
});
return cleanup;
}, []);
return (
ref={iframeRef}
src="https://your-map-app-url.com"
style={{ width: "100%", height: "100%", border: 0 }}
title="Wovv Map"
/>
);
}
`
`tsx
import React from "react";
import { WebViewScreen } from "wovvmap-webview-bridge";
export default function App() {
return
}
`
`tsx
import {
sendStartPointToBridge,
sendEndPointToBridge,
sendActiveFloorToBridge,
sendPathNextBtnClick,
sendPathPreBtnClick,
sendPathFinishBtnClick,
sendSelectCategory,
sendZoomIn,
sendZoomOut,
sendClearStartAndEndPoint,
sendPathFilter,
sendGetDirectionToBridge,
sendNavigateToBridge,
sendMapThemeToBridge,
} from "wovvmap-webview-bridge";
sendStartPointToBridge("A1");
sendEndPointToBridge("B5");
sendActiveFloorToBridge(2);
sendPathNextBtnClick();
sendPathPreBtnClick();
sendPathFinishBtnClick();
sendSelectCategory(["Food", "Fashion"]);
sendZoomIn();
sendZoomOut();
sendClearStartAndEndPoint();
sendPathFilter();
sendGetDirectionToBridge();
sendNavigateToBridge("map-id-123");
sendMapThemeToBridge({ "theme-path-color": "#00AAFF" });
`
You can register handlers for click events. All other events are stored in the Zustand store.
`tsx
import { registerBridgeHandler } from "wovvmap-webview-bridge";
registerBridgeHandler("isSceneClick", (payload) => {
console.log("Scene clicked", payload);
});
registerBridgeHandler("isShapeClick", (payload) => {
console.log("Shape clicked", payload.value);
});
`
`tsx
import { useBridgeStorage } from "wovvmap-webview-bridge";
const state = useBridgeStorage((s) => ({
isBridgeLoaded: s.isBridgeLoaded,
isMapLoaded: s.isMapLoaded,
searchablePoints: s.searchablePoints,
amenities: s.amenities,
allOffers: s.allOffers,
activeFloor: s.activeFloor,
stepByStepList: s.stepByStepList,
pathSummary: s.pathSummary,
categories: s.categories,
subCategories: s.subCategories,
}));
`
Store fields:
- isBridgeLoaded
- isMapLoaded
- searchablePoints
- amenities
- allOffers
- activeFloor
- elevator, escalator
- floorImages
- stepByStepList
- pathSummary
- nextPreState
- pointsByKey
- categories
- subCategories
- cameraControllerState
```
src/
index.ts
webviewBridge/
WebViewScreen.tsx
BridgeService.ts
BridgeStorage.ts
WebViewBridgeRef.ts
handlers/
WebBridgeHandlers.ts
types/
types.ts
MIT