From 3716cd15c43d841851bfd2d8409a222b47bcf7b3 Mon Sep 17 00:00:00 2001 From: Jeanne <25933880+fleuryj@users.noreply.github.com> Date: Fri, 6 Dec 2024 11:04:39 +0100 Subject: [PATCH] feat: toast can have action, can be removed --- .../Views/SBBToast/ToastView.swift | 13 +++++++++-- .../Views/SBBToast/ViewModels/SBBToast.swift | 12 ++++++++-- .../SBBToast/ViewModels/SBBToastService.swift | 14 ++++++++++-- .../Views/DetailViews/ToastDemo.swift | 22 ++++++++++++++++++- 4 files changed, 54 insertions(+), 7 deletions(-) diff --git a/SBBDesignSystemMobileSwiftUI/Views/SBBToast/ToastView.swift b/SBBDesignSystemMobileSwiftUI/Views/SBBToast/ToastView.swift index a023a9866..217403020 100644 --- a/SBBDesignSystemMobileSwiftUI/Views/SBBToast/ToastView.swift +++ b/SBBDesignSystemMobileSwiftUI/Views/SBBToast/ToastView.swift @@ -14,8 +14,17 @@ public struct ToastView: View { } public var body: some View { - viewModel.label - .sbbFont(.small_light) + HStack(alignment: .center, spacing: 16) { + viewModel.label + .sbbFont(.small_light) + + if let actionLabel = viewModel.actionLabel, let action = viewModel.onClickAction { + Button(action: action) { + actionLabel + .sbbFont(.small_bold) + } + } + } .foregroundColor(Color.sbbColor(.white)) .multilineTextAlignment(.center) .padding(.horizontal, 20) diff --git a/SBBDesignSystemMobileSwiftUI/Views/SBBToast/ViewModels/SBBToast.swift b/SBBDesignSystemMobileSwiftUI/Views/SBBToast/ViewModels/SBBToast.swift index 1b495586b..8197d1bf3 100644 --- a/SBBDesignSystemMobileSwiftUI/Views/SBBToast/ViewModels/SBBToast.swift +++ b/SBBDesignSystemMobileSwiftUI/Views/SBBToast/ViewModels/SBBToast.swift @@ -46,10 +46,12 @@ import SwiftUI */ public class SBBToast: Identifiable, ObservableObject { - public let id = UUID() + public let id: UUID let label: Text let easeInOutAnimationDuration: Double let presentedDuration: Double + let actionLabel: Text? + let onClickAction: (() -> Void)? @Published var isPresented = false @@ -62,10 +64,13 @@ public class SBBToast: Identifiable, ObservableObject { - easeInOutAnimationDuration: The duration of the ease-in and ease-out animation performed upon presenting/hiding a toast. - presentedDuration: The duration during which the toast is presented on screen */ - public init(label: Text, easeInOutAnimationDuration: Double = 1, presentedDuration: Double = 2) { + public init(label: Text, easeInOutAnimationDuration: Double = 1, presentedDuration: Double = 2, id: UUID = UUID(), actionLabel: Text? = nil, onClickAction: (() -> Void)? = nil) { self.label = label self.easeInOutAnimationDuration = easeInOutAnimationDuration self.presentedDuration = presentedDuration + self.actionLabel = actionLabel + self.onClickAction = onClickAction + self.id = id } // initializer for SwiftUI Previews @@ -74,5 +79,8 @@ public class SBBToast: Identifiable, ObservableObject { self.easeInOutAnimationDuration = 1 self.presentedDuration = 2 self.isPresented = isPresented + self.actionLabel = nil + self.onClickAction = nil + self.id = UUID() } } diff --git a/SBBDesignSystemMobileSwiftUI/Views/SBBToast/ViewModels/SBBToastService.swift b/SBBDesignSystemMobileSwiftUI/Views/SBBToast/ViewModels/SBBToastService.swift index e63cd7dd2..16c844b41 100644 --- a/SBBDesignSystemMobileSwiftUI/Views/SBBToast/ViewModels/SBBToastService.swift +++ b/SBBDesignSystemMobileSwiftUI/Views/SBBToast/ViewModels/SBBToastService.swift @@ -32,12 +32,22 @@ public class SBBToastService: ObservableObject { } /** - Instantaneously removes an already pressented SBBToast View. SBBToast Views are removed automatically after the defined presentation duration, this method allows to remove them sooner. + Instantaneously removes an already presented SBBToast View. SBBToast Views are removed automatically after the defined presentation duration, this method allows to remove them sooner. - Parameters: - toast: The SBBToast View to be removed instantaneously. */ - func removeToast(_ toast: SBBToast) { + public func removeToast(_ toast: SBBToast) { toasts.removeAll(where: { $0.id == toast.id }) } + + /** + Instantaneously removes an already presented SBBToast View. SBBToast Views are removed automatically after the defined presentation duration, this method allows to remove them sooner. + + - Parameters: + - where: The condition for which to remove the SBBToast. + */ + public func removeToast(where condition: (SBBToast) -> Bool) { + toasts.removeAll(where: condition) + } } diff --git a/SBBDesignSystemMobileSwiftUIDemo/Views/DetailViews/ToastDemo.swift b/SBBDesignSystemMobileSwiftUIDemo/Views/DetailViews/ToastDemo.swift index 5613de9ef..3f394b674 100644 --- a/SBBDesignSystemMobileSwiftUIDemo/Views/DetailViews/ToastDemo.swift +++ b/SBBDesignSystemMobileSwiftUIDemo/Views/DetailViews/ToastDemo.swift @@ -28,6 +28,27 @@ struct ToastDemo: View { Text("Show Toast") } .buttonStyle(SBBPrimaryButtonStyle()) + + Button(action: { + let uuid = UUID() + counter += 1 + toastService.showToast(SBBToast(label: Text("Hello Toast \(counter)\nThis Toast has multiple lines, in fact it might be longer than 2 IC2000 compositions linked together."), id: uuid, actionLabel: Text("Remove it"), onClickAction: { + toastService.removeToast(where: { $0.id == uuid }) + })) + }) { + Text("Show Multiline Toast with Action") + } + .buttonStyle(SBBSecondaryButtonStyle()) + Button(action: { + let uuid = UUID() + counter += 1 + toastService.showToast(SBBToast(label: Text("Hello Toast \(counter)"), id: uuid, actionLabel: Text("Remove it"), onClickAction: { + toastService.removeToast(where: { $0.id == uuid }) + })) + }) { + Text("Show Toast with Action") + } + .buttonStyle(SBBPrimaryButtonStyle()) } .sbbScreenPadding() } @@ -36,7 +57,6 @@ struct ToastDemo: View { .sbbStyle() .sbbToastContainer() .colorScheme(colorScheme) - } }