@lugg/maps 0.2.0-alpha.21 → 0.2.0-alpha.23

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 (45) hide show
  1. package/README.md +5 -0
  2. package/android/src/main/java/com/luggmaps/LuggMapView.kt +201 -0
  3. package/android/src/main/java/com/luggmaps/{LuggGoogleMapViewManager.kt → LuggMapViewManager.kt} +39 -29
  4. package/android/src/main/java/com/luggmaps/LuggPackage.kt +1 -4
  5. package/android/src/main/java/com/luggmaps/{LuggGoogleMapView.kt → core/GoogleMapProvider.kt} +174 -189
  6. package/android/src/main/java/com/luggmaps/core/MapProviderDelegate.kt +51 -0
  7. package/android/src/main/java/com/luggmaps/core/PolylineAnimator.kt +28 -24
  8. package/ios/LuggMapView.h +9 -0
  9. package/ios/LuggMapView.mm +303 -0
  10. package/ios/core/AppleMapProvider.h +15 -0
  11. package/ios/{LuggAppleMapView.mm → core/AppleMapProvider.mm} +317 -410
  12. package/ios/core/GMSPolylineAnimator.m +16 -4
  13. package/ios/core/GoogleMapProvider.h +13 -0
  14. package/ios/{LuggGoogleMapView.mm → core/GoogleMapProvider.mm} +179 -218
  15. package/ios/core/MapProviderDelegate.h +68 -0
  16. package/lib/module/MapView.js +9 -12
  17. package/lib/module/MapView.js.map +1 -1
  18. package/lib/module/MapView.web.js +4 -1
  19. package/lib/module/MapView.web.js.map +1 -1
  20. package/lib/module/fabric/{LuggGoogleMapViewNativeComponent.ts → LuggMapViewNativeComponent.ts} +4 -1
  21. package/lib/typescript/src/MapView.d.ts +0 -1
  22. package/lib/typescript/src/MapView.d.ts.map +1 -1
  23. package/lib/typescript/src/MapView.types.d.ts +6 -1
  24. package/lib/typescript/src/MapView.types.d.ts.map +1 -1
  25. package/lib/typescript/src/MapView.web.d.ts.map +1 -1
  26. package/lib/typescript/src/fabric/{LuggGoogleMapViewNativeComponent.d.ts → LuggMapViewNativeComponent.d.ts} +4 -2
  27. package/lib/typescript/src/fabric/LuggMapViewNativeComponent.d.ts.map +1 -0
  28. package/lib/typescript/src/index.d.ts +1 -1
  29. package/lib/typescript/src/index.d.ts.map +1 -1
  30. package/lib/typescript/src/types.d.ts +4 -0
  31. package/lib/typescript/src/types.d.ts.map +1 -1
  32. package/package.json +5 -3
  33. package/src/MapView.tsx +11 -21
  34. package/src/MapView.types.ts +6 -1
  35. package/src/MapView.web.tsx +10 -0
  36. package/src/fabric/{LuggGoogleMapViewNativeComponent.ts → LuggMapViewNativeComponent.ts} +4 -1
  37. package/src/index.ts +1 -0
  38. package/src/types.ts +5 -0
  39. package/ios/LuggAppleMapView.h +0 -16
  40. package/ios/LuggGoogleMapView.h +0 -13
  41. package/lib/module/fabric/LuggAppleMapViewNativeComponent.ts +0 -83
  42. package/lib/typescript/src/fabric/LuggAppleMapViewNativeComponent.d.ts +0 -54
  43. package/lib/typescript/src/fabric/LuggAppleMapViewNativeComponent.d.ts.map +0 -1
  44. package/lib/typescript/src/fabric/LuggGoogleMapViewNativeComponent.d.ts.map +0 -1
  45. package/src/fabric/LuggAppleMapViewNativeComponent.ts +0 -83
package/README.md CHANGED
@@ -2,6 +2,11 @@
2
2
 
3
3
  Universal maps for your React Native apps 📍
4
4
 
5
+ <img alt="@lugg/maps" src="docs/preview.gif" width="720" />
6
+
7
+ > [!IMPORTANT]
8
+ > This library is currently under heavy development. APIs may change without notice.
9
+
5
10
  ## Installation
6
11
 
7
12
  ```sh
@@ -0,0 +1,201 @@
1
+ package com.luggmaps
2
+
3
+ import android.annotation.SuppressLint
4
+ import android.view.View
5
+ import android.view.View.VISIBLE
6
+ import com.facebook.react.uimanager.ThemedReactContext
7
+ import com.facebook.react.views.view.ReactViewGroup
8
+ import com.google.android.gms.maps.model.LatLng
9
+ import com.luggmaps.core.GoogleMapProvider
10
+ import com.luggmaps.core.MapProvider
11
+ import com.luggmaps.core.MapProviderDelegate
12
+
13
+ interface LuggMapViewEventDelegate {
14
+ fun onCameraMove(
15
+ view: LuggMapView,
16
+ latitude: Double,
17
+ longitude: Double,
18
+ zoom: Float,
19
+ gesture: Boolean
20
+ )
21
+ fun onCameraIdle(
22
+ view: LuggMapView,
23
+ latitude: Double,
24
+ longitude: Double,
25
+ zoom: Float,
26
+ gesture: Boolean
27
+ )
28
+ fun onReady(view: LuggMapView)
29
+ }
30
+
31
+ @SuppressLint("ViewConstructor")
32
+ class LuggMapView(private val reactContext: ThemedReactContext) :
33
+ ReactViewGroup(reactContext),
34
+ MapProviderDelegate {
35
+
36
+ var eventDelegate: LuggMapViewEventDelegate? = null
37
+ private var provider: MapProvider? = null
38
+ private var mapWrapperView: LuggMapWrapperView? = null
39
+
40
+ // Cached initial props
41
+ private var mapId: String = GoogleMapProvider.DEMO_MAP_ID
42
+ private var initialLatitude: Double = 37.78
43
+ private var initialLongitude: Double = -122.43
44
+ private var initialZoom: Float = 14f
45
+
46
+ // region View Lifecycle
47
+
48
+ override fun addView(child: View?, index: Int) {
49
+ super.addView(child, index)
50
+ when (child) {
51
+ is LuggMapWrapperView -> mapWrapperView = child
52
+ is LuggMarkerView -> provider?.addMarkerView(child)
53
+ is LuggPolylineView -> provider?.addPolylineView(child)
54
+ }
55
+ }
56
+
57
+ override fun removeViewAt(index: Int) {
58
+ val view = getChildAt(index)
59
+ when (view) {
60
+ is LuggMarkerView -> provider?.removeMarkerView(view)
61
+ is LuggPolylineView -> provider?.removePolylineView(view)
62
+ }
63
+ super.removeViewAt(index)
64
+ }
65
+
66
+ override fun onAttachedToWindow() {
67
+ super.onAttachedToWindow()
68
+ if (provider == null && mapWrapperView != null) {
69
+ initializeProvider()
70
+ }
71
+ }
72
+
73
+ override fun onWindowVisibilityChanged(visibility: Int) {
74
+ super.onWindowVisibilityChanged(visibility)
75
+ if (visibility == VISIBLE) {
76
+ provider?.resumeAnimations()
77
+ } else {
78
+ provider?.pauseAnimations()
79
+ }
80
+ }
81
+
82
+ fun onDropViewInstance() {
83
+ provider?.destroy()
84
+ provider = null
85
+ mapWrapperView = null
86
+ }
87
+
88
+ // endregion
89
+
90
+ // region Provider Initialization
91
+
92
+ private fun initializeProvider() {
93
+ if (provider != null || mapWrapperView == null) return
94
+
95
+ val google = GoogleMapProvider(context)
96
+ google.mapId = mapId
97
+ google.delegate = this
98
+ provider = google
99
+
100
+ google.initializeMap(mapWrapperView!!, initialLatitude, initialLongitude, initialZoom)
101
+
102
+ // Flush children mounted before provider was created
103
+ for (i in 0 until childCount) {
104
+ when (val child = getChildAt(i)) {
105
+ is LuggMarkerView -> google.addMarkerView(child)
106
+ is LuggPolylineView -> google.addPolylineView(child)
107
+ }
108
+ }
109
+ }
110
+
111
+ // endregion
112
+
113
+ // region MapProviderDelegate
114
+
115
+ override fun mapProviderDidReady() {
116
+ eventDelegate?.onReady(this)
117
+ }
118
+
119
+ override fun mapProviderDidMoveCamera(latitude: Double, longitude: Double, zoom: Float, gesture: Boolean) {
120
+ eventDelegate?.onCameraMove(this, latitude, longitude, zoom, gesture)
121
+ }
122
+
123
+ override fun mapProviderDidIdleCamera(latitude: Double, longitude: Double, zoom: Float, gesture: Boolean) {
124
+ eventDelegate?.onCameraIdle(this, latitude, longitude, zoom, gesture)
125
+ }
126
+
127
+ // endregion
128
+
129
+ // region Property Setters
130
+
131
+ fun setMapId(value: String?) {
132
+ if (value.isNullOrEmpty()) return
133
+ mapId = value
134
+ }
135
+
136
+ fun setInitialCoordinate(latitude: Double, longitude: Double) {
137
+ initialLatitude = latitude
138
+ initialLongitude = longitude
139
+ }
140
+
141
+ fun setInitialZoom(zoom: Double) {
142
+ initialZoom = zoom.toFloat()
143
+ }
144
+
145
+ fun setZoomEnabled(enabled: Boolean) {
146
+ provider?.setZoomEnabled(enabled)
147
+ }
148
+
149
+ fun setScrollEnabled(enabled: Boolean) {
150
+ provider?.setScrollEnabled(enabled)
151
+ }
152
+
153
+ fun setRotateEnabled(enabled: Boolean) {
154
+ provider?.setRotateEnabled(enabled)
155
+ }
156
+
157
+ fun setPitchEnabled(enabled: Boolean) {
158
+ provider?.setPitchEnabled(enabled)
159
+ }
160
+
161
+ fun setUserLocationEnabled(enabled: Boolean) {
162
+ provider?.setUserLocationEnabled(enabled)
163
+ }
164
+
165
+ fun setMinZoom(zoom: Double) {
166
+ provider?.setMinZoom(zoom)
167
+ }
168
+
169
+ fun setMaxZoom(zoom: Double) {
170
+ provider?.setMaxZoom(zoom)
171
+ }
172
+
173
+ fun setTheme(value: String) {
174
+ provider?.setTheme(value)
175
+ }
176
+
177
+ fun setMapPadding(top: Int, left: Int, bottom: Int, right: Int) {
178
+ provider?.setMapPadding(top, left, bottom, right)
179
+ }
180
+
181
+ // endregion
182
+
183
+ // region Commands
184
+
185
+ fun moveCamera(latitude: Double, longitude: Double, zoom: Double, duration: Int) {
186
+ provider?.moveCamera(latitude, longitude, zoom, duration)
187
+ }
188
+
189
+ fun fitCoordinates(
190
+ coordinates: List<LatLng>,
191
+ paddingTop: Int,
192
+ paddingLeft: Int,
193
+ paddingBottom: Int,
194
+ paddingRight: Int,
195
+ duration: Int
196
+ ) {
197
+ provider?.fitCoordinates(coordinates, paddingTop, paddingLeft, paddingBottom, paddingRight, duration)
198
+ }
199
+
200
+ // endregion
201
+ }
@@ -8,27 +8,27 @@ import com.facebook.react.uimanager.ThemedReactContext
8
8
  import com.facebook.react.uimanager.ViewGroupManager
9
9
  import com.facebook.react.uimanager.ViewManagerDelegate
10
10
  import com.facebook.react.uimanager.annotations.ReactProp
11
- import com.facebook.react.viewmanagers.LuggGoogleMapViewManagerDelegate
12
- import com.facebook.react.viewmanagers.LuggGoogleMapViewManagerInterface
11
+ import com.facebook.react.viewmanagers.LuggMapViewManagerDelegate
12
+ import com.facebook.react.viewmanagers.LuggMapViewManagerInterface
13
13
  import com.google.android.gms.maps.model.LatLng
14
14
  import com.luggmaps.events.CameraIdleEvent
15
15
  import com.luggmaps.events.CameraMoveEvent
16
16
  import com.luggmaps.events.ReadyEvent
17
17
  import com.luggmaps.extensions.dispatchEvent
18
18
 
19
- @ReactModule(name = LuggGoogleMapViewManager.NAME)
20
- class LuggGoogleMapViewManager :
21
- ViewGroupManager<LuggGoogleMapView>(),
22
- LuggGoogleMapViewManagerInterface<LuggGoogleMapView>,
23
- LuggGoogleMapViewEventDelegate {
24
- private val delegate: ViewManagerDelegate<LuggGoogleMapView> = LuggGoogleMapViewManagerDelegate(this)
19
+ @ReactModule(name = LuggMapViewManager.NAME)
20
+ class LuggMapViewManager :
21
+ ViewGroupManager<LuggMapView>(),
22
+ LuggMapViewManagerInterface<LuggMapView>,
23
+ LuggMapViewEventDelegate {
24
+ private val delegate: ViewManagerDelegate<LuggMapView> = LuggMapViewManagerDelegate(this)
25
25
 
26
- override fun getDelegate(): ViewManagerDelegate<LuggGoogleMapView> = delegate
26
+ override fun getDelegate(): ViewManagerDelegate<LuggMapView> = delegate
27
27
 
28
28
  override fun getName(): String = NAME
29
29
 
30
- override fun createViewInstance(context: ThemedReactContext): LuggGoogleMapView {
31
- val view = LuggGoogleMapView(context)
30
+ override fun createViewInstance(context: ThemedReactContext): LuggMapView {
31
+ val view = LuggMapView(context)
32
32
  view.eventDelegate = this
33
33
  return view
34
34
  }
@@ -41,7 +41,7 @@ class LuggGoogleMapViewManager :
41
41
  )
42
42
 
43
43
  override fun onCameraMove(
44
- view: LuggGoogleMapView,
44
+ view: LuggMapView,
45
45
  latitude: Double,
46
46
  longitude: Double,
47
47
  zoom: Float,
@@ -51,7 +51,7 @@ class LuggGoogleMapViewManager :
51
51
  }
52
52
 
53
53
  override fun onCameraIdle(
54
- view: LuggGoogleMapView,
54
+ view: LuggMapView,
55
55
  latitude: Double,
56
56
  longitude: Double,
57
57
  zoom: Float,
@@ -60,17 +60,22 @@ class LuggGoogleMapViewManager :
60
60
  view.dispatchEvent(CameraIdleEvent(view, latitude, longitude, zoom, gesture))
61
61
  }
62
62
 
63
- override fun onReady(view: LuggGoogleMapView) {
63
+ override fun onReady(view: LuggMapView) {
64
64
  view.dispatchEvent(ReadyEvent(view))
65
65
  }
66
66
 
67
+ @ReactProp(name = "provider")
68
+ override fun setProvider(view: LuggMapView, value: String?) {
69
+ // No-op on Android — always Google Maps
70
+ }
71
+
67
72
  @ReactProp(name = "mapId")
68
- override fun setMapId(view: LuggGoogleMapView, value: String?) {
73
+ override fun setMapId(view: LuggMapView, value: String?) {
69
74
  view.setMapId(value)
70
75
  }
71
76
 
72
77
  @ReactProp(name = "initialCoordinate")
73
- override fun setInitialCoordinate(view: LuggGoogleMapView, value: ReadableMap?) {
78
+ override fun setInitialCoordinate(view: LuggMapView, value: ReadableMap?) {
74
79
  value?.let {
75
80
  val latitude = if (it.hasKey("latitude")) it.getDouble("latitude") else 0.0
76
81
  val longitude = if (it.hasKey("longitude")) it.getDouble("longitude") else 0.0
@@ -79,47 +84,52 @@ class LuggGoogleMapViewManager :
79
84
  }
80
85
 
81
86
  @ReactProp(name = "initialZoom", defaultDouble = 10.0)
82
- override fun setInitialZoom(view: LuggGoogleMapView, value: Double) {
87
+ override fun setInitialZoom(view: LuggMapView, value: Double) {
83
88
  view.setInitialZoom(value)
84
89
  }
85
90
 
86
91
  @ReactProp(name = "zoomEnabled", defaultBoolean = true)
87
- override fun setZoomEnabled(view: LuggGoogleMapView, value: Boolean) {
92
+ override fun setZoomEnabled(view: LuggMapView, value: Boolean) {
88
93
  view.setZoomEnabled(value)
89
94
  }
90
95
 
91
96
  @ReactProp(name = "scrollEnabled", defaultBoolean = true)
92
- override fun setScrollEnabled(view: LuggGoogleMapView, value: Boolean) {
97
+ override fun setScrollEnabled(view: LuggMapView, value: Boolean) {
93
98
  view.setScrollEnabled(value)
94
99
  }
95
100
 
96
101
  @ReactProp(name = "rotateEnabled", defaultBoolean = true)
97
- override fun setRotateEnabled(view: LuggGoogleMapView, value: Boolean) {
102
+ override fun setRotateEnabled(view: LuggMapView, value: Boolean) {
98
103
  view.setRotateEnabled(value)
99
104
  }
100
105
 
101
106
  @ReactProp(name = "pitchEnabled", defaultBoolean = true)
102
- override fun setPitchEnabled(view: LuggGoogleMapView, value: Boolean) {
107
+ override fun setPitchEnabled(view: LuggMapView, value: Boolean) {
103
108
  view.setPitchEnabled(value)
104
109
  }
105
110
 
106
111
  @ReactProp(name = "userLocationEnabled", defaultBoolean = false)
107
- override fun setUserLocationEnabled(view: LuggGoogleMapView, value: Boolean) {
112
+ override fun setUserLocationEnabled(view: LuggMapView, value: Boolean) {
108
113
  view.setUserLocationEnabled(value)
109
114
  }
110
115
 
111
116
  @ReactProp(name = "minZoom")
112
- override fun setMinZoom(view: LuggGoogleMapView, value: Double) {
117
+ override fun setMinZoom(view: LuggMapView, value: Double) {
113
118
  view.setMinZoom(value)
114
119
  }
115
120
 
116
121
  @ReactProp(name = "maxZoom")
117
- override fun setMaxZoom(view: LuggGoogleMapView, value: Double) {
122
+ override fun setMaxZoom(view: LuggMapView, value: Double) {
118
123
  view.setMaxZoom(value)
119
124
  }
120
125
 
126
+ @ReactProp(name = "theme")
127
+ override fun setTheme(view: LuggMapView, value: String?) {
128
+ view.setTheme(value ?: "system")
129
+ }
130
+
121
131
  @ReactProp(name = "padding")
122
- override fun setPadding(view: LuggGoogleMapView, value: ReadableMap?) {
132
+ override fun setPadding(view: LuggMapView, value: ReadableMap?) {
123
133
  value?.let {
124
134
  val top = if (it.hasKey("top")) it.getDouble("top").toFloat().dpToPx().toInt() else 0
125
135
  val left = if (it.hasKey("left")) it.getDouble("left").toFloat().dpToPx().toInt() else 0
@@ -129,13 +139,13 @@ class LuggGoogleMapViewManager :
129
139
  }
130
140
  }
131
141
 
132
- override fun onDropViewInstance(view: LuggGoogleMapView) {
142
+ override fun onDropViewInstance(view: LuggMapView) {
133
143
  super.onDropViewInstance(view)
134
144
  view.onDropViewInstance()
135
145
  }
136
146
 
137
147
  override fun moveCamera(
138
- view: LuggGoogleMapView,
148
+ view: LuggMapView,
139
149
  latitude: Double,
140
150
  longitude: Double,
141
151
  zoom: Double,
@@ -145,7 +155,7 @@ class LuggGoogleMapViewManager :
145
155
  }
146
156
 
147
157
  override fun fitCoordinates(
148
- view: LuggGoogleMapView,
158
+ view: LuggMapView,
149
159
  coordinates: ReadableArray?,
150
160
  paddingTop: Double,
151
161
  paddingLeft: Double,
@@ -166,6 +176,6 @@ class LuggGoogleMapViewManager :
166
176
  }
167
177
 
168
178
  companion object {
169
- const val NAME = "LuggGoogleMapView"
179
+ const val NAME = "LuggMapView"
170
180
  }
171
181
  }
@@ -1,13 +1,10 @@
1
1
  package com.luggmaps
2
2
 
3
3
  import com.facebook.react.ReactPackage
4
- import com.facebook.react.bridge.NativeModule
5
4
  import com.facebook.react.bridge.ReactApplicationContext
6
5
  import com.facebook.react.uimanager.ViewManager
7
6
 
8
7
  class LuggPackage : ReactPackage {
9
8
  override fun createViewManagers(reactContext: ReactApplicationContext): List<ViewManager<*, *>> =
10
- listOf(LuggGoogleMapViewManager(), LuggMarkerViewManager(), LuggMapWrapperViewManager(), LuggPolylineViewManager())
11
-
12
- override fun createNativeModules(reactContext: ReactApplicationContext): List<NativeModule> = emptyList()
9
+ listOf(LuggMapViewManager(), LuggMarkerViewManager(), LuggMapWrapperViewManager(), LuggPolylineViewManager())
13
10
  }