diff --git a/Documentation.docc/Documentation.md b/Documentation.docc/Documentation.md deleted file mode 100644 index b791a00..0000000 --- a/Documentation.docc/Documentation.md +++ /dev/null @@ -1,87 +0,0 @@ -# ``Navigate`` - -Navigate is a Swift navigation library that enables high-level modularization using `NavigationDestination` protocol. It introduces `ModalStack`, which works exactly like SwiftUI `NavigationStack` and allows you to display multiple **Sheets** and **FullScreenCovers** on top of each other. - -## Overview - -Define your possible destinations in a higher level package in one or more enums. - -```swift -import Navigate - -public enum MainNavigationDestination: NavigationDestination { - case home - case detailCard(id: Int) - case settings - - public var id: Self { self } -} -``` - -Those `MainNavigationDestination` need to be applied to the first element within a `NavigationStack`. - -```swift -import Navigate - -// Import your corresponding views if needed -import FeatureHome -import FeatureCard -import FeatureSettings - -extension View { - func navigationDestinationMain() -> some View { - navigationDestination(for: MainNavigationDestination.self) { destination in - switch destination { - case .home: HomeView() - case .detailCard(let id): DetailCard(for: id) - case .settings: SettingsView() - } - } - } -} -``` - -Example View: - -```swift -struct ContentView: View { - var body: some View { - NavigationStack { - MainView() - .navigationDestinationMain() - } - } -} -``` - -Use it in NavigationLink and sheet - -```swift -struct MainView: View { - - @State - var showSheet = false - - var body: some View { - List { - NavigationLink( - destination: NewsNavigationDestination.detailCard(id: 1) - ) { - Text("Click me") - } - } - .sheet( - destination: MainNavigationDestination.settings, - isPresented: $showSheet - ) - } -} -``` - -The `.sheet(...)` and `.fullScreenCover(...)` modifier also contain some convenience paramters like `withNavigationStack` or `onDismiss`. - -## Topics - -### Group - -- ``NavigationDestination`` diff --git a/NavigateTesting/NavigateTesting/Assets.xcassets/AccentColor.colorset/Contents.json b/NavigateTesting/NavigateTesting/Assets.xcassets/AccentColor.colorset/Contents.json index eb87897..bb57667 100644 --- a/NavigateTesting/NavigateTesting/Assets.xcassets/AccentColor.colorset/Contents.json +++ b/NavigateTesting/NavigateTesting/Assets.xcassets/AccentColor.colorset/Contents.json @@ -1,6 +1,10 @@ { "colors" : [ { + "color" : { + "platform" : "universal", + "reference" : "systemMintColor" + }, "idiom" : "universal" } ], diff --git a/NavigateTesting/NavigateTesting/ContentView.swift b/NavigateTesting/NavigateTesting/ContentView.swift index 50e11dc..5829573 100644 --- a/NavigateTesting/NavigateTesting/ContentView.swift +++ b/NavigateTesting/NavigateTesting/ContentView.swift @@ -11,7 +11,7 @@ import SwiftUI struct ContentView: View { @State - var router = Router() + private var router = Router() var body: some View { ModalStack(path: $router.modalPath) { @@ -20,46 +20,32 @@ struct ContentView: View { NavigationStack(path: $router.homeTabPath) { FeatureAView() .myNavigtationDestinations() + .toolbar { + ToolbarItem(placement: .topBarTrailing) { + SheetLink(destination: .settings) { + Image(systemName: "gearshape") + } + } + } } } - Tab("Tab", systemImage: "pencil", value: .tab) { + Tab("Feature B", systemImage: "pencil", value: .tab) { NavigationStack(path: $router.tabPath) { - FeatureAView() - .myNavigtationDestinations() - } - } - } - .modalDestination(for: MyDestination.self) { destination in - switch destination { - case .featureA: - NavigationStack { - FeatureAView() - .myNavigtationDestinations() - } - case .featureB: - NavigationStack { FeatureBView() .myNavigtationDestinations() } - case .settings: - NavigationStack { - SettingsView() - .myNavigtationDestinations() - } - case .subSettings: - NavigationStack { - SubSettingsView() - .myNavigtationDestinations() - } } } + .myModalDestinations() } .environment(router) } } extension View { + + /// SwiftUI navigation destination convenience func myNavigtationDestinations() -> some View { self.navigationDestination(for: MyDestination.self) { destination in switch destination { @@ -67,10 +53,52 @@ extension View { FeatureAView() case .featureB: FeatureBView() + case .featureC: + FeatureCView() + case .featureD: + FeatureDView() case .settings: SettingsView() - case .subSettings: - SubSettingsView() + case .profile: + ProfileView() + } + } + } + + /// All ModalDestinations wrapped in NavigationStack to support SwiftUI navigation and toolbar + func myModalDestinations() -> some View { + self.modalDestination(for: MyDestination.self) { destination in + switch destination { + case .featureA: + NavigationStack { + FeatureAView() + .myNavigtationDestinations() + } + case .featureB: + NavigationStack { + FeatureBView() + .myNavigtationDestinations() + } + case .featureC: + NavigationStack { + FeatureCView() + .myNavigtationDestinations() + } + case .featureD: + NavigationStack { + FeatureDView() + .myNavigtationDestinations() + } + case .settings: + NavigationStack { + SettingsView() + .myNavigtationDestinations() + } + case .profile: + NavigationStack { + ProfileView() + .myNavigtationDestinations() + } } } } diff --git a/NavigateTesting/NavigateTesting/Features/FeatureAView.swift b/NavigateTesting/NavigateTesting/Features/FeatureAView.swift index 379f4b3..05fef2b 100644 --- a/NavigateTesting/NavigateTesting/Features/FeatureAView.swift +++ b/NavigateTesting/NavigateTesting/Features/FeatureAView.swift @@ -10,19 +10,21 @@ import SwiftUI struct FeatureAView: View { var body: some View { - Text("Feature A") - - NavigationLink(destination: .featureB) { - Text("Go to feature b") - } - - SheetLink(destination: .featureB) { - Text("Sheet to feature b") - } - - FullScreenCoverLink(destination: .settings) { - Text("Go to settings :)") + List { + NavigationLink(destination: .featureB) { + Text("Go to feature B") + } + + SheetLink(destination: .featureB) { + Text("Sheet to feature B") + } + + FullScreenCoverLink(destination: .featureB) { + Text("FullScreenCover to feature B") + } } + .navigationTitle("Feature A") + .navigationBarTitleDisplayMode(.inline) } } diff --git a/NavigateTesting/NavigateTesting/Features/FeatureBView.swift b/NavigateTesting/NavigateTesting/Features/FeatureBView.swift index c2e5c2c..f5f0e0f 100644 --- a/NavigateTesting/NavigateTesting/Features/FeatureBView.swift +++ b/NavigateTesting/NavigateTesting/Features/FeatureBView.swift @@ -14,17 +14,21 @@ struct FeatureBView: View { var router: Router var body: some View { - Text("Feature B") - - SheetLink(destination: .featureB) { - Text("Feature B again ...") - } - - Button("Dismiss all") { - router.homeTabPath = [] - router.tabPath = [] - router.modalPath = [] + List { + NavigationLink(destination: .featureC) { + Text("Go to feature C") + } + + SheetLink(destination: .featureC) { + Text("Sheet to feature C") + } + + FullScreenCoverLink(destination: .featureC) { + Text("FullScreenCover to feature C") + } } + .navigationTitle("Feature B") + .navigationBarTitleDisplayMode(.inline) } } diff --git a/NavigateTesting/NavigateTesting/Features/FeatureCView.swift b/NavigateTesting/NavigateTesting/Features/FeatureCView.swift new file mode 100644 index 0000000..fd79047 --- /dev/null +++ b/NavigateTesting/NavigateTesting/Features/FeatureCView.swift @@ -0,0 +1,37 @@ +// +// FeatureCView.swift +// NavigateTesting +// +// Created by Alexander Kauer on 17.07.25. +// + +import Navigate +import SwiftUI + +struct FeatureCView: View { + + @Environment(Router.self) + var router: Router + + var body: some View { + List { + NavigationLink(destination: .featureD) { + Text("Go to feature D") + } + + SheetLink(destination: .featureD) { + Text("Sheet to feature D") + } + + FullScreenCoverLink(destination: .featureD) { + Text("FullScreenCover to feature D") + } + } + .navigationTitle("Feature C") + .navigationBarTitleDisplayMode(.inline) + } +} + +#Preview { + FeatureBView() +} diff --git a/NavigateTesting/NavigateTesting/Features/FeatureDView.swift b/NavigateTesting/NavigateTesting/Features/FeatureDView.swift new file mode 100644 index 0000000..ec2166c --- /dev/null +++ b/NavigateTesting/NavigateTesting/Features/FeatureDView.swift @@ -0,0 +1,31 @@ +// +// FeatureDView.swift +// NavigateTesting +// +// Created by Alexander Kauer on 17.07.25. +// + +import Navigate +import SwiftUI + +struct FeatureDView: View { + + @Environment(Router.self) + var router: Router + + var body: some View { + List { + Button("Dismiss modal path") { + router.homeTabPath = [] + router.tabPath = [] + router.modalPath = [] + } + } + .navigationTitle("Feature D") + .navigationBarTitleDisplayMode(.inline) + } +} + +#Preview { + FeatureBView() +} diff --git a/NavigateTesting/NavigateTesting/Features/SubSettingsView.swift b/NavigateTesting/NavigateTesting/Features/ProfileView.swift similarity index 56% rename from NavigateTesting/NavigateTesting/Features/SubSettingsView.swift rename to NavigateTesting/NavigateTesting/Features/ProfileView.swift index bb734e1..d12be25 100644 --- a/NavigateTesting/NavigateTesting/Features/SubSettingsView.swift +++ b/NavigateTesting/NavigateTesting/Features/ProfileView.swift @@ -7,13 +7,15 @@ import SwiftUI -struct SubSettingsView: View { +struct ProfileView: View { var body: some View { - Text("Sub Settings") - .navigationTitle("Sub Settings") + List { + + } + .navigationTitle("Profile View") } } #Preview { - SubSettingsView() + ProfileView() } diff --git a/NavigateTesting/NavigateTesting/Features/SettingsView.swift b/NavigateTesting/NavigateTesting/Features/SettingsView.swift index 485e2d5..fcb6ff4 100644 --- a/NavigateTesting/NavigateTesting/Features/SettingsView.swift +++ b/NavigateTesting/NavigateTesting/Features/SettingsView.swift @@ -8,13 +8,27 @@ import SwiftUI struct SettingsView: View { + + @Environment(\.dismiss) + private var dismiss + var body: some View { List { - NavigationLink(destination: .subSettings) { - Text("Sub-Settings") + NavigationLink(destination: .profile) { + Text("Profile") } } .navigationTitle("Settings") + .navigationBarTitleDisplayMode(.inline) + .toolbar { + ToolbarItem(placement: .cancellationAction) { + Button { + dismiss() + } label: { + Image(systemName: "xmark") + } + } + } } } diff --git a/NavigateTesting/NavigateTesting/Navigation/Destinations.swift b/NavigateTesting/NavigateTesting/Navigation/Destinations.swift index 20e0272..caec830 100644 --- a/NavigateTesting/NavigateTesting/Navigation/Destinations.swift +++ b/NavigateTesting/NavigateTesting/Navigation/Destinations.swift @@ -11,8 +11,10 @@ import SwiftUI enum MyDestination: NavigationDestination { case featureA case featureB + case featureC + case featureD case settings - case subSettings + case profile var id: Self { self } } diff --git a/Package.resolved b/Package.resolved new file mode 100644 index 0000000..fefa972 --- /dev/null +++ b/Package.resolved @@ -0,0 +1,23 @@ +{ + "pins" : [ + { + "identity" : "swift-docc-plugin", + "kind" : "remoteSourceControl", + "location" : "https://github.com/swiftlang/swift-docc-plugin", + "state" : { + "revision" : "3e4f133a77e644a5812911a0513aeb7288b07d06", + "version" : "1.4.5" + } + }, + { + "identity" : "swift-docc-symbolkit", + "kind" : "remoteSourceControl", + "location" : "https://github.com/swiftlang/swift-docc-symbolkit", + "state" : { + "revision" : "b45d1f2ed151d057b54504d653e0da5552844e34", + "version" : "1.0.0" + } + } + ], + "version" : 2 +} diff --git a/Package.swift b/Package.swift index 23158ed..608ad3c 100644 --- a/Package.swift +++ b/Package.swift @@ -1,4 +1,4 @@ -// swift-tools-version: 6.1 +// swift-tools-version: 5.9 import PackageDescription @@ -17,15 +17,18 @@ let package = Package( targets: ["Navigate"] ) ], - dependencies: [], + dependencies: [ + .package(url: "https://github.com/swiftlang/swift-docc-plugin", from: "1.0.0"), + ], targets: [ .target( - name: "Navigate" + name: "Navigate", + exclude: ["../../NavigateTesting"] ), .testTarget( name: "NavigateTests", dependencies: ["Navigate"], - exclude: ["NavigateTesting/*"] + exclude: ["../../NavigateTesting"] ) ] ) diff --git a/README.md b/README.md index 6d8e5bf..ef4b6ee 100644 --- a/README.md +++ b/README.md @@ -7,130 +7,145 @@ [![Swift Package Manager compatible](https://img.shields.io/badge/Swift%20Package%20Manager-compatible-brightgreen.svg)](https://github.com/apple/swift-package-manager) -Navigate is a Swift navigation library that enables high-level modularization using `NavigationDestination` protocol. It introduces `ModalStack`, which works exactly like SwiftUI `NavigationStack` and allows you to display multiple **Sheets** and **FullScreenCovers** on top of each other and bind all displayed sheets to a `path`. +Simple navigation for SwiftUI -## Usage +## Overview +Navigate is a Swift navigation library that enables high-level modularization using `NavigationDestination` protocol. It introduces `ModalStack`, which works exactly like SwiftUI `NavigationStack` and allows you to display multiple **Sheets** and **FullScreenCovers** on top of each other. +![Dismiss all animation with path binding.](./Sources/Navigate/Documentation.docc/Ressources/dismiss-all.gif) + +### Define your destinations Define your possible destinations in a higher level package in one or more enums. ```swift import Navigate -public enum MainNavigationDestination: NavigationDestination { - case home - case detailCard(id: Int) +enum MyDestination: NavigationDestination { + case featureA + case featureB case settings - - public var id: Self { self } + case subSettings + + var id: Self { self } } ``` -Those `MainNavigationDestination` need to be applied to the first element within a `NavigationStack`. - - -### NavigationStack & NavigationLink +#### Convenience +To be able to write shortenings for your custom destinations, convenience initializers are necessary. These code can be copied from below and adopted accordingly. ```swift -import Navigate - -// Import your corresponding views if needed -import FeatureHome -import FeatureCard -import FeatureSettings - -extension View { - func navigationDestinationMain() -> some View { - navigationDestination(for: MainNavigationDestination.self) { destination in - switch destination { - case .home: HomeView() - case .detailCard(let id): DetailCard(for: id) - case .settings: SettingsView() - } - } +extension NavigationLink where Destination == Never { + + /// NavigationLink init for `Navigate` framework + /// - Parameters: + /// - destination: The `NavigationDestination` to navigate to + /// - label: The label for the `NavigationLink` + init(destination: MyDestination, @ViewBuilder label: @escaping () -> Label) { + self.init(value: destination, label: label) } } -``` -Example View: +extension SheetLink { + /// NavigationLink init for `Navigate` framework + /// - Parameters: + /// - destination: The `NavigationDestination` to navigate to + /// - label: The label for the `NavigationLink` + init(destination: MyDestination, @ViewBuilder label: @escaping () -> Label) { + self.init(destination: destination as any NavigationDestination, label: label) + } +} -```swift -struct ContentView: View { - var body: some View { - NavigationStack { - MainView() - .navigationDestinationMain() - } +extension FullScreenCoverLink { + /// NavigationLink init for `Navigate` framework + /// - Parameters: + /// - destination: The `NavigationDestination` to navigate to + /// - label: The label for the `NavigationLink` + init(destination: MyDestination, @ViewBuilder label: @escaping () -> Label) { + self.init(destination: destination as any NavigationDestination, label: label) } } ``` -Use it in NavigationLink and sheet +### ModalStack +#### Definition +Those `MyDestination`s need to be applied to the first element within a `ModalStack` similar to SwiftUI's `NavigationStack`. ```swift -struct MainView: View { - var body: some View { +@State var modalPath: [ModalPathDestination] = [] + +var body: some View { + ModalStack(path: $modalPath) { List { - NavigationLink( - destination: NewsNavigationDestination.detailCard(id: 1) - ) { - Text("Click me") + SheetLink(destination: .featureB) { + Text("Sheet to feature B") } } + .myModalDestinations() // register all modal destinations } } ``` -### ModalStack with SheetLink and FullScreenCoverLink - -Simalar to NavigationStack you add a `ModalStack` to enable all Navigate modal presentation features. It also supports a `path` parameter. ModalStack must be placed on the top-most level of your views. +#### Register destinations ```swift - var body: some View { - ModalStack(path: $router.modalPath) { - TabView { - ... +import Navigate + +// Import your corresponding views if needed +import FeatureHome +import FeatureCard +import FeatureSettings + +extension View { + /// SwiftUI navigation destination convenience + func myNavigtationDestinations() -> some View { + self.navigationDestination(for: MyDestination.self) { destination in + switch destination { + case .featureA: + FeatureAView() + case .featureB: + FeatureBView() + ... } } } -} -``` - -This enables you to use `ShareLink` and `FullScreenCoverLink` in any child view. - -### Convenience - -Define a NavigationLink extension offering an initalizer with your `NavigationDestination` type. - -```swift -public extension NavigationLink where Destination == Never { - /// NavigationLink init for `Navigate` framework - /// - Parameters: - /// - destination: The `NavigationDestination` to navigate to - /// - label: The label for the `NavigationLink` - init(destination: MainNavigationDestination, @ViewBuilder label: () -> Label) { - self.init(value: destination, label: label) + /// All ModalDestinations wrapped in NavigationStack to support SwiftUI navigation and toolbar + func myModalDestinations() -> some View { + self.modalDestination(for: MyDestination.self) { destination in + switch destination { + case .featureA: + NavigationStack { + FeatureAView() + .myNavigtationDestinations() + } + case .featureB: + NavigationStack { + FeatureBView() + .myNavigtationDestinations() + } + ... + } + } } } -``` - -If defined you can use shorter syntax when creating a `NavigationLink`, `SheetLink` or `FullScreenCoverLink`. -```swift -NavigationLink(destination: .home) { - Text("Home") -} ``` -## Legacy support: TopSheet and TopFullScreenCover +## Available SwiftUI links +Use the `NavigationLink`, `SheetLink` and `FullScreenCoverLink` -As there is no out-of-the-box way for SwiftUI to display sheets or fullScreenCovers globally without dismissing current presented sheets we added `TopSheet` and `TopFullScreenCover` to the Navigate API. +```swift +List { + NavigationLink(destination: .featureB) { + Text("Go to feature B") + } -Usage: + SheetLink(destination: .featureB) { + Text("Sheet to feature B") + } -```swift -view.topSheet( - destination: $destination, - presentOn: { UIViewController() } -) + FullScreenCoverLink(destination: .featureB) { + Text("FullScreenCover to feature B") + } +} ``` diff --git a/Sources/Navigate/Documentation.docc/Documentation.md b/Sources/Navigate/Documentation.docc/Documentation.md new file mode 100644 index 0000000..27a6a7f --- /dev/null +++ b/Sources/Navigate/Documentation.docc/Documentation.md @@ -0,0 +1,143 @@ +# ``Navigate`` +Simple navigation for SwiftUI + +## Overview +Navigate is a Swift navigation library that enables high-level modularization using `NavigationDestination` protocol. It introduces `ModalStack`, which works exactly like SwiftUI `NavigationStack` and allows you to display multiple **Sheets** and **FullScreenCovers** on top of each other. + +@Image(source: dismiss-all, alt: "Dismiss all animation with path binding.") + +### Define your destinations +Define your possible destinations in a higher level package in one or more enums. + +```swift +import Navigate + +enum MyDestination: NavigationDestination { + case featureA + case featureB + case settings + case subSettings + + var id: Self { self } +} +``` + +#### Convenience +To be able to write shortenings for your custom destinations, convenience initializers are necessary. These code can be copied from below and adopted accordingly. + +```swift +extension NavigationLink where Destination == Never { + + /// NavigationLink init for `Navigate` framework + /// - Parameters: + /// - destination: The `NavigationDestination` to navigate to + /// - label: The label for the `NavigationLink` + init(destination: MyDestination, @ViewBuilder label: @escaping () -> Label) { + self.init(value: destination, label: label) + } +} + +extension SheetLink { + /// NavigationLink init for `Navigate` framework + /// - Parameters: + /// - destination: The `NavigationDestination` to navigate to + /// - label: The label for the `NavigationLink` + init(destination: MyDestination, @ViewBuilder label: @escaping () -> Label) { + self.init(destination: destination as any NavigationDestination, label: label) + } +} + +extension FullScreenCoverLink { + /// NavigationLink init for `Navigate` framework + /// - Parameters: + /// - destination: The `NavigationDestination` to navigate to + /// - label: The label for the `NavigationLink` + init(destination: MyDestination, @ViewBuilder label: @escaping () -> Label) { + self.init(destination: destination as any NavigationDestination, label: label) + } +} +``` + +### ModalStack +#### Definition +Those `MyDestination`s need to be applied to the first element within a `ModalStack` similar to SwiftUI's `NavigationStack`. + +```swift +@State var modalPath: [ModalPathDestination] = [] + +var body: some View { + ModalStack(path: $modalPath) { + List { + SheetLink(destination: .featureB) { + Text("Sheet to feature B") + } + } + .myModalDestinations() // register all modal destinations + } +} +``` + +#### Register destinations + +```swift +import Navigate + +// Import your corresponding views if needed +import FeatureHome +import FeatureCard +import FeatureSettings + +extension View { + /// SwiftUI navigation destination convenience + func myNavigtationDestinations() -> some View { + self.navigationDestination(for: MyDestination.self) { destination in + switch destination { + case .featureA: + FeatureAView() + case .featureB: + FeatureBView() + ... + } + } + } + + /// All ModalDestinations wrapped in NavigationStack to support SwiftUI navigation and toolbar + func myModalDestinations() -> some View { + self.modalDestination(for: MyDestination.self) { destination in + switch destination { + case .featureA: + NavigationStack { + FeatureAView() + .myNavigtationDestinations() + } + case .featureB: + NavigationStack { + FeatureBView() + .myNavigtationDestinations() + } + ... + } + } + } +} + +``` + +### Available SwiftUI links +Use the `NavigationLink`, `SheetLink` and `FullScreenCoverLink` + +```swift +List { + NavigationLink(destination: .featureB) { + Text("Go to feature B") + } + + SheetLink(destination: .featureB) { + Text("Sheet to feature B") + } + + FullScreenCoverLink(destination: .featureB) { + Text("FullScreenCover to feature B") + } +} +``` diff --git a/Sources/Navigate/Documentation.docc/Ressources/dismiss-all.gif b/Sources/Navigate/Documentation.docc/Ressources/dismiss-all.gif new file mode 100644 index 0000000..aefa046 Binary files /dev/null and b/Sources/Navigate/Documentation.docc/Ressources/dismiss-all.gif differ diff --git a/Sources/Navigate/ModalStack/FullScreenCoverLink.swift b/Sources/Navigate/ModalStack/Links/FullScreenCoverLink.swift similarity index 87% rename from Sources/Navigate/ModalStack/FullScreenCoverLink.swift rename to Sources/Navigate/ModalStack/Links/FullScreenCoverLink.swift index 00d5c29..10d5aa9 100644 --- a/Sources/Navigate/ModalStack/FullScreenCoverLink.swift +++ b/Sources/Navigate/ModalStack/Links/FullScreenCoverLink.swift @@ -8,6 +8,7 @@ import SwiftUI #if !os(macOS) +/// A view that controls a navigation presentation as a FullScreenCover in a `ModalStack` public struct FullScreenCoverLink: View { let label: Label let destination: any NavigationDestination diff --git a/Sources/Navigate/ModalStack/SheetLink.swift b/Sources/Navigate/ModalStack/Links/SheetLink.swift similarity index 74% rename from Sources/Navigate/ModalStack/SheetLink.swift rename to Sources/Navigate/ModalStack/Links/SheetLink.swift index 40340f6..b42f336 100644 --- a/Sources/Navigate/ModalStack/SheetLink.swift +++ b/Sources/Navigate/ModalStack/Links/SheetLink.swift @@ -7,9 +7,10 @@ import SwiftUI +/// A view that controls a navigation presentation as a Sheet in a `ModalStack` public struct SheetLink: View { - let label: Label - let destination: any NavigationDestination + private let label: Label + private let destination: any NavigationDestination @Environment(\.presentSheet) private var presentSheet diff --git a/Sources/Navigate/ModalStack/ModalPathDestination.swift b/Sources/Navigate/ModalStack/ModalPathDestination.swift index 7aab3e4..7306b90 100644 --- a/Sources/Navigate/ModalStack/ModalPathDestination.swift +++ b/Sources/Navigate/ModalStack/ModalPathDestination.swift @@ -7,6 +7,8 @@ import SwiftUI +/// Helper for holding the `destination` with the modal presentation type +/// Needed for binding the path of the `ModalStack` public struct ModalPathDestination: NavigationDestination { let destination: any NavigationDestination let type: ModalType diff --git a/Sources/Navigate/ModalStack/ModalStack.swift b/Sources/Navigate/ModalStack/ModalStack.swift index 4e3aec6..ea98b0a 100644 --- a/Sources/Navigate/ModalStack/ModalStack.swift +++ b/Sources/Navigate/ModalStack/ModalStack.swift @@ -8,7 +8,7 @@ import SwiftUI public struct ModalStack: View { - let root: Root + private let root: Root private var path: Binding<[ModalPathDestination]> { externalPath ?? $internalPath diff --git a/Sources/Navigate/ModalStack/FullScreenCoverModifier.swift b/Sources/Navigate/ModalStack/Modifiers/FullScreenCoverModifier.swift similarity index 100% rename from Sources/Navigate/ModalStack/FullScreenCoverModifier.swift rename to Sources/Navigate/ModalStack/Modifiers/FullScreenCoverModifier.swift diff --git a/Sources/Navigate/ModalStack/SheetModifier.swift b/Sources/Navigate/ModalStack/Modifiers/SheetModifier.swift similarity index 100% rename from Sources/Navigate/ModalStack/SheetModifier.swift rename to Sources/Navigate/ModalStack/Modifiers/SheetModifier.swift