Skip to content

Commit

Permalink
feat: 🎸 [JIRA:HCPSDKFIORIUIKIT-2717] Feedback Patterns (#867)
Browse files Browse the repository at this point in the history
* feat: 🎸 [JIRA:HCPSDKFIORIUIKIT-2717] Feedback Patterns

1. Replace example icons
2. Dismiss banner message when modal sheet appear

* feat: 🎸 [JIRA:HCPSDKFIORIUIKIT-2717] Feedback Patterns

---------

Co-authored-by: dyongxu <[email protected]>
  • Loading branch information
hengyi-zhang and dyongxu authored Nov 13, 2024
1 parent 207a8c2 commit 640b1d8
Show file tree
Hide file tree
Showing 4 changed files with 58 additions and 17 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ struct BannerMultiMessageCustomInitExample: View {
}, turnOnSectionHeader: self.turnOnSectionHeader, messageItemView: { id in
if let (message, category) = getItemData(with: id) {
BannerMessage(icon: {
message.icon
(message.icon ?? EmptyView()).typeErased
}, title: {
Text(self.attributedMessageTitle(title: message.title, typeDesc: message.typeDesc))
}, closeAction: {
Expand Down Expand Up @@ -328,21 +328,23 @@ struct BannerMultiMessageCustomInitExample: View {
if self.firstName.isEmpty {
let tips = "First name is required."
self.firstNameErrorMessage = AttributedString(tips)
warningMessages.append(BannerMessageItemModel(id: self.firstNameId, icon: Image(fioriName: "fiori.warning"), title: tips, messageType: .critical))
warningMessages.append(BannerMessageItemModel(id: self.firstNameId, icon: Image(fioriName: "fiori.warning2"), title: tips, messageType: .critical))
} else if self.firstName.count > 20 {
let tips = "First name is too long."
self.firstNameErrorMessage = AttributedString(tips)
errorMessages.append(BannerMessageItemModel(id: self.firstNameId, icon: Image(fioriName: "fiori.notification.3"), title: tips, messageType: .negative))
} else {
let tips = "First name correct."
self.firstNameErrorMessage = AttributedString()
informationMessages.append(BannerMessageItemModel(id: self.firstNameId, icon: Image(fioriName: "fiori.hint"), title: tips, messageType: .positive))
informationMessages.append(BannerMessageItemModel(id: self.firstNameId, icon: EmptyView(), title: tips, messageType: .positive))

informationMessages.append(BannerMessageItemModel(id: UUID(), icon: EmptyView(), title: tips, messageType: .positive))
}

if self.lastName.isEmpty {
let tips = "Last name is required."
self.lastNameErrorMessage = AttributedString(tips)
warningMessages.append(BannerMessageItemModel(id: self.lastNameId, icon: Image(fioriName: "fiori.warning"), title: tips, messageType: .critical))
warningMessages.append(BannerMessageItemModel(id: self.lastNameId, icon: Image(fioriName: "fiori.warning2"), title: tips, messageType: .critical))
} else if self.lastName.count > 20 {
let tips = "Last name is too long."
self.lastNameErrorMessage = AttributedString(tips)
Expand All @@ -356,7 +358,7 @@ struct BannerMultiMessageCustomInitExample: View {
if self.emailAddress.isEmpty {
let tips = "Email address is required!"
self.emailAddressErrorMessage = AttributedString(tips)
warningMessages.append(BannerMessageItemModel(id: self.emailAddressId, icon: Image(fioriName: "fiori.warning"), title: tips, messageType: .critical))
warningMessages.append(BannerMessageItemModel(id: self.emailAddressId, icon: Image(fioriName: "fiori.warning2"), title: tips, messageType: .critical))
} else if self.isEmailInvalid {
let tips = "Email address is Invalid! This can be multiple lines. This can be multiple lines. This can be multiple lines. This can be multiple lines. This can be multiple lines. This can be multiple lines. This can be multiple lines. This can be multiple lines."
self.emailAddressErrorMessage = AttributedString(tips)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -216,21 +216,23 @@ struct BannerMultiMessageExample: View {
if self.firstName.isEmpty {
let tips = "First name is required."
self.firstNameErrorMessage = AttributedString(tips)
warningMessages.append(BannerMessageItemModel(id: self.firstNameId, icon: Image(fioriName: "fiori.warning"), title: tips, messageType: .critical))
warningMessages.append(BannerMessageItemModel(id: self.firstNameId, icon: Image(fioriName: "fiori.warning2"), title: tips, messageType: .critical))
} else if self.firstName.count > 20 {
let tips = "First name is too long."
self.firstNameErrorMessage = AttributedString(tips)
errorMessages.append(BannerMessageItemModel(id: self.firstNameId, icon: Image(fioriName: "fiori.notification.3"), title: tips, messageType: .negative))
} else {
let tips = "First name correct."
self.firstNameErrorMessage = AttributedString()
informationMessages.append(BannerMessageItemModel(id: self.firstNameId, icon: Image(fioriName: "fiori.hint"), title: tips, messageType: .positive))
informationMessages.append(BannerMessageItemModel(id: self.firstNameId, icon: Image(fioriName: "fiori.home"), title: tips + " Developer custom icon.", messageType: .positive))
informationMessages.append(BannerMessageItemModel(id: UUID(), icon: EmptyView(), title: tips + " Empty icon.", messageType: .positive))
informationMessages.append(BannerMessageItemModel(id: UUID(), icon: nil, title: tips + " SDK default icon.", messageType: .positive))
}

if self.lastName.isEmpty {
let tips = "Last name is required."
self.lastNameErrorMessage = AttributedString(tips)
warningMessages.append(BannerMessageItemModel(id: self.lastNameId, icon: Image(fioriName: "fiori.warning"), title: tips, messageType: .critical))
warningMessages.append(BannerMessageItemModel(id: self.lastNameId, icon: Image(fioriName: "fiori.warning2"), title: tips, messageType: .critical))
} else if self.lastName.count > 20 {
let tips = "Last name is too long."
self.lastNameErrorMessage = AttributedString(tips)
Expand All @@ -244,7 +246,7 @@ struct BannerMultiMessageExample: View {
if self.emailAddress.isEmpty {
let tips = "Email address is required!"
self.emailAddressErrorMessage = AttributedString(tips)
warningMessages.append(BannerMessageItemModel(id: self.emailAddressId, icon: Image(fioriName: "fiori.warning"), title: tips, messageType: .critical))
warningMessages.append(BannerMessageItemModel(id: self.emailAddressId, icon: Image(fioriName: "fiori.warning2"), title: tips, messageType: .critical))
} else if self.isEmailInvalid {
let tips = "Email address is Invalid!"
self.emailAddressErrorMessage = AttributedString(tips)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -317,7 +317,7 @@ public extension View {
}

struct BannerMessageModifier: ViewModifier {
let icon: any View
let icon: (any View)?
var title: (any View)?
@Binding var isPresented: Bool
@Binding var pushContentDown: Bool
Expand All @@ -337,7 +337,7 @@ struct BannerMessageModifier: ViewModifier {

@State private var showingMessageDetail: Bool = false

init(icon: any View, title: (any View)? = nil, isPresented: Binding<Bool>, pushContentDown: Binding<Bool>, bannerTapped: (() -> Void)? = nil, viewDetailAction: ((UUID) -> Void)? = nil, alignment: HorizontalAlignment, hideSeparator: Bool, messageType: BannerMultiMessageType, turnOnSectionHeader: Bool, showDetailLink: Bool, bannerMultiMessages: Binding<[BannerMessageListModel]>) {
init(icon: (any View)? = nil, title: (any View)? = nil, isPresented: Binding<Bool>, pushContentDown: Binding<Bool>, bannerTapped: (() -> Void)? = nil, viewDetailAction: ((UUID) -> Void)? = nil, alignment: HorizontalAlignment, hideSeparator: Bool, messageType: BannerMultiMessageType, turnOnSectionHeader: Bool, showDetailLink: Bool, bannerMultiMessages: Binding<[BannerMessageListModel]>) {
self.icon = icon
self.title = title
_isPresented = isPresented
Expand Down Expand Up @@ -408,9 +408,24 @@ struct BannerMessageModifier: ViewModifier {
return NSLocalizedString(key + (count > 1 ? "s" : ""), tableName: "FioriSwiftUICore", bundle: Bundle.accessor, comment: "")
}

@ViewBuilder var defaultIcon: some View {
switch self.messageType {
case .neutral:
Image(fioriName: "fiori.hint")
case .informative:
Image(fioriName: "fiori.hint")
case .positive:
Image(fioriName: "fiori.hint")
case .critical:
Image(fioriName: "fiori.warning2")
case .negative:
Image(fioriName: "fiori.notification.3")
}
}

@ViewBuilder var bannerMessage: some View {
BannerMessage(icon: {
self.icon
(self.icon ?? self.defaultIcon).typeErased
}, title: {
if let title = self.title {
AnyView(title)
Expand All @@ -419,6 +434,10 @@ struct BannerMessageModifier: ViewModifier {
.environment(\.openURL, OpenURLAction(handler: { url in
if url.absoluteString == "ViewDetails" {
self.showingMessageDetail = true

if UIDevice.current.userInterfaceIdiom == .phone {
self.isPresented = false
}
}
return .handled
}))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import SwiftUI
public struct BannerMessageItemModel: Identifiable {
public var id: UUID
/// Banner icon
public var icon: any View
public var icon: (any View)?
/// Banner title
public var title: String
/// Message Type
Expand All @@ -37,7 +37,7 @@ public struct BannerMessageItemModel: Identifiable {
}
}

public init(id: UUID = UUID(), icon: any View, title: String, messageType: BannerMultiMessageType) {
public init(id: UUID = UUID(), icon: (any View)?, title: String, messageType: BannerMultiMessageType) {
self.id = id
self.icon = icon
self.title = title
Expand Down Expand Up @@ -200,6 +200,21 @@ public struct BannerMultiMessageSheetBaseStyle: BannerMultiMessageSheetStyle {
}
}

func defaultIcon(_ messageType: BannerMultiMessageType) -> some View {
switch messageType {
case .neutral:
Image(fioriName: "fiori.hint")
case .informative:
Image(fioriName: "fiori.hint")
case .positive:
Image(fioriName: "fiori.hint")
case .critical:
Image(fioriName: "fiori.warning2")
case .negative:
Image(fioriName: "fiori.notification.3")
}
}

// swiftlint:disable:next function_body_length
public func makeBody(_ configuration: BannerMultiMessageSheetConfiguration) -> some View {
VStack(spacing: 0, content: {
Expand Down Expand Up @@ -249,9 +264,12 @@ public struct BannerMultiMessageSheetBaseStyle: BannerMultiMessageSheetStyle {
.foregroundStyle(Color.preferredColor(.secondaryLabel))
Spacer()

_Action(actionText: _ClearActionDefault().actionText, didSelectAction: {
Button {
self.removeCategoryAction(configuration, category: element.category)
})
} label: {
Text(_ClearActionDefault().actionText ?? "")
}
.buttonStyle(PlainButtonStyle())
.font(.fiori(forTextStyle: .subheadline))
.foregroundStyle(Color.preferredColor(.tintColor))
}
Expand All @@ -265,7 +283,7 @@ public struct BannerMultiMessageSheetBaseStyle: BannerMultiMessageSheetStyle {
AnyView(configuration.messageItemView(message.id))
} else {
BannerMessage(icon: {
message.icon
(message.icon ?? self.defaultIcon(message.messageType)).typeErased
}, title: {
Text(self.attributedMessageTitle(title: message.title, typeDesc: message.typeDesc))
}, closeAction: {
Expand Down

0 comments on commit 640b1d8

Please sign in to comment.