expo-dev-launcher 55.0.11 → 55.0.13

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.
package/CHANGELOG.md CHANGED
@@ -10,6 +10,18 @@
10
10
 
11
11
  ### 💡 Others
12
12
 
13
+ ## 55.0.13 — 2026-03-09
14
+
15
+ ### 🐛 Bug fixes
16
+
17
+ - [iOS] Fix missing navigation bar padding ([#43672](https://github.com/expo/expo/pull/43672) by [@alanjhughes](https://github.com/alanjhughes))
18
+
19
+ ## 55.0.12 — 2026-03-04
20
+
21
+ ### 🐛 Bug fixes
22
+
23
+ - [iOS] Fix issue when using `fullScreenModal` with `expo-router`. ([#43520](https://github.com/expo/expo/pull/43520) by [@alanjhughes](https://github.com/alanjhughes))
24
+
13
25
  ## 55.0.11 — 2026-02-26
14
26
 
15
27
  _This version does not introduce any user-facing changes._
@@ -26,13 +26,13 @@ expoModule {
26
26
  }
27
27
 
28
28
  group = "host.exp.exponent"
29
- version = "55.0.11"
29
+ version = "55.0.13"
30
30
 
31
31
  android {
32
32
  namespace "expo.modules.devlauncher"
33
33
  defaultConfig {
34
34
  versionCode 9
35
- versionName "55.0.11"
35
+ versionName "55.0.13"
36
36
  }
37
37
 
38
38
  buildTypes {
@@ -6,66 +6,25 @@ import React
6
6
 
7
7
  private class DevLauncherWrapperView: UIView {
8
8
  weak var devLauncherViewController: UIViewController?
9
- private var devLauncherConstraints: [NSLayoutConstraint] = []
10
9
 
11
- #if os(iOS)
12
- @objc
13
- func orientationDidChange() {
14
- if let controller = devLauncherViewController {
15
- setDevLauncherViewControllerConstraints(controller)
16
- }
17
- }
18
- #endif
19
-
20
- func setDevLauncherViewControllerConstraints(_ viewController: UIViewController) {
21
- viewController.view.translatesAutoresizingMaskIntoConstraints = false
22
- if !devLauncherConstraints.isEmpty {
23
- NSLayoutConstraint.deactivate(devLauncherConstraints)
24
- }
25
- devLauncherConstraints = [
26
- viewController.view.topAnchor.constraint(equalTo: self.topAnchor),
27
- viewController.view.leadingAnchor.constraint(equalTo: self.leadingAnchor),
28
- viewController.view.trailingAnchor.constraint(equalTo: self.trailingAnchor),
29
- viewController.view.bottomAnchor.constraint(equalTo: self.bottomAnchor)
30
- ]
31
- NSLayoutConstraint.activate(devLauncherConstraints)
10
+ func setupDevLauncherView(_ viewController: UIViewController) {
11
+ #if os(macOS)
12
+ viewController.view.autoresizingMask = [.width, .height]
13
+ #else
14
+ viewController.view.autoresizingMask = [.flexibleWidth, .flexibleHeight]
15
+ #endif
16
+ viewController.view.frame = bounds
32
17
  }
33
18
 
34
19
  #if !os(macOS)
35
- override func didMoveToWindow() {
36
- super.didMoveToWindow()
37
- #if os(iOS)
38
- if window != nil {
39
- NotificationCenter.default.addObserver(self, selector: #selector(orientationDidChange), name: UIDevice.orientationDidChangeNotification, object: nil)
40
- }
41
- #endif
42
-
43
- guard let devLauncherViewController,
44
- let window,
45
- let rootViewController = window.rootViewController else {
46
- return
47
- }
48
-
49
- let isSwiftUIController = NSStringFromClass(type(of: rootViewController)).contains("UIHostingController")
50
- // TODO(pmleczek): Revisit this for a more reliable solution
51
- let isBrownfield = NSStringFromClass(type(of: rootViewController)).contains("UINavigationController")
52
- if !isSwiftUIController && !isBrownfield && devLauncherViewController.parent != rootViewController {
53
- rootViewController.addChild(devLauncherViewController)
54
- devLauncherViewController.didMove(toParent: rootViewController)
55
- devLauncherViewController.view.setNeedsLayout()
56
- devLauncherViewController.view.layoutIfNeeded()
57
- }
20
+ override func layoutSubviews() {
21
+ super.layoutSubviews()
22
+ devLauncherViewController?.view.frame = bounds
58
23
  }
59
24
 
60
- override func willMove(toWindow newWindow: UIWindow?) {
61
- super.willMove(toWindow: newWindow)
62
- if newWindow == nil {
63
- devLauncherViewController?.willMove(toParent: nil)
64
- devLauncherViewController?.removeFromParent()
65
- #if os(iOS)
66
- NotificationCenter.default.removeObserver(self, name: UIDevice.orientationDidChangeNotification, object: nil)
67
- #endif
68
- }
25
+ override func safeAreaInsetsDidChange() {
26
+ super.safeAreaInsetsDidChange()
27
+ devLauncherViewController?.view.layoutIfNeeded()
69
28
  }
70
29
  #endif
71
30
  }
@@ -110,7 +69,7 @@ public class ExpoDevLauncherReactDelegateHandler: ExpoReactDelegateHandler, EXDe
110
69
  let wrapperView = DevLauncherWrapperView()
111
70
  wrapperView.devLauncherViewController = viewController
112
71
  wrapperView.addSubview(viewController.view)
113
- wrapperView.setDevLauncherViewControllerConstraints(viewController)
72
+ wrapperView.setupDevLauncherView(viewController)
114
73
  return wrapperView
115
74
  }
116
75
 
@@ -158,26 +117,49 @@ public class ExpoDevLauncherReactDelegateHandler: ExpoReactDelegateHandler, EXDe
158
117
  )
159
118
  developmentClientController.appBridge = RCTBridge.current()
160
119
 
161
- guard let rootViewController = rootViewController ?? self.reactDelegate?.createRootViewController() else {
120
+ let targetVC: UIViewController
121
+ #if !os(macOS)
122
+ let windowRootVC = rootViewController?.view?.window?.rootViewController
123
+ if let windowRootVC, windowRootVC.view is DevLauncherWrapperView {
124
+ // Greenfield: set root view on the window's root VC so react-native-screens parents its
125
+ // UINavigationController to a VC in the containment hierarchy with correct layout margins.
126
+ targetVC = windowRootVC
127
+ } else if let rootViewController {
128
+ // Brownfield: the wrapper is embedded in a custom hierarchy, fall back to
129
+ // DevLauncherViewController to avoid replacing the host app's root view.
130
+ targetVC = rootViewController
131
+ } else if let fallbackVC = self.reactDelegate?.createRootViewController() {
132
+ targetVC = fallbackVC
133
+ } else {
162
134
  fatalError("Invalid rootViewController returned from ExpoReactDelegate")
163
135
  }
136
+ #else
137
+ // macOS: NSWindow has no rootViewController, fall back to DevLauncherViewController.
138
+ if let rootViewController {
139
+ targetVC = rootViewController
140
+ } else if let fallbackVC = self.reactDelegate?.createRootViewController() {
141
+ targetVC = fallbackVC
142
+ } else {
143
+ fatalError("Invalid rootViewController returned from ExpoReactDelegate")
144
+ }
145
+ #endif
164
146
  #if os(macOS)
165
147
  let newViewController = UIViewController()
166
148
  newViewController.view = rootView
167
149
 
168
- rootViewController.view.subviews.forEach { $0.removeFromSuperview() }
169
- rootViewController.addChild(newViewController)
170
- rootViewController.view.addSubview(newViewController.view)
150
+ targetVC.view.subviews.forEach { $0.removeFromSuperview() }
151
+ targetVC.addChild(newViewController)
152
+ targetVC.view.addSubview(newViewController.view)
171
153
 
172
154
  newViewController.view.translatesAutoresizingMaskIntoConstraints = false
173
155
  NSLayoutConstraint.activate([
174
- newViewController.view.topAnchor.constraint(equalTo: rootViewController.view.topAnchor),
175
- newViewController.view.leadingAnchor.constraint(equalTo: rootViewController.view.leadingAnchor),
176
- newViewController.view.trailingAnchor.constraint(equalTo: rootViewController.view.trailingAnchor),
177
- newViewController.view.bottomAnchor.constraint(equalTo: rootViewController.view.bottomAnchor)
156
+ newViewController.view.topAnchor.constraint(equalTo: targetVC.view.topAnchor),
157
+ newViewController.view.leadingAnchor.constraint(equalTo: targetVC.view.leadingAnchor),
158
+ newViewController.view.trailingAnchor.constraint(equalTo: targetVC.view.trailingAnchor),
159
+ newViewController.view.bottomAnchor.constraint(equalTo: targetVC.view.bottomAnchor)
178
160
  ])
179
161
  #else
180
- rootViewController.view = rootView
162
+ targetVC.view = rootView
181
163
  #endif
182
164
  // it is purposeful that we don't clean up saved properties here, because we may initialize
183
165
  // several React instances over a single app lifetime and we want them all to have the same
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "expo-dev-launcher",
3
3
  "title": "Expo Development Launcher",
4
- "version": "55.0.11",
4
+ "version": "55.0.13",
5
5
  "description": "Pre-release version of the Expo development launcher package for testing.",
6
6
  "repository": {
7
7
  "type": "git",
@@ -16,11 +16,11 @@
16
16
  "homepage": "https://docs.expo.dev",
17
17
  "dependencies": {
18
18
  "@expo/schema-utils": "^55.0.2",
19
- "expo-dev-menu": "55.0.10",
19
+ "expo-dev-menu": "55.0.11",
20
20
  "expo-manifests": "~55.0.9"
21
21
  },
22
22
  "peerDependencies": {
23
23
  "expo": "*"
24
24
  },
25
- "gitHead": "413b0450434d3e456eb391eca792ee9ac1e1efec"
25
+ "gitHead": "1d6c3a990f2092d01320900c5ed1d5f2f8a07913"
26
26
  }