From 6a05b34560661c1c76f4d623d384f6a88a520461 Mon Sep 17 00:00:00 2001 From: Muhammad Saqlain Date: Thu, 12 Jun 2025 19:45:39 +0500 Subject: [PATCH] Added support to set style value of specific layer --- .../components/mapview/NativeMapViewModule.kt | 14 ++++++++ .../rnmbx/components/mapview/RNMBXMapView.kt | 35 ++++++++++++++++++ .../rnmbx/NativeMapViewModuleSpec.java | 4 +++ docs/MapView.md | 18 ++++++++++ docs/docs.json | 36 +++++++++++++++++++ ios/RNMBX/RNMBXMapView.swift | 12 +++++++ ios/RNMBX/RNMBXMapViewManager.swift | 10 ++++++ ios/RNMBX/RNMBXMapViewModule.mm | 11 ++++++ setup-jest.js | 1 + src/components/MapView.tsx | 22 ++++++++++++ src/specs/NativeMapViewModule.ts | 6 ++++ 11 files changed, 169 insertions(+) diff --git a/android/src/main/java/com/rnmapbox/rnmbx/components/mapview/NativeMapViewModule.kt b/android/src/main/java/com/rnmapbox/rnmbx/components/mapview/NativeMapViewModule.kt index 9f412f5557..93324590fe 100644 --- a/android/src/main/java/com/rnmapbox/rnmbx/components/mapview/NativeMapViewModule.kt +++ b/android/src/main/java/com/rnmapbox/rnmbx/components/mapview/NativeMapViewModule.kt @@ -69,6 +69,20 @@ class NativeMapViewModule(context: ReactApplicationContext, val viewTagResolver: } } + override fun setStyleLayerProperty( + viewRef: ViewRefTag?, + layerId: String, + propertyName: String, + propertyValue: String, + promise: Promise + ) { + withMapViewOnUIThread(viewRef, promise) { + it.setStyleLayerProperty(layerId, propertyName, propertyValue) + + promise.resolve(null) + } + } + override fun getCenter(viewRef: ViewRefTag?, promise: Promise) { withMapViewOnUIThread(viewRef, promise) { it.getCenter(createCommandResponse(promise)) diff --git a/android/src/main/java/com/rnmapbox/rnmbx/components/mapview/RNMBXMapView.kt b/android/src/main/java/com/rnmapbox/rnmbx/components/mapview/RNMBXMapView.kt index 3bc941b750..1322602058 100644 --- a/android/src/main/java/com/rnmapbox/rnmbx/components/mapview/RNMBXMapView.kt +++ b/android/src/main/java/com/rnmapbox/rnmbx/components/mapview/RNMBXMapView.kt @@ -1076,6 +1076,41 @@ open class RNMBXMapView(private val mContext: Context, var mManager: RNMBXMapVie } } } + + fun setStyleLayerProperty( + layerId: String, + propertyName: String, + propertyValue: String + ): Boolean { + if (mMap == null) { + Logger.e("MapView", "setStyleLayerProperty, map is null") + return false + } + + val style = mMap.getStyle() + if (style == null) { + Logger.e("MapView", "setStyleLayerProperty, style is null") + return false + } + + try { + val result = style.setStyleLayerProperty( + layerId, + propertyName, + Value.valueOf(propertyValue) + ) + + if (result.isError) { + Logger.e("MapView", "setStyleLayerProperty error: ${result.error}") + return false + } + + return true + } catch (e: Exception) { + Logger.e("MapView", "setStyleLayerProperty exception: ${e.message}") + return false + } + } // endregion companion object { diff --git a/android/src/main/old-arch/com/rnmapbox/rnmbx/NativeMapViewModuleSpec.java b/android/src/main/old-arch/com/rnmapbox/rnmbx/NativeMapViewModuleSpec.java index 5014f4c730..fc024c789b 100644 --- a/android/src/main/old-arch/com/rnmapbox/rnmbx/NativeMapViewModuleSpec.java +++ b/android/src/main/old-arch/com/rnmapbox/rnmbx/NativeMapViewModuleSpec.java @@ -47,6 +47,10 @@ public NativeMapViewModuleSpec(ReactApplicationContext reactContext) { @DoNotStrip public abstract void setSourceVisibility(@Nullable Double viewRef, boolean visible, String sourceId, String sourceLayerId, Promise promise); + @ReactMethod + @DoNotStrip + public abstract void setStyleLayerProperty(@Nullable Double viewRef, String layerId, String propertyName, String propertyValue, Promise promise); + @ReactMethod @DoNotStrip public abstract void getCenter(@Nullable Double viewRef, Promise promise); diff --git a/docs/MapView.md b/docs/MapView.md index 8f252f119c..70fd721255 100644 --- a/docs/MapView.md +++ b/docs/MapView.md @@ -730,4 +730,22 @@ await this._map.setSourceVisibility(false, 'composite', 'building') ``` +### setStyleLayerProperty(layerId, propertyName, propertyValue) + +Sets the value of a property for a specific layer referencing the specified `layerId` + +#### arguments +| Name | Type | Required | Description | +| ---- | :--: | :------: | :----------: | +| `layerId` | `string` | `Yes` | layerId | +| `propertyName` | `string` | `Yes` | propertyName | +| `propertyValue` | `string` | `Yes` | propertyValue | + + + +```javascript +await this._map.setStyleLayerProperty('my-layer', 'visibility', 'none') +``` + + diff --git a/docs/docs.json b/docs/docs.json index e5da3472f4..08c77ba199 100644 --- a/docs/docs.json +++ b/docs/docs.json @@ -3726,6 +3726,42 @@ "examples": [ "\nawait this._map.setSourceVisibility(false, 'composite', 'building')\n\n" ] + }, + { + "name": "setStyleLayerProperty", + "docblock": "Sets the value of a property for a specific layer referencing the specified `layerId`\n\n@example\nawait this._map.setStyleLayerProperty('my-layer', 'visibility', 'none')\n\n@param {String} layerId - layerId\n@param {String} propertyName - propertyName\n@param {String} propertyValue - propertyValue", + "modifiers": [], + "params": [ + { + "name": "layerId", + "description": "layerId", + "type": { + "name": "string" + }, + "optional": false + }, + { + "name": "propertyName", + "description": "propertyName", + "type": { + "name": "string" + }, + "optional": false + }, + { + "name": "propertyValue", + "description": "propertyValue", + "type": { + "name": "string" + }, + "optional": false + } + ], + "returns": null, + "description": "Sets the value of a property for a specific layer referencing the specified `layerId`", + "examples": [ + "\nawait this._map.setStyleLayerProperty('my-layer', 'visibility', 'none')\n\n" + ] } ], "props": [ diff --git a/ios/RNMBX/RNMBXMapView.swift b/ios/RNMBX/RNMBXMapView.swift index 5f07618d0e..1ad4b717b0 100644 --- a/ios/RNMBX/RNMBXMapView.swift +++ b/ios/RNMBX/RNMBXMapView.swift @@ -1514,6 +1514,18 @@ extension RNMBXMapView { } } +extension RNMBXMapView { + func setStyleLayerProperty(layerId: String, propertyName: String, propertyValue: Any) -> Void { + let style = self.mapboxMap.style + + do { + try style.setLayerProperty(for: layerId, property: propertyName, value: propertyValue) + } catch { + Logger.log(level: .error, message: "Cannot set property \(propertyName) on layer: \(layerId)") + } + } +} + class RNMBXPointAnnotationManager : AnnotationInteractionDelegate { weak var selected : RNMBXPointAnnotation? = nil private var draggedAnnotation: PointAnnotation? diff --git a/ios/RNMBX/RNMBXMapViewManager.swift b/ios/RNMBX/RNMBXMapViewManager.swift index 4306b90575..a85976ae21 100644 --- a/ios/RNMBX/RNMBXMapViewManager.swift +++ b/ios/RNMBX/RNMBXMapViewManager.swift @@ -55,6 +55,16 @@ extension RNMBXMapViewManager { view.setSourceVisibility(visible, sourceId: sourceId, sourceLayerId:sourceLayerId) resolver(nil) } + + @objc public static func setStyleLayerProperty(_ view: RNMBXMapView, + layerId: String, + propertyName: String, + propertyValue: String, + resolver: @escaping RCTPromiseResolveBlock, + rejecter: @escaping RCTPromiseRejectBlock) -> Void { + view.setStyleLayerProperty(layerId: layerId, propertyName: propertyName, propertyValue: propertyValue) + resolver(nil) + } @objc public static func getCenter(_ view: RNMBXMapView, resolver: @escaping RCTPromiseResolveBlock, rejecter: @escaping RCTPromiseRejectBlock) { view.withMapboxMap { map in diff --git a/ios/RNMBX/RNMBXMapViewModule.mm b/ios/RNMBX/RNMBXMapViewModule.mm index ec622d2235..0e5e0848b4 100644 --- a/ios/RNMBX/RNMBXMapViewModule.mm +++ b/ios/RNMBX/RNMBXMapViewModule.mm @@ -133,6 +133,17 @@ - (void)withMapView:(nonnull NSNumber*)viewRef block:(void (^)(RNMBXMapView *))b } reject:reject methodName:@"setSourceVisibility"]; } +RCT_EXPORT_METHOD(setStyleLayerProperty:(nonnull NSNumber*)viewRef + layerId:(NSString *)layerId + propertyName:(NSString *)propertyName + propertyValue:(id)propertyValue + resolve:(RCTPromiseResolveBlock)resolve + reject:(RCTPromiseRejectBlock)reject) { + [self withMapView:viewRef block:^(RNMBXMapView *view) { + [RNMBXMapViewManager setStyleLayerProperty:view layerId:layerId propertyName:propertyName propertyValue:propertyValue resolver:resolve rejecter:reject]; + } reject:reject methodName:@"setStyleLayerProperty"]; +} + RCT_EXPORT_METHOD(querySourceFeatures:(nonnull NSNumber*)viewRef sourceId:(NSString*)sourceId withFilter:(NSArray*)withFilter withSourceLayerIDs:(NSArray*)withSourceLayerIDs resolve:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject) { [self withMapView:viewRef block:^(RNMBXMapView *view) { [RNMBXMapViewManager querySourceFeatures:view withSourceId:sourceId withFilter:withFilter withSourceLayerIds:withSourceLayerIDs resolver:resolve rejecter:reject]; diff --git a/setup-jest.js b/setup-jest.js index b02440f995..bf64a9492d 100644 --- a/setup-jest.js +++ b/setup-jest.js @@ -152,6 +152,7 @@ NativeModules.RNMBXMapViewModule = { takeSnap: jest.fn(), queryTerrainElevation: jest.fn(), setSourceVisibility: jest.fn(), + setStyleLayerProperty: jest.fn(), getCenter: jest.fn(), getCoordinateFromView: jest.fn(), getPointInView: jest.fn(), diff --git a/src/components/MapView.tsx b/src/components/MapView.tsx index 13042336fb..82ec285cf5 100644 --- a/src/components/MapView.tsx +++ b/src/components/MapView.tsx @@ -922,6 +922,28 @@ class MapView extends NativeBridgeComponent( ]); } + /** + * Sets the value of a property for a specific layer referencing the specified `layerId` + * + * @example + * await this._map.setStyleLayerProperty('my-layer', 'visibility', 'none') + * + * @param {String} layerId - layerId + * @param {String} propertyName - propertyName + * @param {String} propertyValue - propertyValue + */ + setStyleLayerProperty( + layerId: string, + propertyName: string, + propertyValue: string, + ) { + this._runNative('setStyleLayerProperty', [ + layerId, + propertyName, + propertyValue, + ]); + } + _decodePayload(payload: T | string): T { if (typeof payload === 'string') { return JSON.parse(payload); diff --git a/src/specs/NativeMapViewModule.ts b/src/specs/NativeMapViewModule.ts index d57abde80c..982508ce69 100644 --- a/src/specs/NativeMapViewModule.ts +++ b/src/specs/NativeMapViewModule.ts @@ -15,6 +15,12 @@ export interface Spec extends TurboModule { sourceId: string, sourceLayerId: string, ) => Promise; + setStyleLayerProperty: ( + viewRef: Int32 | null, + layerId: string, + propertyName: string, + propertyValue: string, + ) => Promise; getCenter: (viewRef: Int32 | null) => Promise; getCoordinateFromView: ( viewRef: Int32 | null,