@lugg/maps 0.2.0-alpha.9 → 1.0.0-beta.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (184) hide show
  1. package/README.md +21 -20
  2. package/android/build.gradle +1 -1
  3. package/android/src/main/java/com/luggmaps/LuggCalloutView.kt +74 -0
  4. package/android/src/main/java/com/luggmaps/LuggCalloutViewManager.kt +38 -0
  5. package/android/src/main/java/com/luggmaps/LuggMapView.kt +290 -0
  6. package/android/src/main/java/com/luggmaps/{LuggGoogleMapViewManager.kt → LuggMapViewManager.kt} +99 -36
  7. package/android/src/main/java/com/luggmaps/LuggMapWrapperView.kt +11 -14
  8. package/android/src/main/java/com/luggmaps/LuggMarkerView.kt +187 -21
  9. package/android/src/main/java/com/luggmaps/LuggMarkerViewManager.kt +28 -0
  10. package/android/src/main/java/com/luggmaps/LuggPackage.kt +8 -4
  11. package/android/src/main/java/com/luggmaps/LuggPolygonView.kt +85 -0
  12. package/android/src/main/java/com/luggmaps/LuggPolygonViewManager.kt +100 -0
  13. package/android/src/main/java/com/luggmaps/LuggPolylineView.kt +16 -0
  14. package/android/src/main/java/com/luggmaps/LuggPolylineViewManager.kt +22 -0
  15. package/android/src/main/java/com/luggmaps/core/GoogleMapProvider.kt +874 -0
  16. package/android/src/main/java/com/luggmaps/core/MapProviderDelegate.kt +60 -0
  17. package/android/src/main/java/com/luggmaps/core/PolylineAnimator.kt +89 -24
  18. package/android/src/main/java/com/luggmaps/events/LongPressEvent.kt +29 -0
  19. package/android/src/main/java/com/luggmaps/events/MarkerDragEvent.kt +41 -0
  20. package/android/src/main/java/com/luggmaps/events/MarkerPressEvent.kt +34 -0
  21. package/android/src/main/java/com/luggmaps/events/PolygonPressEvent.kt +12 -0
  22. package/android/src/main/java/com/luggmaps/events/PressEvent.kt +29 -0
  23. package/ios/LuggCalloutView.h +23 -0
  24. package/ios/LuggCalloutView.mm +145 -0
  25. package/ios/LuggMapView.h +9 -0
  26. package/ios/LuggMapView.mm +343 -0
  27. package/ios/LuggMarkerView.h +15 -0
  28. package/ios/LuggMarkerView.mm +136 -2
  29. package/ios/LuggPolygonView.h +31 -0
  30. package/ios/LuggPolygonView.mm +151 -0
  31. package/ios/LuggPolylineView.h +4 -0
  32. package/ios/LuggPolylineView.mm +23 -0
  33. package/ios/core/AppleMapProvider.h +15 -0
  34. package/ios/core/AppleMapProvider.mm +1173 -0
  35. package/ios/core/GMSPolylineAnimator.h +3 -0
  36. package/ios/core/GMSPolylineAnimator.m +101 -15
  37. package/ios/core/GoogleMapProvider.h +13 -0
  38. package/ios/core/GoogleMapProvider.mm +798 -0
  39. package/ios/core/LuggAnnotationView.h +12 -0
  40. package/ios/core/LuggAnnotationView.mm +55 -0
  41. package/ios/core/MKPolylineAnimator.h +4 -0
  42. package/ios/core/MKPolylineAnimator.m +167 -42
  43. package/ios/core/MapProviderDelegate.h +84 -0
  44. package/ios/core/PolylineAnimatorBase.h +24 -1
  45. package/ios/core/PolylineAnimatorBase.m +82 -19
  46. package/ios/events/LongPressEvent.h +29 -0
  47. package/ios/events/MarkerDragEvent.h +69 -0
  48. package/ios/events/MarkerPressEvent.h +29 -0
  49. package/ios/events/PolygonPressEvent.h +20 -0
  50. package/ios/events/PressEvent.h +29 -0
  51. package/ios/extensions/MKMapView+Zoom.h +2 -0
  52. package/ios/extensions/MKMapView+Zoom.m +14 -4
  53. package/lib/module/MapProvider.js +2 -4
  54. package/lib/module/MapProvider.js.map +1 -1
  55. package/lib/module/MapProvider.web.js +14 -7
  56. package/lib/module/MapProvider.web.js.map +1 -1
  57. package/lib/module/MapView.js +33 -16
  58. package/lib/module/MapView.js.map +1 -1
  59. package/lib/module/MapView.web.js +296 -181
  60. package/lib/module/MapView.web.js.map +1 -1
  61. package/lib/module/components/GeoJson.js +159 -0
  62. package/lib/module/components/GeoJson.js.map +1 -0
  63. package/lib/module/components/GeoJson.types.js +4 -0
  64. package/lib/module/components/GeoJson.types.js.map +1 -0
  65. package/lib/module/components/Marker.js +49 -8
  66. package/lib/module/components/Marker.js.map +1 -1
  67. package/lib/module/components/Marker.types.js +4 -0
  68. package/lib/module/components/Marker.types.js.map +1 -0
  69. package/lib/module/components/Marker.web.js +159 -24
  70. package/lib/module/components/Marker.web.js.map +1 -1
  71. package/lib/module/components/Polygon.js +46 -0
  72. package/lib/module/components/Polygon.js.map +1 -0
  73. package/lib/module/components/Polygon.types.js +4 -0
  74. package/lib/module/components/Polygon.types.js.map +1 -0
  75. package/lib/module/components/Polygon.web.js +87 -0
  76. package/lib/module/components/Polygon.web.js.map +1 -0
  77. package/lib/module/components/Polyline.js +17 -4
  78. package/lib/module/components/Polyline.js.map +1 -1
  79. package/lib/module/components/Polyline.types.js +4 -0
  80. package/lib/module/components/Polyline.types.js.map +1 -0
  81. package/lib/module/components/Polyline.web.js +108 -31
  82. package/lib/module/components/Polyline.web.js.map +1 -1
  83. package/lib/module/components/index.js +4 -2
  84. package/lib/module/components/index.js.map +1 -1
  85. package/lib/module/components/index.web.js +2 -0
  86. package/lib/module/components/index.web.js.map +1 -1
  87. package/lib/module/fabric/LuggCalloutViewNativeComponent.ts +20 -0
  88. package/lib/module/fabric/{LuggGoogleMapViewNativeComponent.ts → LuggMapViewNativeComponent.ts} +43 -7
  89. package/lib/module/fabric/LuggMarkerViewNativeComponent.ts +49 -1
  90. package/lib/module/fabric/LuggPolygonViewNativeComponent.ts +25 -0
  91. package/lib/module/fabric/LuggPolylineViewNativeComponent.ts +8 -0
  92. package/lib/module/index.js +4 -1
  93. package/lib/module/index.js.map +1 -1
  94. package/lib/module/index.web.js +4 -1
  95. package/lib/module/index.web.js.map +1 -1
  96. package/lib/typescript/src/MapProvider.d.ts +1 -1
  97. package/lib/typescript/src/MapProvider.d.ts.map +1 -1
  98. package/lib/typescript/src/MapProvider.web.d.ts +23 -1
  99. package/lib/typescript/src/MapProvider.web.d.ts.map +1 -1
  100. package/lib/typescript/src/MapView.d.ts +4 -4
  101. package/lib/typescript/src/MapView.d.ts.map +1 -1
  102. package/lib/typescript/src/MapView.types.d.ts +35 -9
  103. package/lib/typescript/src/MapView.types.d.ts.map +1 -1
  104. package/lib/typescript/src/MapView.web.d.ts +2 -11
  105. package/lib/typescript/src/MapView.web.d.ts.map +1 -1
  106. package/lib/typescript/src/components/GeoJson.d.ts +4 -0
  107. package/lib/typescript/src/components/GeoJson.d.ts.map +1 -0
  108. package/lib/typescript/src/components/GeoJson.types.d.ts +89 -0
  109. package/lib/typescript/src/components/GeoJson.types.d.ts.map +1 -0
  110. package/lib/typescript/src/components/Marker.d.ts +6 -33
  111. package/lib/typescript/src/components/Marker.d.ts.map +1 -1
  112. package/lib/typescript/src/components/Marker.types.d.ts +100 -0
  113. package/lib/typescript/src/components/Marker.types.d.ts.map +1 -0
  114. package/lib/typescript/src/components/Marker.web.d.ts +2 -5
  115. package/lib/typescript/src/components/Marker.web.d.ts.map +1 -1
  116. package/lib/typescript/src/components/Polygon.d.ts +10 -0
  117. package/lib/typescript/src/components/Polygon.d.ts.map +1 -0
  118. package/lib/typescript/src/components/Polygon.types.d.ts +33 -0
  119. package/lib/typescript/src/components/Polygon.types.d.ts.map +1 -0
  120. package/lib/typescript/src/components/Polygon.web.d.ts +3 -0
  121. package/lib/typescript/src/components/Polygon.web.d.ts.map +1 -0
  122. package/lib/typescript/src/components/Polyline.d.ts +6 -21
  123. package/lib/typescript/src/components/Polyline.d.ts.map +1 -1
  124. package/lib/typescript/src/components/Polyline.types.d.ts +53 -0
  125. package/lib/typescript/src/components/Polyline.types.d.ts.map +1 -0
  126. package/lib/typescript/src/components/Polyline.web.d.ts +2 -5
  127. package/lib/typescript/src/components/Polyline.web.d.ts.map +1 -1
  128. package/lib/typescript/src/components/index.d.ts +8 -2
  129. package/lib/typescript/src/components/index.d.ts.map +1 -1
  130. package/lib/typescript/src/components/index.web.d.ts +6 -2
  131. package/lib/typescript/src/components/index.web.d.ts.map +1 -1
  132. package/lib/typescript/src/fabric/LuggCalloutViewNativeComponent.d.ts +13 -0
  133. package/lib/typescript/src/fabric/LuggCalloutViewNativeComponent.d.ts.map +1 -0
  134. package/lib/typescript/src/fabric/{LuggGoogleMapViewNativeComponent.d.ts → LuggMapViewNativeComponent.d.ts} +30 -4
  135. package/lib/typescript/src/fabric/LuggMapViewNativeComponent.d.ts.map +1 -0
  136. package/lib/typescript/src/fabric/LuggMarkerViewNativeComponent.d.ts +45 -1
  137. package/lib/typescript/src/fabric/LuggMarkerViewNativeComponent.d.ts.map +1 -1
  138. package/lib/typescript/src/fabric/LuggPolygonViewNativeComponent.d.ts +18 -0
  139. package/lib/typescript/src/fabric/LuggPolygonViewNativeComponent.d.ts.map +1 -0
  140. package/lib/typescript/src/fabric/LuggPolylineViewNativeComponent.d.ts +7 -0
  141. package/lib/typescript/src/fabric/LuggPolylineViewNativeComponent.d.ts.map +1 -1
  142. package/lib/typescript/src/index.d.ts +11 -3
  143. package/lib/typescript/src/index.d.ts.map +1 -1
  144. package/lib/typescript/src/index.web.d.ts +9 -1
  145. package/lib/typescript/src/index.web.d.ts.map +1 -1
  146. package/lib/typescript/src/types.d.ts +11 -0
  147. package/lib/typescript/src/types.d.ts.map +1 -1
  148. package/package.json +11 -9
  149. package/src/MapProvider.tsx +1 -3
  150. package/src/MapProvider.web.tsx +22 -3
  151. package/src/MapView.tsx +32 -26
  152. package/src/MapView.types.ts +43 -9
  153. package/src/MapView.web.tsx +368 -210
  154. package/src/components/GeoJson.tsx +221 -0
  155. package/src/components/GeoJson.types.ts +118 -0
  156. package/src/components/Marker.tsx +75 -38
  157. package/src/components/Marker.types.ts +102 -0
  158. package/src/components/Marker.web.tsx +197 -19
  159. package/src/components/Polygon.tsx +52 -0
  160. package/src/components/Polygon.types.ts +33 -0
  161. package/src/components/Polygon.web.tsx +104 -0
  162. package/src/components/Polyline.tsx +23 -22
  163. package/src/components/Polyline.types.ts +55 -0
  164. package/src/components/Polyline.web.tsx +151 -37
  165. package/src/components/index.ts +17 -2
  166. package/src/components/index.web.ts +6 -2
  167. package/src/fabric/LuggCalloutViewNativeComponent.ts +20 -0
  168. package/src/fabric/{LuggGoogleMapViewNativeComponent.ts → LuggMapViewNativeComponent.ts} +43 -7
  169. package/src/fabric/LuggMarkerViewNativeComponent.ts +49 -1
  170. package/src/fabric/LuggPolygonViewNativeComponent.ts +25 -0
  171. package/src/fabric/LuggPolylineViewNativeComponent.ts +8 -0
  172. package/src/index.ts +30 -1
  173. package/src/index.web.ts +16 -1
  174. package/src/types.ts +13 -0
  175. package/android/src/main/java/com/luggmaps/LuggGoogleMapView.kt +0 -511
  176. package/ios/LuggAppleMapView.h +0 -16
  177. package/ios/LuggAppleMapView.mm +0 -592
  178. package/ios/LuggGoogleMapView.h +0 -13
  179. package/ios/LuggGoogleMapView.mm +0 -455
  180. package/lib/module/fabric/LuggAppleMapViewNativeComponent.ts +0 -83
  181. package/lib/typescript/src/fabric/LuggAppleMapViewNativeComponent.d.ts +0 -54
  182. package/lib/typescript/src/fabric/LuggAppleMapViewNativeComponent.d.ts.map +0 -1
  183. package/lib/typescript/src/fabric/LuggGoogleMapViewNativeComponent.d.ts.map +0 -1
  184. package/src/fabric/LuggAppleMapViewNativeComponent.ts +0 -83
@@ -0,0 +1,221 @@
1
+ import React, { useMemo, type ReactElement } from 'react';
2
+ import type {
3
+ Feature,
4
+ FeatureCollection,
5
+ GeoJSON,
6
+ Geometry,
7
+ Position,
8
+ } from './GeoJson.types';
9
+ import type { Coordinate } from '../types';
10
+ import type { GeoJsonProps } from './GeoJson.types';
11
+ import { Marker } from './Marker';
12
+ import type { MarkerProps } from './Marker.types';
13
+ import { Polygon } from './Polygon';
14
+ import type { PolygonProps } from './Polygon.types';
15
+ import { Polyline } from './Polyline';
16
+ import type { PolylineProps } from './Polyline.types';
17
+
18
+ export type { GeoJsonProps } from './GeoJson.types';
19
+
20
+ const toCoordinate = (position: Position): Coordinate => ({
21
+ latitude: position[1],
22
+ longitude: position[0],
23
+ });
24
+
25
+ const toCoordinates = (positions: Position[]): Coordinate[] =>
26
+ positions.map(toCoordinate);
27
+
28
+ const normalizeFeatures = (geojson: GeoJSON): Feature[] => {
29
+ switch (geojson.type) {
30
+ case 'FeatureCollection':
31
+ return (geojson as FeatureCollection).features;
32
+ case 'Feature':
33
+ return [geojson as Feature];
34
+ default:
35
+ return [
36
+ { type: 'Feature', geometry: geojson as Geometry, properties: null },
37
+ ];
38
+ }
39
+ };
40
+
41
+ const renderGeometry = (
42
+ geometry: Geometry,
43
+ feature: Feature,
44
+ props: GeoJsonProps,
45
+ keyPrefix: string
46
+ ): ReactElement[] => {
47
+ const elements: ReactElement[] = [];
48
+
49
+ switch (geometry.type) {
50
+ case 'Point': {
51
+ const markerProps: MarkerProps = {
52
+ coordinate: toCoordinate(geometry.coordinates),
53
+ title: feature.properties?.title,
54
+ description: feature.properties?.description,
55
+ zIndex: props.zIndex,
56
+ };
57
+ elements.push(
58
+ props.renderMarker ? (
59
+ props.renderMarker(markerProps, feature) ?? (
60
+ <React.Fragment key={keyPrefix} />
61
+ )
62
+ ) : (
63
+ <Marker key={keyPrefix} {...markerProps} />
64
+ )
65
+ );
66
+ break;
67
+ }
68
+ case 'MultiPoint': {
69
+ for (let i = 0; i < geometry.coordinates.length; i++) {
70
+ const markerProps: MarkerProps = {
71
+ coordinate: toCoordinate(geometry.coordinates[i]!),
72
+ title: feature.properties?.title,
73
+ description: feature.properties?.description,
74
+ zIndex: props.zIndex,
75
+ };
76
+ const key = `${keyPrefix}-${i}`;
77
+ elements.push(
78
+ props.renderMarker ? (
79
+ props.renderMarker(markerProps, feature) ?? (
80
+ <React.Fragment key={key} />
81
+ )
82
+ ) : (
83
+ <Marker key={key} {...markerProps} />
84
+ )
85
+ );
86
+ }
87
+ break;
88
+ }
89
+ case 'LineString': {
90
+ const p = feature.properties;
91
+ const polylineProps: PolylineProps = {
92
+ coordinates: toCoordinates(geometry.coordinates),
93
+ strokeColors: p?.stroke ? [p.stroke] : undefined,
94
+ strokeWidth: p?.['stroke-width'],
95
+ zIndex: props.zIndex,
96
+ };
97
+ elements.push(
98
+ props.renderPolyline ? (
99
+ props.renderPolyline(polylineProps, feature) ?? (
100
+ <React.Fragment key={keyPrefix} />
101
+ )
102
+ ) : (
103
+ <Polyline key={keyPrefix} {...polylineProps} />
104
+ )
105
+ );
106
+ break;
107
+ }
108
+ case 'MultiLineString': {
109
+ const p = feature.properties;
110
+ for (let i = 0; i < geometry.coordinates.length; i++) {
111
+ const polylineProps: PolylineProps = {
112
+ coordinates: toCoordinates(geometry.coordinates[i]!),
113
+ strokeColors: p?.stroke ? [p.stroke] : undefined,
114
+ strokeWidth: p?.['stroke-width'],
115
+ zIndex: props.zIndex,
116
+ };
117
+ const key = `${keyPrefix}-${i}`;
118
+ elements.push(
119
+ props.renderPolyline ? (
120
+ props.renderPolyline(polylineProps, feature) ?? (
121
+ <React.Fragment key={key} />
122
+ )
123
+ ) : (
124
+ <Polyline key={key} {...polylineProps} />
125
+ )
126
+ );
127
+ }
128
+ break;
129
+ }
130
+ case 'Polygon': {
131
+ const outer = toCoordinates(geometry.coordinates[0]!);
132
+ const holes =
133
+ geometry.coordinates.length > 1
134
+ ? geometry.coordinates.slice(1).map(toCoordinates)
135
+ : undefined;
136
+ const p = feature.properties;
137
+ const polygonProps: PolygonProps = {
138
+ coordinates: outer,
139
+ holes,
140
+ fillColor: p?.fill,
141
+ strokeColor: p?.stroke,
142
+ strokeWidth: p?.['stroke-width'],
143
+ zIndex: props.zIndex,
144
+ };
145
+ elements.push(
146
+ props.renderPolygon ? (
147
+ props.renderPolygon(polygonProps, feature) ?? (
148
+ <React.Fragment key={keyPrefix} />
149
+ )
150
+ ) : (
151
+ <Polygon key={keyPrefix} {...polygonProps} />
152
+ )
153
+ );
154
+ break;
155
+ }
156
+ case 'MultiPolygon': {
157
+ const p = feature.properties;
158
+ for (let i = 0; i < geometry.coordinates.length; i++) {
159
+ const rings = geometry.coordinates[i]!;
160
+ const outer = toCoordinates(rings[0]!);
161
+ const holes =
162
+ rings.length > 1 ? rings.slice(1).map(toCoordinates) : undefined;
163
+ const polygonProps: PolygonProps = {
164
+ coordinates: outer,
165
+ holes,
166
+ fillColor: p?.fill,
167
+ strokeColor: p?.stroke,
168
+ strokeWidth: p?.['stroke-width'],
169
+ zIndex: props.zIndex,
170
+ };
171
+ const key = `${keyPrefix}-${i}`;
172
+ elements.push(
173
+ props.renderPolygon ? (
174
+ props.renderPolygon(polygonProps, feature) ?? (
175
+ <React.Fragment key={key} />
176
+ )
177
+ ) : (
178
+ <Polygon key={key} {...polygonProps} />
179
+ )
180
+ );
181
+ }
182
+ break;
183
+ }
184
+ case 'GeometryCollection': {
185
+ for (let i = 0; i < geometry.geometries.length; i++) {
186
+ elements.push(
187
+ ...renderGeometry(
188
+ geometry.geometries[i]!,
189
+ feature,
190
+ props,
191
+ `${keyPrefix}-${i}`
192
+ )
193
+ );
194
+ }
195
+ break;
196
+ }
197
+ }
198
+
199
+ return elements;
200
+ };
201
+
202
+ export const GeoJson = (props: GeoJsonProps) => {
203
+ const { geojson } = props;
204
+
205
+ const elements = useMemo(() => {
206
+ const features = normalizeFeatures(geojson);
207
+ const result: ReactElement[] = [];
208
+
209
+ for (let i = 0; i < features.length; i++) {
210
+ const feature = features[i]!;
211
+ if (!feature.geometry) continue;
212
+
213
+ const key = feature.id != null ? String(feature.id) : String(i);
214
+ result.push(...renderGeometry(feature.geometry, feature, props, key));
215
+ }
216
+
217
+ return result;
218
+ }, [geojson, props]);
219
+
220
+ return <>{elements}</>;
221
+ };
@@ -0,0 +1,118 @@
1
+ import type { ReactElement } from 'react';
2
+ import type { MarkerProps } from './Marker.types';
3
+ import type { PolygonProps } from './Polygon.types';
4
+ import type { PolylineProps } from './Polyline.types';
5
+
6
+ /**
7
+ * GeoJSON types per RFC 7946
8
+ * Note: GeoJSON positions use [longitude, latitude] order
9
+ */
10
+
11
+ export type Position =
12
+ | [longitude: number, latitude: number]
13
+ | [longitude: number, latitude: number, altitude: number];
14
+
15
+ export interface Point {
16
+ type: 'Point';
17
+ coordinates: Position;
18
+ }
19
+
20
+ export interface MultiPoint {
21
+ type: 'MultiPoint';
22
+ coordinates: Position[];
23
+ }
24
+
25
+ export interface LineString {
26
+ type: 'LineString';
27
+ coordinates: Position[];
28
+ }
29
+
30
+ export interface MultiLineString {
31
+ type: 'MultiLineString';
32
+ coordinates: Position[][];
33
+ }
34
+
35
+ export interface Polygon {
36
+ type: 'Polygon';
37
+ coordinates: Position[][];
38
+ }
39
+
40
+ export interface MultiPolygon {
41
+ type: 'MultiPolygon';
42
+ coordinates: Position[][][];
43
+ }
44
+
45
+ export interface GeometryCollection {
46
+ type: 'GeometryCollection';
47
+ geometries: Geometry[];
48
+ }
49
+
50
+ export type Geometry =
51
+ | Point
52
+ | MultiPoint
53
+ | LineString
54
+ | MultiLineString
55
+ | Polygon
56
+ | MultiPolygon
57
+ | GeometryCollection;
58
+
59
+ export interface FeatureProperties {
60
+ 'title'?: string;
61
+ 'description'?: string;
62
+ 'fill'?: string;
63
+ 'fill-opacity'?: number;
64
+ 'stroke'?: string;
65
+ 'stroke-width'?: number;
66
+ 'stroke-opacity'?: number;
67
+ [key: string]: unknown;
68
+ }
69
+
70
+ export interface Feature<G extends Geometry = Geometry> {
71
+ type: 'Feature';
72
+ id?: string | number;
73
+ geometry: G;
74
+ properties: FeatureProperties | null;
75
+ }
76
+
77
+ export interface FeatureCollection<G extends Geometry = Geometry> {
78
+ type: 'FeatureCollection';
79
+ features: Feature<G>[];
80
+ }
81
+
82
+ export type GeoJSON = Geometry | Feature | FeatureCollection;
83
+
84
+ export interface GeoJsonProps {
85
+ /**
86
+ * GeoJSON data to render.
87
+ * Accepts a `FeatureCollection`, `Feature`, or bare `Geometry`.
88
+ */
89
+ geojson: GeoJSON;
90
+ /**
91
+ * Z-index for all rendered features.
92
+ */
93
+ zIndex?: number;
94
+ /**
95
+ * Custom render function for `Point`/`MultiPoint` features.
96
+ * @param props - Default `MarkerProps` derived from the geometry.
97
+ * @param feature - The source GeoJSON `Feature`.
98
+ */
99
+ renderMarker?: (props: MarkerProps, feature: Feature) => ReactElement | null;
100
+ /**
101
+ * Custom render function for `LineString`/`MultiLineString` features.
102
+ * @param props - Default `PolylineProps` derived from the geometry.
103
+ * @param feature - The source GeoJSON `Feature`.
104
+ */
105
+ renderPolyline?: (
106
+ props: PolylineProps,
107
+ feature: Feature
108
+ ) => ReactElement | null;
109
+ /**
110
+ * Custom render function for `Polygon`/`MultiPolygon` features.
111
+ * @param props - Default `PolygonProps` derived from the geometry.
112
+ * @param feature - The source GeoJSON `Feature`.
113
+ */
114
+ renderPolygon?: (
115
+ props: PolygonProps,
116
+ feature: Feature
117
+ ) => ReactElement | null;
118
+ }
@@ -1,55 +1,85 @@
1
- import React from 'react';
2
- import type { ReactNode } from 'react';
1
+ import React, { isValidElement } from 'react';
3
2
  import { StyleSheet } from 'react-native';
4
3
  import LuggMarkerViewNativeComponent from '../fabric/LuggMarkerViewNativeComponent';
5
- import type { Coordinate, Point } from '../types';
6
-
7
- export interface MarkerProps {
8
- /**
9
- * Name used for debugging purposes
10
- */
11
- name?: string;
12
- /**
13
- * Marker position
14
- */
15
- coordinate: Coordinate;
16
- /**
17
- * Callout title
18
- */
19
- title?: string;
20
- /**
21
- * Callout description
22
- */
23
- description?: string;
24
- /**
25
- * Anchor point for custom marker views
26
- */
27
- anchor?: Point;
28
- /**
29
- * Z-index for marker ordering. Higher values render on top.
30
- */
31
- zIndex?: number;
32
- /**
33
- * Custom marker view
34
- */
35
- children?: ReactNode;
36
- }
4
+ import LuggCalloutViewNativeComponent from '../fabric/LuggCalloutViewNativeComponent';
5
+ import type { MarkerProps } from './Marker.types';
6
+
7
+ export type {
8
+ CalloutOptions,
9
+ MarkerProps,
10
+ MarkerPressEvent,
11
+ MarkerDragEvent,
12
+ } from './Marker.types';
13
+
14
+ export class Marker extends React.PureComponent<MarkerProps> {
15
+ private getStyle(zIndex: number | undefined) {
16
+ if (zIndex == null) return styles.marker;
17
+ if (zIndex !== this._cachedZIndex) {
18
+ this._cachedZIndex = zIndex;
19
+ this._cachedStyle = [{ zIndex }, styles.marker];
20
+ }
21
+ return this._cachedStyle!;
22
+ }
23
+
24
+ private _cachedZIndex: number | undefined;
25
+ private _cachedStyle: any;
37
26
 
38
- export class Marker extends React.Component<MarkerProps> {
39
27
  render() {
40
- const { name, coordinate, title, description, anchor, zIndex, children } =
41
- this.props;
28
+ const {
29
+ name,
30
+ coordinate,
31
+ title,
32
+ description,
33
+ anchor,
34
+ zIndex,
35
+ rotate = 0,
36
+ scale = 1,
37
+ rasterize = true,
38
+ draggable = false,
39
+ onPress,
40
+ onDragStart,
41
+ onDragChange,
42
+ onDragEnd,
43
+ callout,
44
+ calloutOptions,
45
+ children,
46
+ } = this.props;
47
+
48
+ const calloutContent = callout
49
+ ? isValidElement(callout)
50
+ ? callout
51
+ : React.createElement(callout)
52
+ : null;
53
+ const calloutBubbled = calloutOptions?.bubbled ?? true;
54
+ const calloutAnchor = calloutOptions?.anchor;
42
55
 
43
56
  return (
44
57
  <LuggMarkerViewNativeComponent
45
- style={[{ zIndex }, styles.marker]}
58
+ style={this.getStyle(zIndex)}
46
59
  name={name}
47
60
  coordinate={coordinate}
48
61
  title={title}
49
62
  description={description}
50
63
  anchor={anchor}
64
+ rotate={rotate}
65
+ scale={scale}
66
+ rasterize={rasterize}
67
+ draggable={draggable}
68
+ onMarkerPress={onPress}
69
+ onMarkerDragStart={onDragStart}
70
+ onMarkerDragChange={onDragChange}
71
+ onMarkerDragEnd={onDragEnd}
51
72
  >
52
73
  {children}
74
+ {calloutContent && (
75
+ <LuggCalloutViewNativeComponent
76
+ style={calloutStyles.callout}
77
+ bubbled={calloutBubbled}
78
+ anchor={calloutAnchor}
79
+ >
80
+ {calloutContent}
81
+ </LuggCalloutViewNativeComponent>
82
+ )}
53
83
  </LuggMarkerViewNativeComponent>
54
84
  );
55
85
  }
@@ -61,3 +91,10 @@ const styles = StyleSheet.create({
61
91
  pointerEvents: 'box-none',
62
92
  },
63
93
  });
94
+
95
+ const calloutStyles = StyleSheet.create({
96
+ callout: {
97
+ position: 'absolute',
98
+ pointerEvents: 'box-none',
99
+ },
100
+ });
@@ -0,0 +1,102 @@
1
+ import type { ComponentType, ReactElement, ReactNode } from 'react';
2
+ import type { NativeSyntheticEvent } from 'react-native';
3
+ import type { Coordinate, Point, PressEventPayload } from '../types';
4
+
5
+ export type MarkerPressEvent = NativeSyntheticEvent<PressEventPayload>;
6
+ export type MarkerDragEvent = NativeSyntheticEvent<PressEventPayload>;
7
+
8
+ export interface CalloutOptions {
9
+ /**
10
+ * Whether to wrap the callout in the native platform bubble.
11
+ * Set to `false` to render custom content directly without the native callout chrome.
12
+ *
13
+ * @default true
14
+ */
15
+ bubbled?: boolean;
16
+ /**
17
+ * Anchor point for the callout relative to the marker position.
18
+ * `{x: 0.5, y: 1}` places the bottom-center of the callout at the marker.
19
+ *
20
+ * @note Not supported on web.
21
+ * @default {x: 0.5, y: 1}
22
+ */
23
+ anchor?: Point;
24
+ }
25
+
26
+ export interface MarkerProps {
27
+ /**
28
+ * Name used for debugging purposes
29
+ */
30
+ name?: string;
31
+ /**
32
+ * Marker position
33
+ */
34
+ coordinate: Coordinate;
35
+ /**
36
+ * Callout title
37
+ */
38
+ title?: string;
39
+ /**
40
+ * Callout description
41
+ */
42
+ description?: string;
43
+ /**
44
+ * Anchor point for custom marker views
45
+ */
46
+ anchor?: Point;
47
+ /**
48
+ * Z-index for marker ordering. Higher values render on top.
49
+ */
50
+ zIndex?: number;
51
+ /**
52
+ * Rotation angle in degrees clockwise from north.
53
+ * @default 0
54
+ */
55
+ rotate?: number;
56
+ /**
57
+ * Scale factor for the marker.
58
+ * @default 1
59
+ */
60
+ scale?: number;
61
+ /**
62
+ * Rasterize custom marker view to bitmap for better performance.
63
+ * Set to false if you need live view updates (e.g., animations).
64
+ * @platform ios, android
65
+ * @default true
66
+ */
67
+ rasterize?: boolean;
68
+ /**
69
+ * Whether the marker can be dragged by the user.
70
+ * @default false
71
+ */
72
+ draggable?: boolean;
73
+ /**
74
+ * Called when the marker is pressed
75
+ */
76
+ onPress?: (event: MarkerPressEvent) => void;
77
+ /**
78
+ * Called when marker drag starts
79
+ */
80
+ onDragStart?: (event: MarkerDragEvent) => void;
81
+ /**
82
+ * Called continuously as the marker is dragged
83
+ */
84
+ onDragChange?: (event: MarkerDragEvent) => void;
85
+ /**
86
+ * Called when marker drag ends
87
+ */
88
+ onDragEnd?: (event: MarkerDragEvent) => void;
89
+ /**
90
+ * Callout content displayed when marker is tapped.
91
+ * Pass a `ReactElement` for inline content or a `ComponentType` to be instantiated.
92
+ */
93
+ callout?: ComponentType<unknown> | ReactElement;
94
+ /**
95
+ * Callout configuration options.
96
+ */
97
+ calloutOptions?: CalloutOptions;
98
+ /**
99
+ * Custom marker view
100
+ */
101
+ children?: ReactNode;
102
+ }