11import * as React from "react" ;
2- import { Image , ImageSourcePropType } from "react-native" ;
2+ import {
3+ Image ,
4+ ImageSourcePropType ,
5+ View ,
6+ StyleSheet ,
7+ Text ,
8+ } from "react-native" ;
39import { Marker as MapMarkerComponent } from "./react-native-maps" ;
410import type { MapMarkerProps as MapMarkerComponentProps } from "react-native-maps" ;
11+ import MapCallout , { renderCallout } from "./MapCallout" ;
512
613export interface MapMarkerProps
714 extends Omit < MapMarkerComponentProps , "onPress" | "coordinate" > {
@@ -12,17 +19,55 @@ export interface MapMarkerProps
1219 onPress ?: ( latitude : number , longitude : number ) => void ;
1320}
1421
15- const MapMarker : React . FC < React . PropsWithChildren < MapMarkerProps > > = ( {
16- latitude,
17- longitude,
18- pinImage,
19- pinImageSize = 50 ,
20- onPress,
21- children,
22- ...rest
23- } ) => {
22+ /**
23+ * Renders nothing, serves as placeholder for props
24+ * Rendering exposed as function to avoid having an intermediary component that changes the type
25+ *
26+ * This is done because the underlying package has logic dependant on the type of child
27+ */
28+ const MapMarker : React . FC < React . PropsWithChildren < MapMarkerProps > > = ( ) => {
29+ return null ;
30+ } ;
31+
32+ export function renderMarker (
33+ {
34+ latitude,
35+ longitude,
36+ pinImage,
37+ pinImageSize = 50 ,
38+ onPress,
39+ children,
40+ title,
41+ description,
42+ ...rest
43+ } : MapMarkerProps ,
44+ key : React . Key
45+ ) {
46+ const childrenArray = React . Children . toArray ( children ) ;
47+
48+ const calloutChildren = childrenArray . filter (
49+ ( child ) => ( child as React . ReactElement ) . type === MapCallout
50+ ) ;
51+
52+ const nonCalloutChildren = childrenArray . filter (
53+ ( child ) => ( child as React . ReactElement ) . type !== MapCallout
54+ ) ;
55+
56+ // Add default callout for title/description
57+ if ( calloutChildren . length === 0 && ( title || description ) ) {
58+ calloutChildren . push (
59+ < MapCallout showTooltip >
60+ < View >
61+ { title && < Text style = { style . title } > { title } </ Text > }
62+ { description && < Text style = { style . description } > { description } </ Text > }
63+ </ View >
64+ </ MapCallout >
65+ ) ;
66+ }
67+
2468 return (
2569 < MapMarkerComponent
70+ key = { key }
2671 coordinate = { {
2772 latitude,
2873 longitude,
@@ -33,6 +78,8 @@ const MapMarker: React.FC<React.PropsWithChildren<MapMarkerProps>> = ({
3378 } }
3479 { ...rest }
3580 >
81+ { nonCalloutChildren }
82+
3683 { pinImage && (
3784 < Image
3885 source = { typeof pinImage === "string" ? { uri : pinImage } : pinImage }
@@ -43,9 +90,22 @@ const MapMarker: React.FC<React.PropsWithChildren<MapMarkerProps>> = ({
4390 } }
4491 />
4592 ) }
46- { children }
93+
94+ { calloutChildren . map ( ( callout , index ) =>
95+ renderCallout ( ( callout as React . ReactElement ) . props , index )
96+ ) }
4797 </ MapMarkerComponent >
4898 ) ;
49- } ;
99+ }
100+
101+ const style = StyleSheet . create ( {
102+ title : {
103+ fontWeight : "600" ,
104+ textAlign : "center" ,
105+ } ,
106+ description : {
107+ textAlign : "center" ,
108+ } ,
109+ } ) ;
50110
51111export default MapMarker ;
0 commit comments