Skip to content

Commit 4af675c

Browse files
authored
Update how Markers/Callout are rendered (47.3.4) (#687)
* Upgrade teovilla/web-maps version * Updated how markers & callouts are rendered to maintain types + added default callout for title/description * v47.3.4
1 parent e029fb7 commit 4af675c

File tree

12 files changed

+139
-57
lines changed

12 files changed

+139
-57
lines changed

example/package.json

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "@draftbit/example",
33
"description": "Example app for @draftbit/ui",
4-
"version": "47.3.3",
4+
"version": "47.3.4",
55
"private": true,
66
"main": "__generated__/AppEntry.js",
77
"scripts": {
@@ -15,8 +15,8 @@
1515
"clean:modules": "rimraf node_modules"
1616
},
1717
"dependencies": {
18-
"@draftbit/maps": "47.3.3",
19-
"@draftbit/ui": "47.3.3",
18+
"@draftbit/maps": "47.3.4",
19+
"@draftbit/ui": "47.3.4",
2020
"@expo/dev-server": "0.1.123",
2121
"@expo/webpack-config": "^0.17.2",
2222
"@react-navigation/drawer": "^5.12.9",

lerna.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
{
2-
"version": "47.3.3",
2+
"version": "47.3.4",
33
"npmClient": "yarn",
44
"useWorkspaces": true,
55
"packages": ["packages/*", "example"],

packages/core/package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@draftbit/core",
3-
"version": "47.3.3",
3+
"version": "47.3.4",
44
"description": "Core (non-native) Components",
55
"main": "lib/src/index.js",
66
"types": "lib/src/index.d.ts",
@@ -39,7 +39,7 @@
3939
"dependencies": {
4040
"@date-io/date-fns": "^1.3.13",
4141
"@draftbit/react-theme-provider": "^2.1.1",
42-
"@draftbit/types": "47.3.3",
42+
"@draftbit/types": "47.3.4",
4343
"@expo/vector-icons": "^13.0.0",
4444
"@material-ui/core": "^4.11.0",
4545
"@material-ui/pickers": "^3.2.10",

packages/maps/package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@draftbit/maps",
3-
"version": "47.3.3",
3+
"version": "47.3.4",
44
"description": "Map Components",
55
"main": "lib/src/index.js",
66
"types": "lib/src/index.d.ts",
@@ -37,7 +37,7 @@
3737
},
3838
"homepage": "https://github.com/draftbit/react-native-jigsaw#readme",
3939
"dependencies": {
40-
"@teovilla/react-native-web-maps": "^0.9.0",
40+
"@teovilla/react-native-web-maps": "^0.9.1",
4141
"react-native-maps": "1.3.2"
4242
},
4343
"eslintIgnore": [
Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,27 @@
11
import * as React from "react";
2-
import { Callout as MapCalloutComponent } from "./react-native-maps";
32
import type { MapCalloutProps as MapCalloutComponentProps } from "react-native-maps";
3+
import { Callout as MapCalloutComponent } from "./react-native-maps";
44

55
export interface MapCalloutProps
66
extends Omit<MapCalloutComponentProps, "tooltip"> {
77
showTooltip?: boolean;
88
}
99

10-
// Has to be a function named 'Callout' to be matched as a Callout component and not a custom view for marker
11-
// See: https://github.com/teovillanueva/react-native-web-maps/blob/81278079c6f26a707d915d69de9a00080c305957/packages/react-native-web-maps/src/components/marker.web.tsx#L79
12-
export function Callout({
13-
showTooltip,
14-
...rest
15-
}: React.PropsWithChildren<MapCalloutProps>) {
16-
return <MapCalloutComponent tooltip={!showTooltip} {...rest} />;
10+
/**
11+
* Renders nothing, serves as placeholder for props
12+
* Rendering exposed as function to avoid having an intermediary component that changes the type
13+
*
14+
* This is done because the underlying package has logic dependant on the type of child
15+
* See: https://github.com/teovillanueva/react-native-web-maps/blob/5f3d0ec7c24f789c3df30c1d6d7223e638ff5868/packages/react-native-web-maps/src/components/marker.web.tsx#L79
16+
*/
17+
const MapCallout: React.FC<React.PropsWithChildren<MapCalloutProps>> = () => {
18+
return null;
19+
};
20+
21+
export function renderCallout(props: MapCalloutProps, key: React.Key) {
22+
return (
23+
<MapCalloutComponent key={key} tooltip={!props.showTooltip} {...props} />
24+
);
1725
}
26+
27+
export default MapCallout;
Lines changed: 72 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,14 @@
11
import * 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";
39
import { Marker as MapMarkerComponent } from "./react-native-maps";
410
import type { MapMarkerProps as MapMarkerComponentProps } from "react-native-maps";
11+
import MapCallout, { renderCallout } from "./MapCallout";
512

613
export 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

51111
export default MapMarker;

packages/maps/src/components/MapView.tsx

Lines changed: 30 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import type {
77
Region,
88
MapViewProps as MapViewComponentProps,
99
} from "react-native-maps";
10+
import MapMarker, { renderMarker } from "./MapMarker";
1011

1112
export interface MapViewProps<T> extends MapViewComponentProps {
1213
apiKey: string;
@@ -69,6 +70,32 @@ class MapView<T> extends React.Component<
6970
this.mapRef.current.animateCamera(camera);
7071
}
7172

73+
getMarkers(): React.ReactElement[] {
74+
const { markersData, renderItem, keyExtractor, children } = this.props;
75+
76+
if (markersData && renderItem) {
77+
const markers: React.ReactElement[] = [];
78+
79+
markersData.forEach((item, index) => {
80+
const component = renderItem?.({ item, index });
81+
82+
if (component && component.type === MapMarker) {
83+
const key = keyExtractor ? keyExtractor(item, index) : index;
84+
markers.push(
85+
React.cloneElement(component, {
86+
key,
87+
})
88+
);
89+
}
90+
});
91+
return markers;
92+
} else {
93+
return React.Children.toArray(children).filter(
94+
(child) => (child as React.ReactElement).type === MapMarker
95+
) as React.ReactElement[];
96+
}
97+
}
98+
7299
render() {
73100
const {
74101
apiKey,
@@ -78,12 +105,8 @@ class MapView<T> extends React.Component<
78105
zoom,
79106
showsCompass = false,
80107
loadingEnabled = true,
81-
markersData,
82-
renderItem,
83-
keyExtractor,
84108
onRegionChange,
85109
style,
86-
children,
87110
...rest
88111
} = this.props;
89112

@@ -112,20 +135,9 @@ class MapView<T> extends React.Component<
112135
style={[styles.map, style]}
113136
{...rest}
114137
>
115-
{markersData && renderItem
116-
? markersData.map((item, index) => {
117-
const component = renderItem({ item, index });
118-
119-
if (!component) {
120-
return null;
121-
}
122-
123-
const key = keyExtractor ? keyExtractor(item, index) : index;
124-
return React.cloneElement(component, {
125-
key,
126-
});
127-
})
128-
: children}
138+
{this.getMarkers().map((marker, index) =>
139+
renderMarker(marker.props, index)
140+
)}
129141
</MapViewComponent>
130142
);
131143
}

packages/maps/src/index.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
export { default as MapView } from "./components/MapView";
22
export { default as MapMarker } from "./components/MapMarker";
3-
export { Callout as MapCallout } from "./components/MapCallout";
3+
export { default as MapCallout } from "./components/MapCallout";

packages/native/package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@draftbit/native",
3-
"version": "47.3.3",
3+
"version": "47.3.4",
44
"description": "Draftbit UI Components that Depend on Native Components",
55
"main": "lib/src/index.js",
66
"types": "lib/src/index.d.ts",
@@ -37,7 +37,7 @@
3737
},
3838
"homepage": "https://github.com/draftbit/react-native-jigsaw#readme",
3939
"dependencies": {
40-
"@draftbit/types": "47.3.3",
40+
"@draftbit/types": "47.3.4",
4141
"@expo/vector-icons": "^13.0.0",
4242
"@react-native-community/datetimepicker": "6.3.5",
4343
"@react-native-community/slider": "4.2.4",

packages/types/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@draftbit/types",
3-
"version": "47.3.3",
3+
"version": "47.3.4",
44
"description": "Shared constants and types between native and core components",
55
"main": "lib/src/index.js",
66
"types": "lib/src/index.d.ts",

0 commit comments

Comments
 (0)