Skip to content

Commit

Permalink
Support displaying alert using any Identifiable
Browse files Browse the repository at this point in the history
  • Loading branch information
divadretlaw committed Feb 28, 2024
1 parent 6fe5957 commit ff08e14
Show file tree
Hide file tree
Showing 4 changed files with 423 additions and 10 deletions.
File renamed without changes.
337 changes: 337 additions & 0 deletions Sources/CustomAlert/API+Identifiable.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,337 @@
//
// API+Identifiable.swift
// CustomAlert
//
// Created by David Walter on 28.02.24.
//

import SwiftUI
import Combine
import WindowKit

enum AlertIdentifiable: Int, Identifiable, Hashable, Equatable {
case present

var id: Int { rawValue }
}

public extension View {
/// Presents an alert when a given condition is true, using an optional text view for
/// the title.
///
/// All actions in an alert dismiss the alert after the action runs.
///
/// - Parameters:
/// - title: The optional title of the alert.
/// - item: A binding to an optional source of truth for the alert.
/// When `item` is non-`nil`, the system passes the item's content to
/// the modifier's closure. You display this content in a alert that you
/// create that the system displays to the user. If `item` changes,
/// the system dismisses the alert and replaces it with a new one
/// using the same process.
/// - content: A `ViewBuilder` returing the alerts main view.
/// - actions: A `ViewBuilder` returning the alert's actions.
@warn_unqualified_access
func customAlert<Item, Content, Actions>(
_ title: Text? = nil,
item: Binding<Item?>,
@ViewBuilder content: @escaping (Item) -> Content,
@ViewBuilder actions: @escaping (Item) -> Actions
) -> some View where Item: Identifiable, Content: View, Actions: View {
modifier(
CustomAlertHandler(
title: title,
item: item,
windowScene: nil,
alertContent: content,
alertActions: actions
)
)
}

/// Presents an alert when a given condition is true, using
/// a localized string key for a title.
///
/// All actions in an alert dismiss the alert after the action runs.
///
/// - Parameters:
/// - title: The title of the alert.
/// - item: A binding to an optional source of truth for the alert.
/// When `item` is non-`nil`, the system passes the item's content to
/// the modifier's closure. You display this content in a alert that you
/// create that the system displays to the user. If `item` changes,
/// the system dismisses the alert and replaces it with a new one
/// using the same process.
/// - content: A `ViewBuilder` returing the alerts main view.
/// - actions: A `ViewBuilder` returning the alert's actions.
@warn_unqualified_access
func customAlert<Item, Content, Actions>(
_ title: LocalizedStringKey,
item: Binding<Item?>,
@ViewBuilder content: @escaping (Item) -> Content,
@ViewBuilder actions: @escaping (Item) -> Actions
) -> some View where Item: Identifiable, Content: View, Actions: View {
self.customAlert(Text(title), item: item, content: content, actions: actions)
}

/// Presents an alert when a given condition is true
///
/// All actions in an alert dismiss the alert after the action runs.
///
/// - Parameters:
/// - title: The title of the alert.
/// - item: A binding to an optional source of truth for the alert.
/// When `item` is non-`nil`, the system passes the item's content to
/// the modifier's closure. You display this content in a alert that you
/// create that the system displays to the user. If `item` changes,
/// the system dismisses the alert and replaces it with a new one
/// using the same process.
/// - content: A `ViewBuilder` returing the alerts main view.
/// - actions: A `ViewBuilder` returning the alert's actions.
@warn_unqualified_access
@_disfavoredOverload
func customAlert<Item, Title, Content, Actions>(
_ title: Title,
item: Binding<Item?>,
@ViewBuilder content: @escaping (Item) -> Content,
@ViewBuilder actions: @escaping (Item) -> Actions
) -> some View where Item: Identifiable, Title: StringProtocol, Content: View, Actions: View {
self.customAlert(Text(title), item: item, content: content, actions: actions)
}

/// Presents an alert when a given condition is true, using an optional text view for
/// the title.
///
/// All actions in an alert dismiss the alert after the action runs.
///
/// - Parameters:
/// - item: A binding to an optional source of truth for the alert.
/// When `item` is non-`nil`, the system passes the item's content to
/// the modifier's closure. You display this content in a alert that you
/// create that the system displays to the user. If `item` changes,
/// the system dismisses the alert and replaces it with a new one
/// using the same process.
/// - title: Callback for the optional title of the alert.
/// - content: A `ViewBuilder` returing the alerts main view.
/// - actions: A `ViewBuilder` returning the alert's actions.
@warn_unqualified_access
func customAlert<Item, Content, Actions>(
item: Binding<Item?>,
title: @escaping () -> Text?,
@ViewBuilder content: @escaping (Item) -> Content,
@ViewBuilder actions: @escaping (Item) -> Actions
) -> some View where Item: Identifiable, Content: View, Actions: View {
self.customAlert(title(), item: item, content: content, actions: actions)
}
}

public extension View {
/// Presents an alert when a given condition is true, using an optional text view for
/// the title.
///
/// All actions in an alert dismiss the alert after the action runs.
///
/// - Parameters:
/// - title: The optional title of the alert.
/// - item: A binding to an optional source of truth for the alert.
/// When `item` is non-`nil`, the system passes the item's content to
/// the modifier's closure. You display this content in a alert that you
/// create that the system displays to the user. If `item` changes,
/// the system dismisses the alert and replaces it with a new one
/// using the same process.
/// - windowScene: The window scene to present the alert on.
/// - content: A `ViewBuilder` returing the alerts main view.
/// - actions: A `ViewBuilder` returning the alert's actions.
@warn_unqualified_access
func customAlert<Item, Content, Actions>(
_ title: Text? = nil,
item: Binding<Item?>,
on windowScene: UIWindowScene,
@ViewBuilder content: @escaping (Item) -> Content,
@ViewBuilder actions: @escaping (Item) -> Actions
) -> some View where Item: Identifiable, Content: View, Actions: View {
modifier(
CustomAlertHandler(
title: title,
item: item,
windowScene: windowScene,
alertContent: content,
alertActions: actions
)
)
}

/// Presents an alert when a given condition is true, using
/// a localized string key for a title.
///
/// All actions in an alert dismiss the alert after the action runs.
///
/// - Parameters:
/// - title: The title of the alert.
/// - item: A binding to an optional source of truth for the alert.
/// When `item` is non-`nil`, the system passes the item's content to
/// the modifier's closure. You display this content in a alert that you
/// create that the system displays to the user. If `item` changes,
/// the system dismisses the alert and replaces it with a new one
/// using the same process.
/// - windowScene: The window scene to present the alert on.
/// - content: A `ViewBuilder` returing the alerts main view.
/// - actions: A `ViewBuilder` returning the alert's actions.
@warn_unqualified_access func customAlert<Item, Content, Actions>(
_ title: LocalizedStringKey,
item: Binding<Item?>,
on windowScene: UIWindowScene,
@ViewBuilder content: @escaping (Item) -> Content,
@ViewBuilder actions: @escaping (Item) -> Actions
) -> some View where Item: Identifiable, Content: View, Actions: View {
self.customAlert(Text(title), item: item, on: windowScene, content: content, actions: actions)
}

/// Presents an alert when a given condition is true
///
/// All actions in an alert dismiss the alert after the action runs.
///
/// - Parameters:
/// - title: The title of the alert.
/// - item: A binding to an optional source of truth for the alert.
/// When `item` is non-`nil`, the system passes the item's content to
/// the modifier's closure. You display this content in a alert that you
/// create that the system displays to the user. If `item` changes,
/// the system dismisses the alert and replaces it with a new one
/// using the same process.
/// - windowScene: The window scene to present the alert on.
/// - content: A `ViewBuilder` returing the alerts main view.
/// - actions: A `ViewBuilder` returning the alert's actions.
@warn_unqualified_access
@_disfavoredOverload
func customAlert<Item, Title, Content, Actions>(
_ title: Title,
item: Binding<Item?>,
on windowScene: UIWindowScene,
@ViewBuilder content: @escaping (Item) -> Content,
@ViewBuilder actions: @escaping (Item) -> Actions
) -> some View where Item: Identifiable, Title: StringProtocol, Content: View, Actions: View {
self.customAlert(Text(title), item: item, on: windowScene, content: content, actions: actions)
}

/// Presents an alert when a given condition is true, using an optional text view for
/// the title.
///
/// All actions in an alert dismiss the alert after the action runs.
///
/// - Parameters:
/// - item: A binding to an optional source of truth for the alert.
/// When `item` is non-`nil`, the system passes the item's content to
/// the modifier's closure. You display this content in a alert that you
/// create that the system displays to the user. If `item` changes,
/// the system dismisses the alert and replaces it with a new one
/// using the same process.
/// - windowScene: The window scene to present the alert on.
/// - title: Callback for the optional title of the alert.
/// - content: A `ViewBuilder` returing the alerts main view.
/// - actions: A `ViewBuilder` returning the alert's actions.
@warn_unqualified_access
func customAlert<Item, Content, Actions>(
item: Binding<Item?>,
on windowScene: UIWindowScene,
title: @escaping () -> Text?,
@ViewBuilder content: @escaping (Item) -> Content,
@ViewBuilder actions: @escaping (Item) -> Actions
) -> some View where Item: Identifiable, Content: View, Actions: View {
self.customAlert(title(), item: item, on: windowScene, content: content, actions: actions)
}
}

public extension View {
/// Presents an alert when a given condition is true, using an optional text view for
/// the title.
///
/// All actions in an alert dismiss the alert after the action runs.
///
/// - Parameters:
/// - title: The optional title of the alert.
/// - item: A binding to an optional source of truth for the alert.
/// When `item` is non-`nil`, the system passes the item's content to
/// the modifier's closure. You display this content in a alert that you
/// create that the system displays to the user. If `item` changes,
/// the system dismisses the alert and replaces it with a new one
/// using the same process.
/// - content: A `ViewBuilder` returing the alerts main view.
@warn_unqualified_access
func customAlert<Item, Content>(
_ title: Text? = nil,
item: Binding<Item?>,
@ViewBuilder content: @escaping (Item) -> Content
) -> some View where Item: Identifiable,Content: View {
self.customAlert(title, item: item, content: content, actions: { _ in /* no actions */ })
}

/// Presents an alert when a given condition is true, using
/// a localized string key for a title.
///
/// All actions in an alert dismiss the alert after the action runs.
///
/// - Parameters:
/// - title: The title of the alert.
/// - item: A binding to an optional source of truth for the alert.
/// When `item` is non-`nil`, the system passes the item's content to
/// the modifier's closure. You display this content in a alert that you
/// create that the system displays to the user. If `item` changes,
/// the system dismisses the alert and replaces it with a new one
/// using the same process.
/// - content: A `ViewBuilder` returing the alerts main view.
@warn_unqualified_access
func customAlert<Item, Content>(
_ title: LocalizedStringKey,
item: Binding<Item?>,
@ViewBuilder content: @escaping (Item) -> Content
) -> some View where Item: Identifiable, Content: View {
self.customAlert(Text(title), item: item, content: content, actions: { _ in /* no actions */ })
}

/// Presents an alert when a given condition is true
///
/// All actions in an alert dismiss the alert after the action runs.
///
/// - Parameters:
/// - title: The title of the alert.
/// - item: A binding to an optional source of truth for the alert.
/// When `item` is non-`nil`, the system passes the item's content to
/// the modifier's closure. You display this content in a alert that you
/// create that the system displays to the user. If `item` changes,
/// the system dismisses the alert and replaces it with a new one
/// using the same process.
/// - content: A `ViewBuilder` returing the alerts main view.
@warn_unqualified_access
@_disfavoredOverload
func customAlert<Item, Title, Content>(
_ title: Title,
item: Binding<Item?>,
@ViewBuilder content: @escaping (Item) -> Content
) -> some View where Item: Identifiable, Title: StringProtocol, Content: View {
self.customAlert(Text(title), item: item, content: content, actions: { _ in /* no actions */ })
}

/// Presents an alert when a given condition is true, using an optional text view for
/// the title.
///
/// All actions in an alert dismiss the alert after the action runs.
///
/// - Parameters:
/// - item: A binding to an optional source of truth for the alert.
/// When `item` is non-`nil`, the system passes the item's content to
/// the modifier's closure. You display this content in a alert that you
/// create that the system displays to the user. If `item` changes,
/// the system dismisses the alert and replaces it with a new one
/// using the same process.
/// - title: Callback for the optional title of the alert.
/// - content: A `ViewBuilder` returing the alerts main view.
@warn_unqualified_access
func customAlert<Item, Content>(
item: Binding<Item?>,
title: @escaping () -> Text?,
@ViewBuilder content: @escaping (Item) -> Content
) -> some View where Item: Identifiable, Content: View {
self.customAlert(title(), item: item, content: content, actions: { _ in /* no actions */ })
}
}
Loading

0 comments on commit ff08e14

Please sign in to comment.