import SwiftUI struct GenerationIssuesActionView: View where S: Collection, T: Hashable & Comparable, S.Element == T { let title: String let statusWhenNonEmpty: IssueStatus let items: S let buttonText: String let itemText: (T) -> String let action: (T) -> Void @State private var showList = false var status: IssueStatus { items.isEmpty ? .nominal : statusWhenNonEmpty } init(title: String, statusWhenNonEmpty: IssueStatus = .error, items: S, buttonText: String, itemText: @escaping (T) -> String, action: @escaping (T) -> Void) { self.title = title self.statusWhenNonEmpty = statusWhenNonEmpty self.items = items self.buttonText = buttonText self.itemText = itemText self.action = action } var body: some View { HStack { Button(action: showListIfNonEmpty) { Image(systemSymbol: status.symbol) .foregroundStyle(status.color) }.buttonStyle(.plain) Text("\(items.count) \(title)") } .sheet(isPresented: $showList) { VStack { Text("\(items.count) \(title)") .font(.title) List(items.sorted(), id: \.self) { item in HStack { Text(itemText(item)) Spacer() Button(buttonText) { action(item) } } } .frame(minHeight: 400) Button("Close") { showList = false } }.padding() } } private func showListIfNonEmpty() { guard !items.isEmpty else { return } showList = true } } extension GenerationIssuesActionView where S == Set { init(title: String, statusWhenNonEmpty: IssueStatus = .error, items: Set, buttonText: String, action: @escaping (T) -> Void) { self.title = title self.statusWhenNonEmpty = statusWhenNonEmpty self.items = items self.buttonText = buttonText self.itemText = { $0 } self.action = action } }