expo-router 7.0.0-canary-20251216-3f01dbf → 7.0.0-canary-20251223-b83b31e
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/android/build.gradle +2 -2
- package/build/color/index.d.ts +44 -0
- package/build/color/index.d.ts.map +1 -1
- package/build/color/index.js +69 -5
- package/build/color/index.js.map +1 -1
- package/build/exports.d.ts +1 -0
- package/build/exports.d.ts.map +1 -1
- package/build/exports.js +3 -1
- package/build/exports.js.map +1 -1
- package/build/layouts/StackClient.d.ts +1 -1
- package/build/layouts/stack-utils/StackHeaderButton.d.ts +77 -2
- package/build/layouts/stack-utils/StackHeaderButton.d.ts.map +1 -1
- package/build/layouts/stack-utils/StackHeaderButton.js +3 -0
- package/build/layouts/stack-utils/StackHeaderButton.js.map +1 -1
- package/build/layouts/stack-utils/StackHeaderLeftRight.d.ts.map +1 -1
- package/build/layouts/stack-utils/StackHeaderLeftRight.js +7 -5
- package/build/layouts/stack-utils/StackHeaderLeftRight.js.map +1 -1
- package/build/layouts/stack-utils/StackHeaderMenu.d.ts +83 -7
- package/build/layouts/stack-utils/StackHeaderMenu.d.ts.map +1 -1
- package/build/layouts/stack-utils/StackHeaderMenu.js +14 -4
- package/build/layouts/stack-utils/StackHeaderMenu.js.map +1 -1
- package/build/layouts/stack-utils/StackHeaderSpacer.d.ts +7 -1
- package/build/layouts/stack-utils/StackHeaderSpacer.d.ts.map +1 -1
- package/build/layouts/stack-utils/StackHeaderSpacer.js +5 -2
- package/build/layouts/stack-utils/StackHeaderSpacer.js.map +1 -1
- package/build/layouts/stack-utils/{StackHeaderItem.d.ts → StackHeaderView.d.ts} +18 -5
- package/build/layouts/stack-utils/StackHeaderView.d.ts.map +1 -0
- package/build/layouts/stack-utils/{StackHeaderItem.js → StackHeaderView.js} +14 -10
- package/build/layouts/stack-utils/StackHeaderView.js.map +1 -0
- package/build/layouts/stack-utils/index.d.ts +3 -3
- package/build/layouts/stack-utils/index.d.ts.map +1 -1
- package/build/layouts/stack-utils/index.js +4 -4
- package/build/layouts/stack-utils/index.js.map +1 -1
- package/build/layouts/stack-utils/shared.d.ts +4 -42
- package/build/layouts/stack-utils/shared.d.ts.map +1 -1
- package/build/layouts/stack-utils/shared.js +3 -22
- package/build/layouts/stack-utils/shared.js.map +1 -1
- package/build/link/ExpoLink.d.ts.map +1 -1
- package/build/link/ExpoLink.js +1 -8
- package/build/link/ExpoLink.js.map +1 -1
- package/build/link/elements.d.ts +36 -13
- package/build/link/elements.d.ts.map +1 -1
- package/build/link/elements.js +14 -5
- package/build/link/elements.js.map +1 -1
- package/build/link/preview/native.d.ts +12 -1
- package/build/link/preview/native.d.ts.map +1 -1
- package/build/link/preview/native.js.map +1 -1
- package/build/navigationEvents/index.d.ts +36 -0
- package/build/navigationEvents/index.d.ts.map +1 -0
- package/build/navigationEvents/index.js +53 -0
- package/build/navigationEvents/index.js.map +1 -0
- package/build/toolbar/elements.d.ts +325 -16
- package/build/toolbar/elements.d.ts.map +1 -1
- package/build/toolbar/elements.js +130 -12
- package/build/toolbar/elements.js.map +1 -1
- package/build/toolbar/index.d.ts +38 -6
- package/build/toolbar/index.d.ts.map +1 -1
- package/build/toolbar/index.js +36 -1
- package/build/toolbar/index.js.map +1 -1
- package/build/toolbar/native.ios.d.ts.map +1 -1
- package/build/toolbar/native.ios.js.map +1 -1
- package/build/toolbar/native.types.d.ts +6 -5
- package/build/toolbar/native.types.d.ts.map +1 -1
- package/build/toolbar/native.types.js.map +1 -1
- package/build/useScreens.d.ts.map +1 -1
- package/build/useScreens.js +50 -0
- package/build/useScreens.js.map +1 -1
- package/build/utils/font.d.ts +9 -0
- package/build/utils/font.d.ts.map +1 -0
- package/build/utils/font.js +20 -0
- package/build/utils/font.js.map +1 -0
- package/expo-module.config.json +1 -1
- package/ios/LinkPreview/LinkPreviewNativeActionView.swift +105 -24
- package/ios/LinkPreview/LinkPreviewNativeModule.swift +35 -8
- package/ios/LinkPreview/LinkPreviewNativeNavigation.swift +16 -20
- package/ios/LinkPreview/LinkPreviewNativePreviewView.swift +1 -8
- package/ios/LinkPreview/LinkPreviewNativeView.swift +48 -50
- package/ios/LinkPreview/LinkZoomTransition.swift +8 -10
- package/ios/RouterViewWithLogger.swift +5 -0
- package/ios/Toolbar/RouterFontUtils.swift +50 -0
- package/ios/Toolbar/RouterToolbarHostView.swift +41 -17
- package/ios/Toolbar/RouterToolbarItemView.swift +30 -13
- package/ios/Toolbar/RouterToolbarModule.swift +28 -0
- package/local-maven-repo/expo/modules/router/expo.modules.router/7.0.0-canary-20251223-b83b31e/expo.modules.router-7.0.0-canary-20251223-b83b31e.aar +0 -0
- package/local-maven-repo/expo/modules/router/expo.modules.router/7.0.0-canary-20251223-b83b31e/expo.modules.router-7.0.0-canary-20251223-b83b31e.aar.md5 +1 -0
- package/local-maven-repo/expo/modules/router/expo.modules.router/7.0.0-canary-20251223-b83b31e/expo.modules.router-7.0.0-canary-20251223-b83b31e.aar.sha1 +1 -0
- package/local-maven-repo/expo/modules/router/expo.modules.router/7.0.0-canary-20251223-b83b31e/expo.modules.router-7.0.0-canary-20251223-b83b31e.aar.sha256 +1 -0
- package/local-maven-repo/expo/modules/router/expo.modules.router/7.0.0-canary-20251223-b83b31e/expo.modules.router-7.0.0-canary-20251223-b83b31e.aar.sha512 +1 -0
- package/local-maven-repo/expo/modules/router/expo.modules.router/{7.0.0-canary-20251216-3f01dbf/expo.modules.router-7.0.0-canary-20251216-3f01dbf.module → 7.0.0-canary-20251223-b83b31e/expo.modules.router-7.0.0-canary-20251223-b83b31e.module} +17 -17
- package/local-maven-repo/expo/modules/router/expo.modules.router/7.0.0-canary-20251223-b83b31e/expo.modules.router-7.0.0-canary-20251223-b83b31e.module.md5 +1 -0
- package/local-maven-repo/expo/modules/router/expo.modules.router/7.0.0-canary-20251223-b83b31e/expo.modules.router-7.0.0-canary-20251223-b83b31e.module.sha1 +1 -0
- package/local-maven-repo/expo/modules/router/expo.modules.router/7.0.0-canary-20251223-b83b31e/expo.modules.router-7.0.0-canary-20251223-b83b31e.module.sha256 +1 -0
- package/local-maven-repo/expo/modules/router/expo.modules.router/7.0.0-canary-20251223-b83b31e/expo.modules.router-7.0.0-canary-20251223-b83b31e.module.sha512 +1 -0
- package/local-maven-repo/expo/modules/router/expo.modules.router/{7.0.0-canary-20251216-3f01dbf/expo.modules.router-7.0.0-canary-20251216-3f01dbf.pom → 7.0.0-canary-20251223-b83b31e/expo.modules.router-7.0.0-canary-20251223-b83b31e.pom} +1 -1
- package/local-maven-repo/expo/modules/router/expo.modules.router/7.0.0-canary-20251223-b83b31e/expo.modules.router-7.0.0-canary-20251223-b83b31e.pom.md5 +1 -0
- package/local-maven-repo/expo/modules/router/expo.modules.router/7.0.0-canary-20251223-b83b31e/expo.modules.router-7.0.0-canary-20251223-b83b31e.pom.sha1 +1 -0
- package/local-maven-repo/expo/modules/router/expo.modules.router/7.0.0-canary-20251223-b83b31e/expo.modules.router-7.0.0-canary-20251223-b83b31e.pom.sha256 +1 -0
- package/local-maven-repo/expo/modules/router/expo.modules.router/7.0.0-canary-20251223-b83b31e/expo.modules.router-7.0.0-canary-20251223-b83b31e.pom.sha512 +1 -0
- package/local-maven-repo/expo/modules/router/expo.modules.router/maven-metadata.xml +4 -4
- package/local-maven-repo/expo/modules/router/expo.modules.router/maven-metadata.xml.md5 +1 -1
- package/local-maven-repo/expo/modules/router/expo.modules.router/maven-metadata.xml.sha1 +1 -1
- package/local-maven-repo/expo/modules/router/expo.modules.router/maven-metadata.xml.sha256 +1 -1
- package/local-maven-repo/expo/modules/router/expo.modules.router/maven-metadata.xml.sha512 +1 -1
- package/package.json +10 -10
- package/build/layouts/stack-utils/StackHeaderItem.d.ts.map +0 -1
- package/build/layouts/stack-utils/StackHeaderItem.js.map +0 -1
- package/local-maven-repo/expo/modules/router/expo.modules.router/7.0.0-canary-20251216-3f01dbf/expo.modules.router-7.0.0-canary-20251216-3f01dbf.aar +0 -0
- package/local-maven-repo/expo/modules/router/expo.modules.router/7.0.0-canary-20251216-3f01dbf/expo.modules.router-7.0.0-canary-20251216-3f01dbf.aar.md5 +0 -1
- package/local-maven-repo/expo/modules/router/expo.modules.router/7.0.0-canary-20251216-3f01dbf/expo.modules.router-7.0.0-canary-20251216-3f01dbf.aar.sha1 +0 -1
- package/local-maven-repo/expo/modules/router/expo.modules.router/7.0.0-canary-20251216-3f01dbf/expo.modules.router-7.0.0-canary-20251216-3f01dbf.aar.sha256 +0 -1
- package/local-maven-repo/expo/modules/router/expo.modules.router/7.0.0-canary-20251216-3f01dbf/expo.modules.router-7.0.0-canary-20251216-3f01dbf.aar.sha512 +0 -1
- package/local-maven-repo/expo/modules/router/expo.modules.router/7.0.0-canary-20251216-3f01dbf/expo.modules.router-7.0.0-canary-20251216-3f01dbf.module.md5 +0 -1
- package/local-maven-repo/expo/modules/router/expo.modules.router/7.0.0-canary-20251216-3f01dbf/expo.modules.router-7.0.0-canary-20251216-3f01dbf.module.sha1 +0 -1
- package/local-maven-repo/expo/modules/router/expo.modules.router/7.0.0-canary-20251216-3f01dbf/expo.modules.router-7.0.0-canary-20251216-3f01dbf.module.sha256 +0 -1
- package/local-maven-repo/expo/modules/router/expo.modules.router/7.0.0-canary-20251216-3f01dbf/expo.modules.router-7.0.0-canary-20251216-3f01dbf.module.sha512 +0 -1
- package/local-maven-repo/expo/modules/router/expo.modules.router/7.0.0-canary-20251216-3f01dbf/expo.modules.router-7.0.0-canary-20251216-3f01dbf.pom.md5 +0 -1
- package/local-maven-repo/expo/modules/router/expo.modules.router/7.0.0-canary-20251216-3f01dbf/expo.modules.router-7.0.0-canary-20251216-3f01dbf.pom.sha1 +0 -1
- package/local-maven-repo/expo/modules/router/expo.modules.router/7.0.0-canary-20251216-3f01dbf/expo.modules.router-7.0.0-canary-20251216-3f01dbf.pom.sha256 +0 -1
- package/local-maven-repo/expo/modules/router/expo.modules.router/7.0.0-canary-20251216-3f01dbf/expo.modules.router-7.0.0-canary-20251216-3f01dbf.pom.sha512 +0 -1
- /package/local-maven-repo/expo/modules/router/expo.modules.router/{7.0.0-canary-20251216-3f01dbf/expo.modules.router-7.0.0-canary-20251216-3f01dbf-sources.jar → 7.0.0-canary-20251223-b83b31e/expo.modules.router-7.0.0-canary-20251223-b83b31e-sources.jar} +0 -0
- /package/local-maven-repo/expo/modules/router/expo.modules.router/{7.0.0-canary-20251216-3f01dbf/expo.modules.router-7.0.0-canary-20251216-3f01dbf-sources.jar.md5 → 7.0.0-canary-20251223-b83b31e/expo.modules.router-7.0.0-canary-20251223-b83b31e-sources.jar.md5} +0 -0
- /package/local-maven-repo/expo/modules/router/expo.modules.router/{7.0.0-canary-20251216-3f01dbf/expo.modules.router-7.0.0-canary-20251216-3f01dbf-sources.jar.sha1 → 7.0.0-canary-20251223-b83b31e/expo.modules.router-7.0.0-canary-20251223-b83b31e-sources.jar.sha1} +0 -0
- /package/local-maven-repo/expo/modules/router/expo.modules.router/{7.0.0-canary-20251216-3f01dbf/expo.modules.router-7.0.0-canary-20251216-3f01dbf-sources.jar.sha256 → 7.0.0-canary-20251223-b83b31e/expo.modules.router-7.0.0-canary-20251223-b83b31e-sources.jar.sha256} +0 -0
- /package/local-maven-repo/expo/modules/router/expo.modules.router/{7.0.0-canary-20251216-3f01dbf/expo.modules.router-7.0.0-canary-20251216-3f01dbf-sources.jar.sha512 → 7.0.0-canary-20251223-b83b31e/expo.modules.router-7.0.0-canary-20251223-b83b31e-sources.jar.sha512} +0 -0
|
@@ -8,8 +8,8 @@ struct TabChangeCommand {
|
|
|
8
8
|
}
|
|
9
9
|
|
|
10
10
|
internal class LinkPreviewNativeNavigation {
|
|
11
|
-
private var preloadedScreenView: RNSScreenView?
|
|
12
|
-
private var preloadedStackView: RNSScreenStackView?
|
|
11
|
+
private weak var preloadedScreenView: RNSScreenView?
|
|
12
|
+
private weak var preloadedStackView: RNSScreenStackView?
|
|
13
13
|
private var tabChangeCommands: [TabChangeCommand] = []
|
|
14
14
|
private let logger: Logger?
|
|
15
15
|
|
|
@@ -27,7 +27,7 @@ internal class LinkPreviewNativeNavigation {
|
|
|
27
27
|
// If there were, the preview transition could be to a different tab only
|
|
28
28
|
if self.tabChangeCommands.isEmpty {
|
|
29
29
|
logger?.warn(
|
|
30
|
-
"expo-router
|
|
30
|
+
"[expo-router] No preloaded screen view to push. Link.Preview transition is only supported inside a native stack or native tabs navigators."
|
|
31
31
|
)
|
|
32
32
|
}
|
|
33
33
|
return
|
|
@@ -45,22 +45,19 @@ internal class LinkPreviewNativeNavigation {
|
|
|
45
45
|
let oldTabKeys = tabPath?.path.map { $0.oldTabKey } ?? []
|
|
46
46
|
let stackOrTabView = findStackViewWithScreenIdOrTabBarController(
|
|
47
47
|
screenId: screenId, tabKeys: oldTabKeys, responder: responder)
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
} else if let stackView = stackOrTabView as? RNSScreenStackView, let screenId {
|
|
48
|
+
guard let stackOrTabView else {
|
|
49
|
+
return
|
|
50
|
+
}
|
|
51
|
+
if let tabView = stackOrTabView as? RNSBottomTabsScreenComponentView {
|
|
52
|
+
let newTabKeys = tabPath?.path.map { $0.newTabKey } ?? []
|
|
53
|
+
// The order is important here. findStackViewWithScreenIdInSubViews must be called
|
|
54
|
+
// even if screenId is nil to compute the tabChangeCommands.
|
|
55
|
+
if let stackView = findStackViewWithScreenIdInSubViews(
|
|
56
|
+
screenId: screenId, tabKeys: newTabKeys, rootView: tabView), let screenId {
|
|
58
57
|
setPreloadedView(stackView: stackView, screenId: screenId)
|
|
59
58
|
}
|
|
60
|
-
} else {
|
|
61
|
-
|
|
62
|
-
"expo-router: No view found for link preview navigation. You should only use Link.Preview when navigating inside a stack or native tabs navigator."
|
|
63
|
-
)
|
|
59
|
+
} else if let stackView = stackOrTabView as? RNSScreenStackView, let screenId {
|
|
60
|
+
setPreloadedView(stackView: stackView, screenId: screenId)
|
|
64
61
|
}
|
|
65
62
|
}
|
|
66
63
|
|
|
@@ -88,8 +85,6 @@ internal class LinkPreviewNativeNavigation {
|
|
|
88
85
|
// The first and only child of the inner screen stack should be
|
|
89
86
|
// RNSScreenView (<ScreenStackItem>).
|
|
90
87
|
let screenContentView = innerScreenStack.reactSubviews().first as? RNSScreenView {
|
|
91
|
-
print("screenView screenId:", screenView.screenId)
|
|
92
|
-
print("innerScreenStack screenIds:", innerScreenStack.screenIds)
|
|
93
88
|
// Same as above, we let React Native Screens handle the transition.
|
|
94
89
|
// We need to set the activity of inner screen as well, because its
|
|
95
90
|
// react value is the same as the preloaded screen - 0.
|
|
@@ -152,7 +147,8 @@ internal class LinkPreviewNativeNavigation {
|
|
|
152
147
|
) -> (tabIndex: Int, tabView: UIView)? {
|
|
153
148
|
let views = tabBarController.viewControllers?.compactMap { $0.view } ?? []
|
|
154
149
|
let enumeratedViews = views.enumerated()
|
|
155
|
-
if let result =
|
|
150
|
+
if let result =
|
|
151
|
+
enumeratedViews
|
|
156
152
|
.first(where: { _, view in
|
|
157
153
|
guard let tabView = view as? RNSBottomTabsScreenComponentView, let tabKey = tabView.tabKey
|
|
158
154
|
else {
|
|
@@ -1,16 +1,9 @@
|
|
|
1
1
|
import ExpoModulesCore
|
|
2
|
-
import WebKit
|
|
3
2
|
|
|
4
|
-
class NativeLinkPreviewContentView:
|
|
3
|
+
class NativeLinkPreviewContentView: RouterViewWithLogger {
|
|
5
4
|
var preferredContentSize: CGSize = .zero
|
|
6
5
|
|
|
7
|
-
required init(appContext: AppContext? = nil) {
|
|
8
|
-
super.init(appContext: appContext)
|
|
9
|
-
}
|
|
10
|
-
|
|
11
6
|
func setInitialSize(bounds: CGRect) {
|
|
12
|
-
#if RCT_NEW_ARCH_ENABLED
|
|
13
7
|
self.setShadowNodeSize(Float(bounds.width), height: Float(bounds.height))
|
|
14
|
-
#endif
|
|
15
8
|
}
|
|
16
9
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import ExpoModulesCore
|
|
2
2
|
import RNScreens
|
|
3
3
|
|
|
4
|
-
class NativeLinkPreviewView:
|
|
4
|
+
class NativeLinkPreviewView: RouterViewWithLogger, UIContextMenuInteractionDelegate,
|
|
5
5
|
RNSDismissibleModalProtocol, LinkPreviewMenuUpdatable {
|
|
6
6
|
private var preview: NativeLinkPreviewContentView?
|
|
7
7
|
private var interaction: UIContextMenuInteraction?
|
|
@@ -19,7 +19,7 @@ class NativeLinkPreviewView: ExpoView, UIContextMenuInteractionDelegate,
|
|
|
19
19
|
private var actions: [LinkPreviewNativeActionView] = []
|
|
20
20
|
|
|
21
21
|
private lazy var linkPreviewNativeNavigation: LinkPreviewNativeNavigation = {
|
|
22
|
-
return LinkPreviewNativeNavigation(logger:
|
|
22
|
+
return LinkPreviewNativeNavigation(logger: logger)
|
|
23
23
|
}()
|
|
24
24
|
|
|
25
25
|
let onPreviewTapped = EventDispatcher()
|
|
@@ -53,64 +53,62 @@ class NativeLinkPreviewView: ExpoView, UIContextMenuInteractionDelegate,
|
|
|
53
53
|
}
|
|
54
54
|
|
|
55
55
|
// MARK: - Children
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
56
|
+
override func mountChildComponentView(_ childComponentView: UIView, index: Int) {
|
|
57
|
+
if let previewView = childComponentView as? NativeLinkPreviewContentView {
|
|
58
|
+
preview = previewView
|
|
59
|
+
} else if let actionView = childComponentView as? LinkPreviewNativeActionView {
|
|
60
|
+
actionView.parentMenuUpdatable = self
|
|
61
|
+
actions.append(actionView)
|
|
62
|
+
} else {
|
|
63
|
+
if directChild != nil {
|
|
64
|
+
logger?.warn(
|
|
65
|
+
"[expo-router] Found a second child of <Link.Trigger>. Only one is allowed. This is most likely a bug in expo-router."
|
|
66
|
+
)
|
|
67
|
+
return
|
|
68
|
+
}
|
|
69
|
+
directChild = childComponentView
|
|
70
|
+
if let interaction = self.interaction {
|
|
71
|
+
if let indirectTrigger = childComponentView as? LinkPreviewIndirectTriggerProtocol {
|
|
72
|
+
indirectTrigger.indirectTrigger?.addInteraction(interaction)
|
|
73
|
+
} else {
|
|
74
|
+
childComponentView.addInteraction(interaction)
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
super.mountChildComponentView(childComponentView, index: index)
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
override func unmountChildComponentView(_ child: UIView, index: Int) {
|
|
82
|
+
if child is NativeLinkPreviewContentView {
|
|
83
|
+
preview = nil
|
|
84
|
+
} else if let actionView = child as? LinkPreviewNativeActionView {
|
|
85
|
+
actions.removeAll(where: {
|
|
86
|
+
$0 == actionView
|
|
87
|
+
})
|
|
88
|
+
} else {
|
|
89
|
+
if let directChild = directChild {
|
|
90
|
+
if directChild != child {
|
|
91
|
+
logger?.warn(
|
|
92
|
+
"[expo-router] Unmounting unexpected child from <Link.Trigger>. This is most likely a bug in expo-router."
|
|
67
93
|
)
|
|
68
94
|
return
|
|
69
95
|
}
|
|
70
|
-
directChild = childComponentView
|
|
71
96
|
if let interaction = self.interaction {
|
|
72
|
-
if let indirectTrigger =
|
|
73
|
-
indirectTrigger.indirectTrigger?.
|
|
97
|
+
if let indirectTrigger = directChild as? LinkPreviewIndirectTriggerProtocol {
|
|
98
|
+
indirectTrigger.indirectTrigger?.removeInteraction(interaction)
|
|
74
99
|
} else {
|
|
75
|
-
|
|
100
|
+
directChild.removeInteraction(interaction)
|
|
76
101
|
}
|
|
77
102
|
}
|
|
78
|
-
super.
|
|
79
|
-
}
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
override func unmountChildComponentView(_ child: UIView, index: Int) {
|
|
83
|
-
if child is NativeLinkPreviewContentView {
|
|
84
|
-
preview = nil
|
|
85
|
-
} else if let actionView = child as? LinkPreviewNativeActionView {
|
|
86
|
-
actions.removeAll(where: {
|
|
87
|
-
$0 == actionView
|
|
88
|
-
})
|
|
103
|
+
super.unmountChildComponentView(child, index: index)
|
|
89
104
|
} else {
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
)
|
|
95
|
-
return
|
|
96
|
-
}
|
|
97
|
-
if let interaction = self.interaction {
|
|
98
|
-
if let indirectTrigger = directChild as? LinkPreviewIndirectTriggerProtocol {
|
|
99
|
-
indirectTrigger.indirectTrigger?.removeInteraction(interaction)
|
|
100
|
-
} else {
|
|
101
|
-
directChild.removeInteraction(interaction)
|
|
102
|
-
}
|
|
103
|
-
}
|
|
104
|
-
super.unmountChildComponentView(child, index: index)
|
|
105
|
-
} else {
|
|
106
|
-
print(
|
|
107
|
-
"[expo-router] No link child found to unmount. This is most likely a bug in expo-router."
|
|
108
|
-
)
|
|
109
|
-
return
|
|
110
|
-
}
|
|
105
|
+
logger?.warn(
|
|
106
|
+
"[expo-router] No link child found to unmount. This is most likely a bug in expo-router."
|
|
107
|
+
)
|
|
108
|
+
return
|
|
111
109
|
}
|
|
112
110
|
}
|
|
113
|
-
|
|
111
|
+
}
|
|
114
112
|
|
|
115
113
|
// MARK: - UIContextMenuInteractionDelegate
|
|
116
114
|
|
|
@@ -244,7 +244,7 @@ class LinkZoomTransitionAlignmentRectDetector: LinkZoomExpoView {
|
|
|
244
244
|
) {
|
|
245
245
|
guard child == nil else {
|
|
246
246
|
logger?.warn(
|
|
247
|
-
"[expo-router] Link.AppleZoomTarget can only have a single native child."
|
|
247
|
+
"[expo-router] Link.AppleZoomTarget can only have a single native child. If you passed a single child, consider adding collapsible={false} to your component"
|
|
248
248
|
)
|
|
249
249
|
return
|
|
250
250
|
}
|
|
@@ -287,7 +287,7 @@ class LinkZoomTransitionEnabler: LinkZoomExpoView {
|
|
|
287
287
|
|
|
288
288
|
private func setupZoomTransition() {
|
|
289
289
|
if self.zoomTransitionSourceIdentifier.isEmpty {
|
|
290
|
-
|
|
290
|
+
logger?.warn("[expo-router] No zoomTransitionSourceIdentifier passed to LinkZoomTransitionEnabler. This is most likely a bug in expo-router.")
|
|
291
291
|
return
|
|
292
292
|
}
|
|
293
293
|
if let controller = self.findViewController() {
|
|
@@ -329,8 +329,8 @@ class LinkZoomTransitionEnabler: LinkZoomExpoView {
|
|
|
329
329
|
view = linkPreviewView.directChild
|
|
330
330
|
}
|
|
331
331
|
guard let view else {
|
|
332
|
-
|
|
333
|
-
"[expo-router] No source view found for identifier \(self.zoomTransitionSourceIdentifier) to enable zoom transition"
|
|
332
|
+
self.logger?.warn(
|
|
333
|
+
"[expo-router] No source view found for identifier \(self.zoomTransitionSourceIdentifier) to enable zoom transition. This is most likely a bug in expo-router."
|
|
334
334
|
)
|
|
335
335
|
return nil
|
|
336
336
|
}
|
|
@@ -339,7 +339,7 @@ class LinkZoomTransitionEnabler: LinkZoomExpoView {
|
|
|
339
339
|
return
|
|
340
340
|
}
|
|
341
341
|
} else {
|
|
342
|
-
|
|
342
|
+
logger?.warn("[expo-router] No navigation controller found to enable zoom transition. This is most likely a bug in expo-router.")
|
|
343
343
|
}
|
|
344
344
|
}
|
|
345
345
|
|
|
@@ -390,7 +390,7 @@ class LinkZoomTransitionEnabler: LinkZoomExpoView {
|
|
|
390
390
|
}
|
|
391
391
|
}
|
|
392
392
|
|
|
393
|
-
class LinkZoomExpoView:
|
|
393
|
+
class LinkZoomExpoView: RouterViewWithLogger {
|
|
394
394
|
var module: LinkPreviewNativeModule? {
|
|
395
395
|
return appContext?.moduleRegistry.get(moduleWithName: LinkPreviewNativeModule.moduleName)
|
|
396
396
|
as? LinkPreviewNativeModule
|
|
@@ -398,7 +398,7 @@ class LinkZoomExpoView: ExpoView {
|
|
|
398
398
|
|
|
399
399
|
var sourceRepository: LinkZoomTransitionsSourceRepository? {
|
|
400
400
|
guard let module else {
|
|
401
|
-
|
|
401
|
+
logger?.warn("[expo-router] LinkPreviewNativeModule not loaded. Make sure expo-router is properly configured.")
|
|
402
402
|
return nil
|
|
403
403
|
}
|
|
404
404
|
return module.zoomSourceRepository
|
|
@@ -406,11 +406,9 @@ class LinkZoomExpoView: ExpoView {
|
|
|
406
406
|
|
|
407
407
|
var alignmentViewRepository: LinkZoomTransitionsAlignmentViewRepository? {
|
|
408
408
|
guard let module else {
|
|
409
|
-
|
|
409
|
+
logger?.warn("[expo-router] LinkPreviewNativeModule not loaded. Make sure expo-router is properly configured.")
|
|
410
410
|
return nil
|
|
411
411
|
}
|
|
412
412
|
return module.zoomAlignmentViewRepository
|
|
413
413
|
}
|
|
414
|
-
|
|
415
|
-
lazy var logger = appContext?.jsLogger
|
|
416
414
|
}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import React
|
|
2
|
+
import UIKit
|
|
3
|
+
|
|
4
|
+
struct RouterFontUtils {
|
|
5
|
+
static func convertTitleStyleToFont(_ titleStyle: TitleStyle) -> UIFont {
|
|
6
|
+
let fontFamily = titleStyle.fontFamily
|
|
7
|
+
let fontWeight = titleStyle.fontWeight
|
|
8
|
+
|
|
9
|
+
let resolvedFontSize = resolveFontSize(titleStyle.fontSize)
|
|
10
|
+
|
|
11
|
+
if fontFamily != nil || fontWeight != nil {
|
|
12
|
+
return RCTFont.update(
|
|
13
|
+
nil,
|
|
14
|
+
withFamily: fontFamily,
|
|
15
|
+
size: NSNumber(value: Float(resolvedFontSize)),
|
|
16
|
+
weight: fontWeight,
|
|
17
|
+
style: nil,
|
|
18
|
+
variant: nil,
|
|
19
|
+
scaleMultiplier: 1.0)
|
|
20
|
+
}
|
|
21
|
+
return UIFont.systemFont(ofSize: resolvedFontSize)
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
static func setTitleStyle(fromConfig titleStyle: TitleStyle, for item: UIBarButtonItem) {
|
|
25
|
+
var attrs: [NSAttributedString.Key: Any] = [:]
|
|
26
|
+
|
|
27
|
+
attrs[.font] = convertTitleStyleToFont(titleStyle)
|
|
28
|
+
|
|
29
|
+
if let color = titleStyle.color {
|
|
30
|
+
attrs[.foregroundColor] = color
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
item.setTitleTextAttributes(attrs, for: .normal)
|
|
34
|
+
item.setTitleTextAttributes(attrs, for: .highlighted)
|
|
35
|
+
item.setTitleTextAttributes(attrs, for: .disabled)
|
|
36
|
+
item.setTitleTextAttributes(attrs, for: .selected)
|
|
37
|
+
item.setTitleTextAttributes(attrs, for: .focused)
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
private static func resolveFontSize(_ fontSize: Double?) -> CGFloat {
|
|
41
|
+
if let fontSize = fontSize {
|
|
42
|
+
return CGFloat(fontSize)
|
|
43
|
+
}
|
|
44
|
+
#if os(tvOS)
|
|
45
|
+
return 17.0
|
|
46
|
+
#else
|
|
47
|
+
return UIFont.labelFontSize
|
|
48
|
+
#endif
|
|
49
|
+
}
|
|
50
|
+
}
|
|
@@ -2,16 +2,12 @@ import ExpoModulesCore
|
|
|
2
2
|
import RNScreens
|
|
3
3
|
import UIKit
|
|
4
4
|
|
|
5
|
-
class RouterToolbarHostView:
|
|
5
|
+
class RouterToolbarHostView: RouterViewWithLogger, LinkPreviewMenuUpdatable {
|
|
6
6
|
// Mutable map of toolbar items
|
|
7
7
|
var toolbarItemsArray: [String] = []
|
|
8
8
|
var toolbarItemsMap: [String: RouterToolbarItemView] = [:]
|
|
9
9
|
var menuItemsMap: [String: LinkPreviewNativeActionView] = [:]
|
|
10
10
|
|
|
11
|
-
required init(appContext: AppContext? = nil) {
|
|
12
|
-
super.init(appContext: appContext)
|
|
13
|
-
}
|
|
14
|
-
|
|
15
11
|
private func addRouterToolbarItemAtIndex(
|
|
16
12
|
_ item: RouterToolbarItemView,
|
|
17
13
|
index: Int
|
|
@@ -56,6 +52,7 @@ class RouterToolbarHostView: ExpoView, LinkPreviewMenuUpdatable {
|
|
|
56
52
|
if let item = toolbarItemsMap[$0] {
|
|
57
53
|
return item.barButtonItem
|
|
58
54
|
}
|
|
55
|
+
// TODO: Extract this logic to separate function
|
|
59
56
|
if let menu = menuItemsMap[$0] {
|
|
60
57
|
let item = UIBarButtonItem(
|
|
61
58
|
title: menu.title,
|
|
@@ -65,10 +62,35 @@ class RouterToolbarHostView: ExpoView, LinkPreviewMenuUpdatable {
|
|
|
65
62
|
)
|
|
66
63
|
// Otherwise, the menu items will be reversed in the toolbar
|
|
67
64
|
item.preferredMenuElementOrder = .fixed
|
|
65
|
+
if #available(iOS 26.0, *) {
|
|
66
|
+
if let hidesSharedBackground = menu.hidesSharedBackground {
|
|
67
|
+
item.hidesSharedBackground = hidesSharedBackground
|
|
68
|
+
}
|
|
69
|
+
if let sharesBackground = menu.sharesBackground {
|
|
70
|
+
item.sharesBackground = sharesBackground
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
if let titleStyle = menu.titleStyle {
|
|
74
|
+
RouterFontUtils.setTitleStyle(fromConfig: titleStyle, for: item)
|
|
75
|
+
}
|
|
76
|
+
item.isHidden = menu.routerHidden
|
|
77
|
+
item.isEnabled = !menu.disabled
|
|
78
|
+
if let accessibilityLabel = menu.accessibilityLabelForMenu {
|
|
79
|
+
item.accessibilityLabel = accessibilityLabel
|
|
80
|
+
} else {
|
|
81
|
+
item.accessibilityLabel = menu.title
|
|
82
|
+
}
|
|
83
|
+
if let accessibilityHint = menu.accessibilityHintForMenu {
|
|
84
|
+
item.accessibilityHint = accessibilityHint
|
|
85
|
+
}
|
|
86
|
+
item.tintColor = menu.customTintColor
|
|
87
|
+
if let style = menu.barButtonItemStyle {
|
|
88
|
+
item.style = style
|
|
89
|
+
}
|
|
68
90
|
return item
|
|
69
91
|
}
|
|
70
|
-
|
|
71
|
-
"[expo-router] Warning: Could not find toolbar item or menu for identifier \($0)"
|
|
92
|
+
logger?.warn(
|
|
93
|
+
"[expo-router] Warning: Could not find toolbar item or menu for identifier \($0). This is most likely a bug in expo-router."
|
|
72
94
|
)
|
|
73
95
|
return nil
|
|
74
96
|
}, animated: true)
|
|
@@ -76,16 +98,15 @@ class RouterToolbarHostView: ExpoView, LinkPreviewMenuUpdatable {
|
|
|
76
98
|
false, animated: true)
|
|
77
99
|
return
|
|
78
100
|
}
|
|
79
|
-
} else {
|
|
80
|
-
print(
|
|
81
|
-
"[expo-router] Warning: Could not find owning UIViewController for RouterToolbarHostView")
|
|
82
101
|
}
|
|
83
102
|
}
|
|
84
103
|
|
|
85
104
|
override func mountChildComponentView(_ childComponentView: UIView, index: Int) {
|
|
86
105
|
if let toolbarItem = childComponentView as? RouterToolbarItemView {
|
|
87
106
|
if toolbarItem.identifier.isEmpty {
|
|
88
|
-
|
|
107
|
+
logger?.warn(
|
|
108
|
+
"[expo-router] RouterToolbarItemView identifier is empty. This is most likely a bug in expo-router."
|
|
109
|
+
)
|
|
89
110
|
return
|
|
90
111
|
}
|
|
91
112
|
addRouterToolbarItemAtIndex(toolbarItem, index: index)
|
|
@@ -93,8 +114,8 @@ class RouterToolbarHostView: ExpoView, LinkPreviewMenuUpdatable {
|
|
|
93
114
|
menu.parentMenuUpdatable = self
|
|
94
115
|
addMenuToolbarItemAtIndex(menu, index: index)
|
|
95
116
|
} else {
|
|
96
|
-
|
|
97
|
-
"
|
|
117
|
+
logger?.warn(
|
|
118
|
+
"[expo-router] Unknown child component view (\(childComponentView)) mounted to RouterToolbarHost. This is most likely a bug in expo-router."
|
|
98
119
|
)
|
|
99
120
|
}
|
|
100
121
|
updateToolbarItems()
|
|
@@ -103,19 +124,22 @@ class RouterToolbarHostView: ExpoView, LinkPreviewMenuUpdatable {
|
|
|
103
124
|
override func unmountChildComponentView(_ childComponentView: UIView, index: Int) {
|
|
104
125
|
if let toolbarItem = childComponentView as? RouterToolbarItemView {
|
|
105
126
|
if toolbarItem.identifier.isEmpty {
|
|
106
|
-
|
|
127
|
+
logger?.warn(
|
|
128
|
+
"[expo-router] RouterToolbarItemView identifier is empty. This is most likely a bug in expo-router."
|
|
129
|
+
)
|
|
107
130
|
return
|
|
108
131
|
}
|
|
109
132
|
removeToolbarItemWithId(toolbarItem.identifier)
|
|
110
133
|
} else if let menu = childComponentView as? LinkPreviewNativeActionView {
|
|
111
134
|
if menu.identifier.isEmpty {
|
|
112
|
-
|
|
135
|
+
logger?.warn(
|
|
136
|
+
"[expo-router] Menu identifier is empty. This is most likely a bug in expo-router.")
|
|
113
137
|
return
|
|
114
138
|
}
|
|
115
139
|
removeToolbarItemWithId(menu.identifier)
|
|
116
140
|
} else {
|
|
117
|
-
|
|
118
|
-
"
|
|
141
|
+
logger?.warn(
|
|
142
|
+
"[expo-router] Unknown child component view (\(childComponentView)) unmounted from RouterToolbarHost. This is most likely a bug in expo-router."
|
|
119
143
|
)
|
|
120
144
|
}
|
|
121
145
|
updateToolbarItems()
|
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
import ExpoModulesCore
|
|
2
|
-
import React
|
|
3
2
|
import UIKit
|
|
4
3
|
|
|
5
|
-
class RouterToolbarItemView:
|
|
4
|
+
class RouterToolbarItemView: RouterViewWithLogger {
|
|
6
5
|
var identifier: String = ""
|
|
7
6
|
@ReactiveProp var type: ItemType?
|
|
8
7
|
@ReactiveProp var title: String?
|
|
@@ -18,6 +17,10 @@ class RouterToolbarItemView: ExpoView {
|
|
|
18
17
|
@ReactiveProp var selected: Bool = false
|
|
19
18
|
@ReactiveProp var possibleTitles: Set<String>?
|
|
20
19
|
@ReactiveProp var badgeConfiguration: BadgeConfiguration?
|
|
20
|
+
@ReactiveProp var titleStyle: TitleStyle?
|
|
21
|
+
@ReactiveProp var routerAccessibilityLabel: String?
|
|
22
|
+
@ReactiveProp var routerAccessibilityHint: String?
|
|
23
|
+
@ReactiveProp var disabled: Bool = false
|
|
21
24
|
|
|
22
25
|
var host: RouterToolbarHostView?
|
|
23
26
|
|
|
@@ -50,6 +53,9 @@ class RouterToolbarItemView: ExpoView {
|
|
|
50
53
|
if let tintColor = customTintColor {
|
|
51
54
|
item.tintColor = tintColor
|
|
52
55
|
}
|
|
56
|
+
if let titleStyle {
|
|
57
|
+
RouterFontUtils.setTitleStyle(fromConfig: titleStyle, for: item)
|
|
58
|
+
}
|
|
53
59
|
}
|
|
54
60
|
if #available(iOS 26.0, *) {
|
|
55
61
|
item.hidesSharedBackground = hidesSharedBackground
|
|
@@ -67,6 +73,13 @@ class RouterToolbarItemView: ExpoView {
|
|
|
67
73
|
item.isHidden = routerHidden
|
|
68
74
|
}
|
|
69
75
|
item.isSelected = selected
|
|
76
|
+
if let routerAccessibilityLabel = routerAccessibilityLabel {
|
|
77
|
+
item.accessibilityLabel = routerAccessibilityLabel
|
|
78
|
+
}
|
|
79
|
+
if let routerAccessibilityHint = routerAccessibilityHint {
|
|
80
|
+
item.accessibilityHint = routerAccessibilityHint
|
|
81
|
+
}
|
|
82
|
+
item.isEnabled = !disabled
|
|
70
83
|
if #available(iOS 26.0, *) {
|
|
71
84
|
if let badgeConfig = badgeConfiguration {
|
|
72
85
|
var badge = UIBarButtonItem.Badge.indicator()
|
|
@@ -81,17 +94,14 @@ class RouterToolbarItemView: ExpoView {
|
|
|
81
94
|
}
|
|
82
95
|
if badgeConfig.fontFamily != nil || badgeConfig.fontSize != nil
|
|
83
96
|
|| badgeConfig.fontWeight != nil {
|
|
84
|
-
let font =
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
variant: nil,
|
|
91
|
-
scaleMultiplier: 1.0)
|
|
97
|
+
let font = RouterFontUtils.convertTitleStyleToFont(
|
|
98
|
+
TitleStyle(
|
|
99
|
+
fontFamily: badgeConfig.fontFamily,
|
|
100
|
+
fontSize: badgeConfig.fontSize,
|
|
101
|
+
fontWeight: badgeConfig.fontWeight
|
|
102
|
+
))
|
|
92
103
|
badge.font = font
|
|
93
104
|
}
|
|
94
|
-
// TODO: Find out why this does not work
|
|
95
105
|
item.badge = badge
|
|
96
106
|
}
|
|
97
107
|
}
|
|
@@ -105,8 +115,8 @@ class RouterToolbarItemView: ExpoView {
|
|
|
105
115
|
|
|
106
116
|
override func mountChildComponentView(_ childComponentView: UIView, index: Int) {
|
|
107
117
|
if customView != nil {
|
|
108
|
-
|
|
109
|
-
"[expo-router]
|
|
118
|
+
logger?.warn(
|
|
119
|
+
"[expo-router] RouterToolbarItemView can only have one child view. This is most likely a bug in expo-router."
|
|
110
120
|
)
|
|
111
121
|
return
|
|
112
122
|
}
|
|
@@ -138,6 +148,13 @@ struct BadgeConfiguration: Equatable {
|
|
|
138
148
|
var fontWeight: String?
|
|
139
149
|
}
|
|
140
150
|
|
|
151
|
+
struct TitleStyle: Equatable {
|
|
152
|
+
var fontFamily: String?
|
|
153
|
+
var fontSize: Double?
|
|
154
|
+
var fontWeight: String?
|
|
155
|
+
var color: UIColor?
|
|
156
|
+
}
|
|
157
|
+
|
|
141
158
|
@propertyWrapper
|
|
142
159
|
struct ReactiveProp<Value: Equatable> {
|
|
143
160
|
private var value: Value
|
|
@@ -57,6 +57,18 @@ public class RouterToolbarModule: Module {
|
|
|
57
57
|
(view: RouterToolbarItemView, config: BadgeConfigurationRecord?) in
|
|
58
58
|
view.badgeConfiguration = config?.toBadgeConfiguration()
|
|
59
59
|
}
|
|
60
|
+
Prop("titleStyle") { (view: RouterToolbarItemView, style: TitleStyleRecord?) in
|
|
61
|
+
view.titleStyle = style?.toTitleStyle()
|
|
62
|
+
}
|
|
63
|
+
Prop("accessibilityLabel") { (view: RouterToolbarItemView, accessibilityLabel: String?) in
|
|
64
|
+
view.accessibilityLabel = accessibilityLabel
|
|
65
|
+
}
|
|
66
|
+
Prop("accessibilityHint") { (view: RouterToolbarItemView, accessibilityHint: String?) in
|
|
67
|
+
view.accessibilityHint = accessibilityHint
|
|
68
|
+
}
|
|
69
|
+
Prop("disabled") { (view: RouterToolbarItemView, disabled: Bool?) in
|
|
70
|
+
view.disabled = disabled ?? false
|
|
71
|
+
}
|
|
60
72
|
|
|
61
73
|
Events("onSelected")
|
|
62
74
|
}
|
|
@@ -100,3 +112,19 @@ struct BadgeConfigurationRecord: Record {
|
|
|
100
112
|
)
|
|
101
113
|
}
|
|
102
114
|
}
|
|
115
|
+
|
|
116
|
+
struct TitleStyleRecord: Record {
|
|
117
|
+
@Field var fontFamily: String?
|
|
118
|
+
@Field var fontSize: Double?
|
|
119
|
+
@Field var fontWeight: String?
|
|
120
|
+
@Field var color: UIColor?
|
|
121
|
+
|
|
122
|
+
func toTitleStyle() -> TitleStyle {
|
|
123
|
+
return TitleStyle(
|
|
124
|
+
fontFamily: fontFamily,
|
|
125
|
+
fontSize: fontSize,
|
|
126
|
+
fontWeight: fontWeight,
|
|
127
|
+
color: color
|
|
128
|
+
)
|
|
129
|
+
}
|
|
130
|
+
}
|
|
Binary file
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
8c916bee60640e0b60daed543761abd9
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
5fa5e3051c154802f07905f47f18a306d7262425
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
054876f9b960d2ed5b7762c66b32c7e994f942c05013456f5e41e1fe6c71ee54
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
0c996832cda246cbf02acf875f7c3add8610a0e5e7c466bbe5fa2f073a6a644933eec90d1bff2a7fac7fd3c0c5bdae8a695373cebdec4f9853ce116658960554
|