Skip to content

Commit 8b82e08

Browse files
authored
feat: add support for screenId prop allowing for native screen recognition (#2967)
## Description Add support for `screenId` prop on native side. At the moment we use this value only in JS code. It was brought to my attention, however, that other libs that wanna integrate might want that to be exposed also on native side. ## Changes Added `screenId` prop & exposed it on both platforms. ## Test code and steps to reproduce Any example & add a breakpoint at setter method. ## Checklist - [ ] Ensured that CI passes
1 parent 19170db commit 8b82e08

File tree

14 files changed

+67
-0
lines changed

14 files changed

+67
-0
lines changed

android/src/main/java/com/swmansion/rnscreens/Screen.kt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ class Screen(
5959
var isGestureEnabled = true
6060
var screenOrientation: Int? = null
6161
private set
62+
var screenId: String? = null
6263
var isStatusBarAnimated: Boolean? = null
6364
var isBeingRemoved = false
6465

android/src/main/java/com/swmansion/rnscreens/ScreenStack.kt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,11 @@ class ScreenStack(
9191
}
9292
}
9393

94+
/**
95+
* Integration function. Allows other solutions to retrieve list of screens owned by this stack.
96+
*/
97+
fun getScreenIds(): List<String?> = screenWrappers.map { it.screen.screenId }
98+
9499
private fun dispatchOnFinishTransitioning() {
95100
val surfaceId = UIManagerHelper.getSurfaceId(this)
96101
UIManagerHelper

android/src/main/java/com/swmansion/rnscreens/ScreenViewManager.kt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -376,6 +376,10 @@ open class ScreenViewManager :
376376
view.sheetInitialDetentIndex = value
377377
}
378378

379+
override fun setScreenId(view: Screen, value: String?) {
380+
view.screenId = if (value.isNullOrEmpty()) null else value
381+
}
382+
379383
override fun getExportedCustomDirectEventTypeConstants(): MutableMap<String, Any> =
380384
mutableMapOf(
381385
ScreenDismissedEvent.EVENT_NAME to hashMapOf("registrationName" to "onDismissed"),

android/src/paper/java/com/facebook/react/viewmanagers/RNSScreenManagerDelegate.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,9 @@ public RNSScreenManagerDelegate(U viewManager) {
2525
@Override
2626
public void setProperty(T view, String propName, @Nullable Object value) {
2727
switch (propName) {
28+
case "screenId":
29+
mViewManager.setScreenId(view, value == null ? "" : (String) value);
30+
break;
2831
case "sheetAllowedDetents":
2932
mViewManager.setSheetAllowedDetents(view, (ReadableArray) value);
3033
break;

android/src/paper/java/com/facebook/react/viewmanagers/RNSScreenManagerInterface.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616

1717

1818
public interface RNSScreenManagerInterface<T extends View> {
19+
void setScreenId(T view, @Nullable String value);
1920
void setSheetAllowedDetents(T view, @Nullable ReadableArray value);
2021
void setSheetLargestUndimmedDetent(T view, int value);
2122
void setSheetGrabberVisible(T view, boolean value);

ios/RNSScreen.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,7 @@ namespace react = facebook::react;
7878
@property (nonatomic, retain) RNSScreen *controller;
7979
@property (nonatomic, copy) NSDictionary *gestureResponseDistance;
8080
@property (nonatomic) int activityState;
81+
@property (nonatomic, nullable) NSString *screenId;
8182
@property (weak, nonatomic) UIView<RNSScreenContainerDelegate> *reactSuperview;
8283

8384
#if !TARGET_OS_TV

ios/RNSScreen.mm

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1305,6 +1305,10 @@ - (void)updateProps:(react::Props::Shared const &)props oldProps:(react::Props::
13051305
[self setReplaceAnimation:[RNSConvert RNSScreenReplaceAnimationFromCppEquivalent:newScreenProps.replaceAnimation]];
13061306
}
13071307

1308+
if (newScreenProps.screenId != oldScreenProps.screenId) {
1309+
[self setScreenId:RCTNSStringFromStringNilIfEmpty(newScreenProps.screenId)];
1310+
}
1311+
13081312
[super updateProps:props oldProps:oldProps];
13091313
}
13101314

@@ -1344,6 +1348,17 @@ - (void)finalizeUpdates:(RNComponentViewUpdateMask)updateMask
13441348
#pragma mark - Paper specific
13451349
#else
13461350

1351+
// On Fabric the setter is not needed, because value invariant (empty string to nil translation)
1352+
// is upheld in `- [updateProps:oldProps:]`
1353+
- (void)setScreenId:(NSString *)screenId
1354+
{
1355+
if (screenId != nil && screenId.length == 0) {
1356+
_screenId = nil;
1357+
} else {
1358+
_screenId = screenId;
1359+
}
1360+
}
1361+
13471362
- (void)didSetProps:(NSArray<NSString *> *)changedProps
13481363
{
13491364
[super didSetProps:changedProps];
@@ -1969,6 +1984,7 @@ @implementation RNSScreenManager
19691984
RCT_EXPORT_VIEW_PROPERTY(stackAnimation, RNSScreenStackAnimation)
19701985
RCT_EXPORT_VIEW_PROPERTY(swipeDirection, RNSScreenSwipeDirection)
19711986
RCT_EXPORT_VIEW_PROPERTY(transitionDuration, NSNumber)
1987+
RCT_EXPORT_VIEW_PROPERTY(screenId, NSString);
19721988

19731989
RCT_EXPORT_VIEW_PROPERTY(onAppear, RCTDirectEventBlock);
19741990
RCT_EXPORT_VIEW_PROPERTY(onDisappear, RCTDirectEventBlock);

ios/RNSScreenStack.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,18 @@ NS_ASSUME_NONNULL_BEGIN
3636

3737
@end
3838

39+
#pragma mark-- Integration
40+
41+
@interface RNSScreenStackView ()
42+
43+
/**
44+
* \return Arrray with ids of screens owned by this stack. Ids are returned in no particular order. The list might be
45+
* empty. The strings inside the list are nullable if the screen has not been assigned an ID.
46+
*/
47+
@property (nonatomic, readonly, nonnull) NSArray<NSString *> *screenIds;
48+
49+
@end
50+
3951
@interface RNSScreenStackManager : RCTViewManager <RCTInvalidating>
4052

4153
@end

ios/RNSScreenStack.mm

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1157,6 +1157,15 @@ - (void)finishScreenTransition:(BOOL)canceled
11571157
_interactionController = nil;
11581158
}
11591159

1160+
- (nonnull NSArray<NSString *> *)screenIds
1161+
{
1162+
NSMutableArray<NSString *> *ids = [NSMutableArray arrayWithCapacity:_reactSubviews.count];
1163+
for (RNSScreenView *childScreenView in _reactSubviews) {
1164+
[ids addObject:childScreenView.screenId];
1165+
}
1166+
return ids;
1167+
}
1168+
11601169
#ifdef RCT_NEW_ARCH_ENABLED
11611170
#pragma mark - Fabric specific
11621171

src/components/Screen.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,7 @@ export const InnerScreen = React.forwardRef<View, ScreenProps>(
9191
sheetElevation = 24,
9292
sheetInitialDetentIndex = 0,
9393
// Other
94+
screenId,
9495
stackPresentation,
9596
// Events for override
9697
onAppear,
@@ -210,6 +211,7 @@ export const InnerScreen = React.forwardRef<View, ScreenProps>(
210211
// Detailed information can be found here https://github.com/software-mansion/react-native-screens/pull/2351
211212
style={[style, { zIndex: undefined }]}
212213
activityState={activityState}
214+
screenId={screenId}
213215
sheetAllowedDetents={resolvedSheetAllowedDetents}
214216
sheetLargestUndimmedDetent={resolvedSheetLargestUndimmedDetent}
215217
sheetElevation={sheetElevation}

0 commit comments

Comments
 (0)