diff --git a/__tests__/interface.test.js b/__tests__/interface.test.js index d7e7299680..45b6ed7cee 100644 --- a/__tests__/interface.test.js +++ b/__tests__/interface.test.js @@ -9,6 +9,7 @@ describe('Public Interface', () => { 'StyleSheet', 'Light', 'PointAnnotation', + 'PointAnnotationManager', 'MarkerView', 'Annotation', 'Callout', diff --git a/android/src/main/java/com/rnmapbox/rnmbx/RNMBXPackage.kt b/android/src/main/java/com/rnmapbox/rnmbx/RNMBXPackage.kt index f82fadd32d..0b9bf05813 100644 --- a/android/src/main/java/com/rnmapbox/rnmbx/RNMBXPackage.kt +++ b/android/src/main/java/com/rnmapbox/rnmbx/RNMBXPackage.kt @@ -11,6 +11,7 @@ import com.rnmapbox.rnmbx.components.annotation.RNMBXCalloutManager import com.rnmapbox.rnmbx.components.annotation.RNMBXMarkerViewContentManager import com.rnmapbox.rnmbx.components.annotation.RNMBXMarkerViewManager import com.rnmapbox.rnmbx.components.annotation.RNMBXPointAnnotationManager +import com.rnmapbox.rnmbx.components.annotation.RNMBXPointAnnotationManagerViewManager import com.rnmapbox.rnmbx.components.annotation.RNMBXPointAnnotationModule import com.rnmapbox.rnmbx.components.camera.RNMBXCameraManager import com.rnmapbox.rnmbx.components.camera.RNMBXCameraModule @@ -135,6 +136,7 @@ class RNMBXPackage : TurboReactPackage() { managers.add(RNMBXMarkerViewManager(reactApplicationContext)) managers.add(RNMBXMarkerViewContentManager(reactApplicationContext)) managers.add(RNMBXPointAnnotationManager(reactApplicationContext, getViewTagResolver(reactApplicationContext, "RNMBXPointAnnotationManager"))) + managers.add(RNMBXPointAnnotationManagerViewManager(reactApplicationContext)) managers.add(RNMBXCalloutManager()) managers.add(RNMBXNativeUserLocationManager()) managers.add(RNMBXCustomLocationProviderManager()) diff --git a/android/src/main/java/com/rnmapbox/rnmbx/components/annotation/RNMBXPointAnnotationManagerView.kt b/android/src/main/java/com/rnmapbox/rnmbx/components/annotation/RNMBXPointAnnotationManagerView.kt new file mode 100644 index 0000000000..f97d17ef77 --- /dev/null +++ b/android/src/main/java/com/rnmapbox/rnmbx/components/annotation/RNMBXPointAnnotationManagerView.kt @@ -0,0 +1,26 @@ +package com.rnmapbox.rnmbx.components.annotation + +import android.content.Context +import com.rnmapbox.rnmbx.components.AbstractMapFeature +import com.rnmapbox.rnmbx.components.RemovalReason +import com.rnmapbox.rnmbx.components.mapview.RNMBXMapView + +class RNMBXPointAnnotationManagerView(context: Context) : AbstractMapFeature(context) { + var slot: String? = null + set(value) { + field = value + applySlot() + } + + private fun applySlot() { + withMapView { mapView -> + slot?.let { mapView.pointAnnotations?.manager?.slot = it } + ?: run { mapView.pointAnnotations?.manager?.slot = null } + } + } + + override fun addToMap(mapView: RNMBXMapView) { + super.addToMap(mapView) + applySlot() + } +} diff --git a/android/src/main/java/com/rnmapbox/rnmbx/components/annotation/RNMBXPointAnnotationManagerViewManager.kt b/android/src/main/java/com/rnmapbox/rnmbx/components/annotation/RNMBXPointAnnotationManagerViewManager.kt new file mode 100644 index 0000000000..b4edbb202b --- /dev/null +++ b/android/src/main/java/com/rnmapbox/rnmbx/components/annotation/RNMBXPointAnnotationManagerViewManager.kt @@ -0,0 +1,33 @@ +package com.rnmapbox.rnmbx.components.annotation + +import com.facebook.react.bridge.ReactApplicationContext +import com.facebook.react.common.MapBuilder +import com.facebook.react.uimanager.ThemedReactContext +import com.facebook.react.uimanager.annotations.ReactProp +import com.facebook.react.viewmanagers.RNMBXPointAnnotationManagerManagerInterface +import com.rnmapbox.rnmbx.components.AbstractEventEmitter + +class RNMBXPointAnnotationManagerViewManager(context: ReactApplicationContext) : + AbstractEventEmitter(context), + RNMBXPointAnnotationManagerManagerInterface { + override fun customEvents(): Map? { + return MapBuilder.builder().build() + } + + override fun getName(): String { + return REACT_CLASS + } + + override fun createViewInstance(context: ThemedReactContext): RNMBXPointAnnotationManagerView { + return RNMBXPointAnnotationManagerView(context) + } + + companion object { + const val REACT_CLASS = "RNMBXPointAnnotationManager" + } + + @ReactProp(name = "slot") + override fun setSlot(view: RNMBXPointAnnotationManagerView, value: String?) { + view.slot = value + } +} diff --git a/docs/docs.json b/docs/docs.json index 399a40f854..0074a55653 100644 --- a/docs/docs.json +++ b/docs/docs.json @@ -6529,6 +6529,30 @@ "relPath": "src/components/PointAnnotation.tsx", "name": "PointAnnotation" }, + "PointAnnotationManager": { + "description": "Configures the shared PointAnnotation manager for the parent MapView.\nWrap PointAnnotation components as children.", + "displayName": "PointAnnotationManager", + "methods": [], + "props": [ + { + "name": "slot", + "required": false, + "type": "'bottom' \\| 'middle' \\| 'top' \\| (string & {})", + "default": "none", + "description": "The slot in the style layer stack to position the annotation layer.\nUse with Mapbox Standard style to control layer ordering." + }, + { + "name": "children", + "required": false, + "type": "ReactNode", + "default": "none", + "description": "FIX ME NO DESCRIPTION" + } + ], + "fileNameWithExt": "PointAnnotationManager.tsx", + "relPath": "src/components/PointAnnotationManager.tsx", + "name": "PointAnnotationManager" + }, "Rain": { "description": "", "displayName": "Rain", diff --git a/example/src/examples/Annotations/PointAnnotationManagerSlot.tsx b/example/src/examples/Annotations/PointAnnotationManagerSlot.tsx new file mode 100644 index 0000000000..bfa5a4b2e6 --- /dev/null +++ b/example/src/examples/Annotations/PointAnnotationManagerSlot.tsx @@ -0,0 +1,91 @@ +import { useState } from 'react'; +import { View, Text, StyleSheet } from 'react-native'; +import { + Camera, + MapView, + PointAnnotation, + PointAnnotationManager, +} from '@rnmapbox/maps'; +import { Button } from '@rneui/base'; + +import { ExampleWithMetadata } from '../common/ExampleMetadata'; // exclude-from-doc + +const styles = StyleSheet.create({ + map: { flex: 1 }, + pin: { + width: 30, + height: 30, + borderRadius: 15, + justifyContent: 'center', + alignItems: 'center', + }, + label: { color: 'white', fontWeight: 'bold', fontSize: 12 }, + buttons: { + flexDirection: 'row', + justifyContent: 'center', + padding: 8, + gap: 8, + }, +}); + +const COORDS: [number, number][] = [ + [-74.00597, 40.71427], + [-74.0065, 40.7128], + [-74.0045, 40.7155], +]; + +const PointAnnotationManagerSlot = () => { + const [slot, setSlot] = useState('middle'); + + return ( + <> + + + + {COORDS.map((coord, i) => ( + + + {i + 1} + + + ))} + + + +