import React, { FC, useCallback, useLayoutEffect, useRef, useState, } from 'react'; import { Platform, StyleSheet, View } from 'react-native'; import WebView from 'react-native-webview'; import { Layers, Markers, TileOptions, Zoom } from '../types/types'; type Props = { map: { src: string; tileOptions?: TileOptions; }; layers?: Layers[]; zoom?: Zoom; minZoom?: Zoom; maxZoom?: Zoom; markers?: Markers[]; flyTo?: { latLng: number[]; zoom: Zoom; }; onMessage?: (event: any) => void; onError?: (event: any) => void; onLoadStart?: () => void; startInLoadingState?: boolean; backgroundColor?: string; injectJavascript?: string; }; export const RNLeaflet: FC = ({ map, layers, zoom = 0, minZoom, maxZoom, markers, flyTo, onMessage, onError, onLoadStart, startInLoadingState = true, backgroundColor, injectJavascript, }) => { const htmlFile = Platform.OS === 'android' ? { uri: 'file:///android_asset/Leaflet.html' } : require('../html/Leaflet.html'); const ref = useRef(null); const [configured, setConfigured] = useState(false); const sendAction = useCallback((message: any) => { if (!ref?.current) return; ref.current.postMessage(`${JSON.stringify(message)}`); }, []); const injectScript = useCallback((script: string) => { ref.current?.injectJavaScript(script); }, []); useLayoutEffect(() => { if (!configured) return; if (!flyTo) { sendAction({ zoom }); } if (maxZoom) sendAction({ maxZoom }); if (minZoom) sendAction({ minZoom }); if (markers) sendAction({ markers }); if (flyTo) { sendAction({ flyTo: { latLng: flyTo?.latLng, zoom: flyTo?.zoom, }, }); } if (layers) sendAction({ layers }); if (map) sendAction({ map }); }, [ flyTo, flyTo?.latLng, flyTo?.zoom, markers, maxZoom, sendAction, map, zoom, configured, minZoom, ]); useLayoutEffect(() => { if (!configured) return; if (injectJavascript) injectScript(injectJavascript); }, [configured, injectJavascript, injectScript]); return ( onMessage && onMessage(e?.nativeEvent?.data)} onError={onError} onLoadStart={onLoadStart} onLoadEnd={() => setConfigured(true)} startInLoadingState={startInLoadingState} originWhitelist={['*']} javaScriptEnabled domStorageEnabled /> ); }; const styles = StyleSheet.create({ wrapper: { flex: 1, }, flexer: { flex: 1, backgroundColor: 'transparent', }, });