11import SwiftUI
2+ import React
23
34/**
45 This SwiftUI struct returns main React Native scene. It should be used only once as it conains setup code.
@@ -21,25 +22,67 @@ public struct RCTMainWindow: Scene {
2122 var moduleName : String
2223 var initialProps : RCTRootViewRepresentable . InitialPropsType
2324 var onOpenURLCallback : ( ( URL ) -> ( ) ) ?
25+ var devMenuPlacement : ToolbarPlacement = . bottomOrnament
26+ var contentView : AnyView ?
2427
25- public init ( moduleName: String , initialProps: RCTRootViewRepresentable . InitialPropsType = nil ) {
28+ var rootView : RCTRootViewRepresentable {
29+ RCTRootViewRepresentable ( moduleName: moduleName, initialProps: initialProps)
30+ }
31+
32+ /// Creates new RCTMainWindowWindow.
33+ ///
34+ /// - Parameters:
35+ /// - moduleName: Name of the module registered using `AppRegistry.registerComponent()`
36+ /// - initialProps: Initial properties for this view.
37+ /// - devMenuPlacement: Placement of the additional controls for triggering reload command and dev menu trigger.
38+ public init (
39+ moduleName: String ,
40+ initialProps: RCTRootViewRepresentable . InitialPropsType = nil ,
41+ devMenuPlacement: ToolbarPlacement = . bottomOrnament
42+ ) {
43+ self . moduleName = moduleName
44+ self . initialProps = initialProps
45+ self . devMenuPlacement = devMenuPlacement
46+ self . contentView = AnyView ( rootView)
47+ }
48+
49+ /// Creates new RCTMainWindowWindow.
50+ ///
51+ /// - Parameters:
52+ /// - moduleName: Name of the module registered using `AppRegistry.registerComponent()`
53+ /// - initialProps: Initial properties for this view.
54+ /// - devMenuPlacement: Placement of the additional controls for triggering reload command and dev menu trigger.
55+ /// - contentView: Closure which accepts rootView, allows to apply additional modifiers to React Native rootView.
56+ public init < Content: View > (
57+ moduleName: String ,
58+ initialProps: RCTRootViewRepresentable . InitialPropsType = nil ,
59+ devMenuPlacement: ToolbarPlacement = . bottomOrnament,
60+ @ViewBuilder contentView: @escaping ( _ view: RCTRootViewRepresentable ) -> Content
61+ ) {
2662 self . moduleName = moduleName
2763 self . initialProps = initialProps
64+ self . devMenuPlacement = devMenuPlacement
65+ self . contentView = AnyView ( contentView ( rootView) )
2866 }
2967
3068 public var body : some Scene {
3169 WindowGroup {
32- RCTRootViewRepresentable ( moduleName : moduleName , initialProps : initialProps )
70+ contentView
3371 . modifier ( WindowHandlingModifier ( ) )
3472 . onOpenURL ( perform: { url in
3573 onOpenURLCallback ? ( url)
3674 } )
75+ #if DEBUG
76+ . toolbar {
77+ DevMenuView ( placement: . bottomOrnament)
78+ }
79+ #endif
3780 }
3881 }
3982}
4083
4184extension RCTMainWindow {
42- public func onOpenURL( perform action: @escaping ( URL ) -> ( ) ) -> some Scene {
85+ public func onOpenURL( perform action: @escaping ( URL ) -> ( ) ) -> Self {
4386 var scene = self
4487 scene. onOpenURLCallback = action
4588 return scene
@@ -95,3 +138,30 @@ public struct WindowHandlingModifier: ViewModifier {
95138 }
96139 }
97140}
141+
142+ /**
143+ Toolbar which displays additional controls to easily open dev menu and trigger reload command.
144+ */
145+ struct DevMenuView : ToolbarContent {
146+ let placement : ToolbarItemPlacement
147+
148+ var body : some ToolbarContent {
149+ ToolbarItem ( placement: placement) {
150+ Button ( action: {
151+ RCTTriggerReloadCommandListeners ( " User Reload " )
152+ } , label: {
153+ Image ( systemName: " arrow.clockwise " )
154+ } )
155+ }
156+ ToolbarItem ( placement: placement) {
157+ Button ( action: {
158+ NotificationCenter . default. post (
159+ Notification ( name: Notification . Name ( " RCTShowDevMenuNotification " ) , object: nil )
160+ )
161+ } ,
162+ label: {
163+ Image ( systemName: " filemenu.and.selection " )
164+ } )
165+ }
166+ }
167+ }
0 commit comments