Skip to content

Commit

Permalink
init
Browse files Browse the repository at this point in the history
  • Loading branch information
0xLeif committed Nov 16, 2024
1 parent 6948a7c commit 0e92d78
Show file tree
Hide file tree
Showing 13 changed files with 1,433 additions and 11 deletions.
18 changes: 11 additions & 7 deletions Package.swift
Original file line number Diff line number Diff line change
@@ -1,24 +1,28 @@
// swift-tools-version: 6.0
// The swift-tools-version declares the minimum version of Swift required to build this package.

import PackageDescription

let package = Package(
name: "Navigation",
platforms: [
.iOS(.v16),
.macOS(.v13),
.tvOS(.v16),
.watchOS(.v9)
],
products: [
// Products define the executables and libraries a package produces, making them visible to other packages.
.library(
name: "Navigation",
targets: ["Navigation"]),
targets: ["Navigation"]
)
],
targets: [
// Targets are the basic building blocks of a package, defining a module or a test suite.
// Targets can depend on other targets in this package and products from dependencies.
.target(
name: "Navigation"),
name: "Navigation"
),
.testTarget(
name: "NavigationTests",
dependencies: ["Navigation"]
),
)
]
)
57 changes: 57 additions & 0 deletions README
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
# Navigation Framework for SwiftUI

[![macOS Build](https://img.shields.io/github/actions/workflow/status/0xLeif/Navigation/macOS.yml?label=macOS&branch=main)](https://github.com/0xLeif/Navigation/actions/workflows/macOS.yml)
[![License](https://img.shields.io/github/license/0xLeif/Navigation)](https://github.com/0xLeif/Navigation/blob/main/LICENSE)
[![Version](https://img.shields.io/github/v/release/0xLeif/Navigation)](https://github.com/0xLeif/Navigation/releases)

**Navigation** is a SwiftUI framework that simplifies and enhances navigation in your applications. It centralizes state management through the `Navigator` class, making it easier to handle navigation actions, sheets, alerts, and confirmation dialogs.

## Requirements

- **iOS**: 16.0+
- **macOS**: 13.0+
- **tvOS**: 16.0+
- **watchOS**: 9.0+
- **Swift**: 6.0+
- **Xcode**: 16.0+

## Key Features

**Navigation** offers powerful tools for managing navigation state:

- **Centralized State Management**: Use the `Navigator` class to manage navigation actions, alerts, sheets, and confirmation dialogs.
- **Automatic Navigator Injection**: The `Navigation` view automatically creates and injects a `Navigator` into the environment.
- **Environment Access**: Access the `Navigator` throughout your app via `@EnvironmentObject`.
- **Seamless SwiftUI Integration**: Works smoothly with SwiftUI's `NavigationStack`, `NavigationLink`, and `navigationDestination`.
- **Simplified UI Components**: Manage sheets, alerts, and confirmation dialogs without multiple `@State` variables.
- **Type-Safe Navigation**: Ensure type safety by using custom `Hashable` data types for navigation.
- **Programmatic Navigation**: Support dynamic navigation flows by pushing and popping views based on conditions or events.

## Getting Started

To add **Navigation** to your SwiftUI project, follow the detailed instructions in the [Installation Guide](INSTALLATION.md).

After installation, refer to the [Usage Overview](USAGE_OVERVIEW.md) for a quick introduction on setting up and using the framework.

## Documentation

Explore **Navigation**'s documentation to get the most out of the framework:

- [Installation Guide](documentation/INSTALLATION.md): Steps to add **Navigation** to your project using Swift Package Manager.
- [Usage Overview](documentation/USAGE_OVERVIEW.md): A quick start guide with key features and example implementations.

### Detailed Usage Guides

- [Navigation Techniques](documentation/NAVIGATION_TECHNIQUES.md): Discover various navigation methods using the `Navigator`, including pushing and popping views, `NavigationLink`, and `NavigatorButton`.
- [Modals, Alerts, and Dialogs](documentation/MODALS_ALERTS_DIALOGS.md): Learn how to present sheets, alerts, and confirmation dialogs using the `Navigator`.
- [Advanced Usage](documentation/ADVANCED_USAGE.md): Delve into advanced topics like custom navigation actions, deep linking, and environment integration.
- [Patterns and Best Practices](documentation/PATTERNS_BEST_PRACTICES.md): Improve your app's navigation architecture by following best practices.
- [API Overview](documentation/API_OVERVIEW.md): A comprehensive overview of the `Navigator` API.

## Next Steps

With **Navigation** installed, start exploring its features by reading the [Usage Overview](documentation/USAGE_OVERVIEW.md) and the detailed guides. Begin managing navigation effectively in your SwiftUI projects. For advanced techniques, consult the [Advanced Usage Guide](documentation/ADVANCED_USAGE.md).

## License

This project is licensed under the MIT License. See the [LICENSE](LICENSE) file for details.
126 changes: 124 additions & 2 deletions Sources/Navigation/Navigation.swift
Original file line number Diff line number Diff line change
@@ -1,2 +1,124 @@
// The Swift Programming Language
// https://docs.swift.org/swift-book
import SwiftUI

/// A SwiftUI container for managing navigation paths and dialogs.
public struct Navigation<Root: View>: View {
@ObservedObject private var navigator: Navigator

private let isAppAlertPresented: Binding<Bool>
private let isSheetAlertPresented: Binding<Bool>
private let isAppConfirmPresented: Binding<Bool>
private let isSheetConfirmPresented: Binding<Bool>
private let root: (Navigator) -> Root

/// Creates a navigation container with a custom root view.
/// - Parameters:
/// - navigator: An optional `Navigator` instance.
/// - root: A closure to define the root view.
public init(
navigator: Navigator = Navigator(),
@ViewBuilder root: @escaping (Navigator) -> Root
) {
self.navigator = navigator
self.isAppAlertPresented = Binding(
get: {
navigator.alert != nil && navigator.sheet == nil
},
set: { newValue in
if newValue == false {
navigator.alert = nil
}
}
)
self.isSheetAlertPresented = Binding(
get: {
navigator.alert != nil && navigator.sheet != nil
},
set: { newValue in
if newValue == false {
navigator.alert = nil
}
}
)
self.isAppConfirmPresented = Binding(
get: {
navigator.confirmDialog != nil && navigator.sheet == nil
},
set: { newValue in
if newValue == false {
navigator.confirmDialog = nil
}
}
)
self.isSheetConfirmPresented = Binding(
get: {
navigator.confirmDialog != nil && navigator.confirmDialog != nil
},
set: { newValue in
if newValue == false {
navigator.confirmDialog = nil
}
}
)
self.root = root
}

/// Creates a navigation container with a custom root view.
/// - Parameters:
/// - navigator: An optional `Navigator` instance.
/// - root: A closure to define the root view.
public init(
navigator: Navigator = Navigator(),
@ViewBuilder root: @escaping () -> Root
) {
self.init(
navigator: navigator,
root: { _ in root() }
)
}

public var body: some View {
NavigationStack(path: $navigator.path) {
root(navigator)
}
.alert(
navigator.alert?.title ?? "",
isPresented: isAppAlertPresented,
presenting: navigator.alert,
actions: \.actions,
message: \.message
)
.confirmationDialog(
navigator.confirmDialog?.title ?? "",
isPresented: isAppConfirmPresented,
titleVisibility: .automatic,
presenting: navigator.confirmDialog,
actions: \.actions,
message: \.message
)
.sheet(
item: $navigator.sheet,
onDismiss: {
navigator.sheet?.onDismiss?()
},
content: { sheet in
sheet.content
.alert(
navigator.alert?.title ?? "",
isPresented: isSheetAlertPresented,
presenting: navigator.alert,
actions: \.actions,
message: \.message
)
.confirmationDialog(
navigator.confirmDialog?.title ?? "",
isPresented: isSheetConfirmPresented,
titleVisibility: .automatic,
presenting: navigator.confirmDialog,
actions: \.actions,
message: \.message
)
}
)
.environmentObject(navigator)
}
}
Loading

0 comments on commit 0e92d78

Please sign in to comment.