expo-router 5.2.0-canary-20250713-8f814f8 → 5.2.0-canary-20250722-599a28f

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 (47) hide show
  1. package/assets/modal.module.css +5 -4
  2. package/build/getServerManifest.d.ts.map +1 -1
  3. package/build/getServerManifest.js +11 -3
  4. package/build/getServerManifest.js.map +1 -1
  5. package/build/link/preview/native.d.ts +1 -0
  6. package/build/link/preview/native.d.ts.map +1 -1
  7. package/build/link/preview/native.js.map +1 -1
  8. package/build/modal/Modal.d.ts +3 -1
  9. package/build/modal/Modal.d.ts.map +1 -1
  10. package/build/modal/Modal.js +27 -12
  11. package/build/modal/Modal.js.map +1 -1
  12. package/build/modal/ModalContext.d.ts +6 -13
  13. package/build/modal/ModalContext.d.ts.map +1 -1
  14. package/build/modal/ModalContext.js +34 -94
  15. package/build/modal/ModalContext.js.map +1 -1
  16. package/build/modal/ModalsRenderer.d.ts +3 -0
  17. package/build/modal/ModalsRenderer.d.ts.map +1 -0
  18. package/build/modal/ModalsRenderer.js +47 -0
  19. package/build/modal/ModalsRenderer.js.map +1 -0
  20. package/build/modal/ModalsRenderer.web.d.ts +3 -0
  21. package/build/modal/ModalsRenderer.web.d.ts.map +1 -0
  22. package/build/modal/ModalsRenderer.web.js +37 -0
  23. package/build/modal/ModalsRenderer.web.js.map +1 -0
  24. package/build/modal/types.d.ts +19 -0
  25. package/build/modal/types.d.ts.map +1 -0
  26. package/build/modal/types.js +3 -0
  27. package/build/modal/types.js.map +1 -0
  28. package/build/modal/utils.d.ts +4 -0
  29. package/build/modal/utils.d.ts.map +1 -1
  30. package/build/modal/utils.js +46 -0
  31. package/build/modal/utils.js.map +1 -1
  32. package/build/modal/web/ModalStack.web.d.ts.map +1 -1
  33. package/build/modal/web/ModalStack.web.js +4 -4
  34. package/build/modal/web/ModalStack.web.js.map +1 -1
  35. package/build/modal/web/ModalStackRouteDrawer.web.d.ts.map +1 -1
  36. package/build/modal/web/ModalStackRouteDrawer.web.js +6 -3
  37. package/build/modal/web/ModalStackRouteDrawer.web.js.map +1 -1
  38. package/build/utils/splash.d.ts.map +1 -1
  39. package/build/utils/splash.js +4 -2
  40. package/build/utils/splash.js.map +1 -1
  41. package/build/views/Sitemap.js +1 -8
  42. package/build/views/Sitemap.js.map +1 -1
  43. package/ios/LinkPreview/LinkPreviewNativeModule.swift +1 -0
  44. package/ios/LinkPreview/LinkPreviewNativeNavigation.h +6 -0
  45. package/ios/LinkPreview/LinkPreviewNativeNavigation.mm +38 -5
  46. package/ios/LinkPreview/LinkPreviewNativeView.swift +11 -3
  47. package/package.json +6 -6
@@ -11,6 +11,7 @@ public class LinkPreviewNativeModule: Module {
11
11
 
12
12
  Events(
13
13
  "onPreviewTapped",
14
+ "onPreviewTappedAnimationCompleted",
14
15
  "onWillPreviewOpen",
15
16
  "onDidPreviewOpen",
16
17
  "onPreviewWillClose",
@@ -1,5 +1,7 @@
1
1
  // Copyright 2015-present 650 Industries. All rights reserved.
2
2
 
3
+ #import <RNScreens/RNSScreenStack.h>
4
+
3
5
  @interface LinkPreviewNativeNavigation: NSObject
4
6
 
5
7
  /*
@@ -16,3 +18,7 @@
16
18
 
17
19
  @end
18
20
 
21
+ @protocol LinkPreviewModalDismissible <RNSDismissibleModalProtocol>
22
+ @required
23
+ @end
24
+
@@ -2,6 +2,7 @@
2
2
 
3
3
  #import "LinkPreviewNativeNavigation.h"
4
4
  #import <Foundation/Foundation.h>
5
+ #include <Foundation/NSObjCRuntime.h>
5
6
  #import <RNScreens/RNSScreen.h>
6
7
  #import <RNScreens/RNSScreenStack.h>
7
8
 
@@ -16,6 +17,38 @@
16
17
  // React native screens will then handle the rest.
17
18
  [preloadedScreenView setActivityState:2];
18
19
  [stackView markChildUpdated];
20
+ // If the screen is modal with header then it will have exactly one child -
21
+ // RNSNavigationController.
22
+ // https://github.com/software-mansion/react-native-screens/blob/8b82e081e8fdfa6e0864821134bda9e87a745b00/src/components/ScreenStackItem.tsx#L146-L160
23
+ if (preloadedScreenView.isModal &&
24
+ preloadedScreenView.controller.childViewControllers.count == 1) {
25
+ // The first child should be RNSNavigationController (<ScreenStack>).
26
+ UIViewController *navController =
27
+ preloadedScreenView.controller.childViewControllers[0];
28
+ if ([navController isKindOfClass:[RNSNavigationController class]]) {
29
+ RNSNavigationController *rnsNavController =
30
+ (RNSNavigationController *)navController;
31
+ // The delegate of RNSNavigationController is RNSScreenStackView.
32
+ id<UINavigationControllerDelegate> delegate = rnsNavController.delegate;
33
+ if ([delegate isKindOfClass:[RNSScreenStackView class]]) {
34
+ RNSScreenStackView *innerScreenStack = (RNSScreenStackView *)delegate;
35
+ // The first and only child of the inner screen stack should be
36
+ // RNSScreenView (<ScreenStackItem>).
37
+ UIView *firstChild = innerScreenStack.reactSubviews != nil
38
+ ? innerScreenStack.reactSubviews[0]
39
+ : nil;
40
+ if (firstChild != nil &&
41
+ [firstChild isKindOfClass:[RNSScreenView class]]) {
42
+ RNSScreenView *screenContentView = (RNSScreenView *)firstChild;
43
+ // Same as above, we let React Native Screens handle the transition.
44
+ // We need to set the activity of inner screen as well, because its react value is the same as the preloaded screen - 0.
45
+ // https://github.com/software-mansion/react-native-screens/blob/8b82e081e8fdfa6e0864821134bda9e87a745b00/src/components/ScreenStackItem.tsx#L151
46
+ [screenContentView setActivityState:2];
47
+ [innerScreenStack markChildUpdated];
48
+ }
49
+ }
50
+ }
51
+ }
19
52
  NSLog(@"ExpoRouter: Preloaded screen view pushed.");
20
53
  } else {
21
54
  NSLog(@"ExpoRouter: No preloaded screen view found. Relying on JS "
@@ -38,8 +71,8 @@
38
71
  }
39
72
  }
40
73
 
41
- - (nonnull NSArray<RNSScreenStackView *> *)findAllScreenStackViewsInResponderChain:
42
- (nonnull UIResponder *)responder {
74
+ - (nonnull NSArray<RNSScreenStackView *> *)
75
+ findAllScreenStackViewsInResponderChain:(nonnull UIResponder *)responder {
43
76
  NSMutableArray<RNSScreenStackView *> *stackViews = [NSMutableArray array];
44
77
 
45
78
  while (responder) {
@@ -93,9 +126,9 @@
93
126
  return NO;
94
127
  }
95
128
 
96
- - (nullable RNSScreenView *)findPreloadedScreenView:
97
- (nonnull NSArray<RNSScreenView *> *)screenViews
98
- withScreenId:(nonnull NSString *)screenId {
129
+ - (nullable RNSScreenView *)
130
+ findPreloadedScreenView:(nonnull NSArray<RNSScreenView *> *)screenViews
131
+ withScreenId:(nonnull NSString *)screenId {
99
132
  for (RNSScreenView *screenView in screenViews) {
100
133
  if (screenView.activityState == 0 &&
101
134
  [screenView.screenId isEqualToString:screenId]) {
@@ -1,6 +1,6 @@
1
1
  import ExpoModulesCore
2
2
 
3
- class NativeLinkPreviewView: ExpoView, UIContextMenuInteractionDelegate {
3
+ class NativeLinkPreviewView: ExpoView, UIContextMenuInteractionDelegate, LinkPreviewModalDismissible {
4
4
  private var trigger: NativeLinkPreviewTrigger?
5
5
  private var preview: NativeLinkPreviewContentView?
6
6
  private var interaction: UIContextMenuInteraction?
@@ -10,6 +10,7 @@ class NativeLinkPreviewView: ExpoView, UIContextMenuInteractionDelegate {
10
10
  private let linkPreviewNativeNavigation = LinkPreviewNativeNavigation()
11
11
 
12
12
  let onPreviewTapped = EventDispatcher()
13
+ let onPreviewTappedAnimationCompleted = EventDispatcher()
13
14
  let onWillPreviewOpen = EventDispatcher()
14
15
  let onDidPreviewOpen = EventDispatcher()
15
16
  let onPreviewWillClose = EventDispatcher()
@@ -21,6 +22,12 @@ class NativeLinkPreviewView: ExpoView, UIContextMenuInteractionDelegate {
21
22
  self.interaction = UIContextMenuInteraction(delegate: self)
22
23
  }
23
24
 
25
+ // MARK: - LinkPreviewModalDismissable
26
+
27
+ func isDismissible() -> Bool {
28
+ return false
29
+ }
30
+
24
31
  // MARK: - Props
25
32
 
26
33
  func setNextScreenId(_ screenId: String) {
@@ -137,9 +144,10 @@ class NativeLinkPreviewView: ExpoView, UIContextMenuInteractionDelegate {
137
144
  willPerformPreviewActionForMenuWith configuration: UIContextMenuConfiguration,
138
145
  animator: UIContextMenuInteractionCommitAnimating
139
146
  ) {
140
- linkPreviewNativeNavigation.pushPreloadedView()
141
- onPreviewTapped()
147
+ self.onPreviewTapped()
142
148
  animator.addCompletion { [weak self] in
149
+ self?.linkPreviewNativeNavigation.pushPreloadedView()
150
+ self?.onPreviewTappedAnimationCompleted()
143
151
  }
144
152
  }
145
153
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "expo-router",
3
- "version": "5.2.0-canary-20250713-8f814f8",
3
+ "version": "5.2.0-canary-20250722-599a28f",
4
4
  "description": "Expo Router is a file-based router for React Native and web applications.",
5
5
  "author": "650 Industries, Inc.",
6
6
  "license": "MIT",
@@ -76,9 +76,9 @@
76
76
  ],
77
77
  "peerDependencies": {
78
78
  "@react-navigation/drawer": "^7.3.9",
79
- "expo": "54.0.0-canary-20250713-8f814f8",
80
- "expo-constants": "17.1.8-canary-20250713-8f814f8",
81
- "expo-linking": "7.1.8-canary-20250713-8f814f8",
79
+ "expo": "54.0.0-canary-20250722-599a28f",
80
+ "expo-constants": "17.1.8-canary-20250722-599a28f",
81
+ "expo-linking": "7.1.8-canary-20250722-599a28f",
82
82
  "react-native-reanimated": "*",
83
83
  "react-native-safe-area-context": "*",
84
84
  "react-native-screens": "*"
@@ -105,8 +105,8 @@
105
105
  "tsd": "^0.28.1"
106
106
  },
107
107
  "dependencies": {
108
- "@expo/metro-runtime": "6.0.0-canary-20250713-8f814f8",
109
- "@expo/server": "0.6.4-canary-20250713-8f814f8",
108
+ "@expo/metro-runtime": "6.0.0-canary-20250722-599a28f",
109
+ "@expo/server": "0.6.4-canary-20250722-599a28f",
110
110
  "@radix-ui/react-slot": "1.2.0",
111
111
  "@react-navigation/bottom-tabs": "^7.3.10",
112
112
  "@react-navigation/native": "^7.1.6",