wovvmap-webview-bridge
v1.0.28
Published
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 -
Readme
wovvmap-webview-bridge
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
- Strongly typed message contracts
Installation
npm install react-native-webview zustand
# or
yarn add react-native-webview zustandQuick start
Web (React TS) usage
Use the web entrypoint so you don't need react-native or react-native-webview in your web app.
import React from "react";
import { WebIframeScreen } from "wovvmap-webview-bridge/web";
export default function App() {
return (
<WebIframeScreen
url="https://your-map-app-url.com"
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:
import React, { useEffect, useRef } from "react";
import {
attachIframeBridge,
registerBridgeHandler,
sendStartPointToBridge,
} from "wovvmap-webview-bridge/web";
export default function App() {
const iframeRef = useRef<HTMLIFrameElement>(null);
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 (
<iframe
ref={iframeRef}
src="https://your-map-app-url.com"
style={{ width: "100%", height: "100%", border: 0 }}
title="Wovv Map"
/>
);
}1) Render the WebView
import React from "react";
import { WebViewScreen } from "wovvmap-webview-bridge";
export default function App() {
return <WebViewScreen url="https://your-map-app-url.com" />;
}2) Send events to the WebView (RN -> Web)
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" });3) Handle events from the WebView (Web -> RN)
You can register handlers for click events. All other events are stored in the Zustand store.
import { registerBridgeHandler } from "wovvmap-webview-bridge";
registerBridgeHandler("isSceneClick", (payload) => {
console.log("Scene clicked", payload);
});
registerBridgeHandler("isShapeClick", (payload) => {
console.log("Shape clicked", payload.value);
});4) Read synced state from the store
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
Bridge message contracts
IncomingMessage (Web -> RN)
Keys and payloads:
- pong: boolean
- isConnection: boolean
- mapLoaded: boolean
- _searchablePoints: NodePoint[]
- _allAmenities: AmenityWithNodePoint[]
- _allOffers: string[]
- _activeFloor: number
- FloorImg: FloorImage[]
- categories: Record<ExternalId, Category>
- subCategories: Record<ExternalId, SubCategory>
- isSceneClick: no value
- isShapeClick: NodePoint
- stepByStepList: StepByStepResult
- pathNextPreState: NavState
- cameraControllerState: { cameraPosition: CameraPosition; controlsPosition: ControlsPosition }
OutgoingMessage (RN -> Web)
Keys and payloads:
- applyCSS: { selector: string; style: Partial }
- ping: boolean
- setEndPoint: string
- setStartPoint: string
- setActiveFloor: number
- pathNextBtnClick: no value
- pathPreBtnClick: no value
- pathFinishBtnClick: no value
- setSelectCategory: string | string[] | null
- zoomIn: no value
- zoomOut: no value
- clearStartAndEndPoint: no value
- setPathFilter: filterPath
- getDirection: no value
- setMapTheme: Theme | null
- navigateTo: string
- editableView: MapApiResponse
- pathHighlightByStepIndex: number
Exported API
Components
- WebViewScreen
- WebIframeScreen (web only)
Bridge helpers
- sendStartPointToBridge
- sendEndPointToBridge
- sendActiveFloorToBridge
- sendPathNextBtnClick
- sendPathPreBtnClick
- sendPathFinishBtnClick
- sendSelectCategory
- sendZoomIn
- sendZoomOut
- sendClearStartAndEndPoint
- sendGetDirectionToBridge
- sendPathFilter
- sendNavigateToBridge
- sendMapThemeToBridge
Handlers
- registerBridgeHandler
Store
- useBridgeStorage (Zustand)
Types
- IncomingMessage, OutgoingMessage
- NodePoint
- AmenityWithNodePoint
- Category, SubCategory, ExternalId
- Environment, DayHours, WeeklyHours
- NodePointOffer, BrandInfo
- MapExportContext, GeometryFloor, GeometryNodePoint, GeometryLayer
- NodeMetadata, AssetPayloads
- FloorImage
- StepInstruction, PathSummary, StepByStepResult
- NavState
- filterPath
- Theme
- CameraPosition, ControlsPosition
- MapApiResponse, MapDataExport
File structure
src/
index.ts
webviewBridge/
WebViewScreen.tsx
BridgeService.ts
BridgeStorage.ts
WebViewBridgeRef.ts
handlers/
WebBridgeHandlers.ts
types/
types.tsLicense
MIT
