// // List.swift // MacBackend // // Created by david-swift on 23.11.2024. // import SwiftUI /// A list widget. public struct List: SwiftUIWidget where Element: Identifiable { /// The elements. var elements: [Element] /// The selected element. var selection: Meta.Binding /// The content for an element. var content: (Element) -> Body /// The action at the bottom. var bottomAction: ((String, Icon), () -> Void)? /// The wrapped views. public var wrappedViews: [String: any Meta.AnyView] { elements.reduce(into: [:]) { partialResult, element in partialResult["\(element.id)"] = content(element) } } /// Initialize a list widget. /// - Parameters: /// - elements: The elements. /// - selection: The selected element. /// - content: The content for an element. public init( _ elements: [Element], selection: Meta.Binding, @Meta.ViewBuilder content: @escaping (Element) -> Body ) { self.elements = elements self.content = content self.selection = selection } /// Get the SwiftUI view. /// - Parameter properties: The widget data. /// - Returns: The SwiftUI view. public static func view(properties: Self) -> some SwiftUI.View { SwiftUI.List(properties.elements, selection: properties.selection.swiftUI) { element in MacBackendView("\(element.id)") } .safeAreaInset(edge: .bottom, alignment: .leading) { if let action = properties.bottomAction { SwiftUI.Button { action.1() } label: { SwiftUI.Label { SwiftUI.Text(action.0.0) } icon: { action.0.1.image } } .buttonStyle(.plain) .foregroundStyle(.secondary) .symbolVariant(.circle) .padding([.bottom, .leading], 7) } } } /// Add a button to the bottom of the list. /// - Parameters: /// - label: The button's label. /// - icon: The button's icon. /// - handler: The handler. /// - Returns: The list. public func bottomAction(_ label: String, icon: Icon, handler: @escaping () -> Void) -> Self { modify { $0.bottomAction = ((label, icon), handler) } } }