From b17f05a6a0c3ab0247a8334c329d0e6f0bfde092 Mon Sep 17 00:00:00 2001 From: david-swift Date: Tue, 31 Dec 2024 09:55:02 +0100 Subject: [PATCH] Add support for ForEach --- Sources/Core/View/Alert.swift | 2 +- Sources/Core/View/ForEach.swift | 63 +++++++++++++++++++++++++++++ Sources/Core/View/HStack.swift | 2 +- Sources/Core/View/Picker.swift | 2 +- Sources/Core/View/ToolbarView.swift | 6 +-- Sources/Core/View/VStack.swift | 2 +- 6 files changed, 70 insertions(+), 7 deletions(-) create mode 100644 Sources/Core/View/ForEach.swift diff --git a/Sources/Core/View/Alert.swift b/Sources/Core/View/Alert.swift index 2711ea8..48a648b 100644 --- a/Sources/Core/View/Alert.swift +++ b/Sources/Core/View/Alert.swift @@ -101,7 +101,7 @@ public struct Alert: SwiftUIWidget { public static func view(properties: Self) -> some SwiftUI.View { MacBackendView(.mainContent) .alert(properties.title, isPresented: properties.isPresented.swiftUI) { - ForEach(Array(properties.actions.enumerated()), id: \.offset) { action in + SwiftUI.ForEach(Array(properties.actions.enumerated()), id: \.offset) { action in action.element.button } } message: { diff --git a/Sources/Core/View/ForEach.swift b/Sources/Core/View/ForEach.swift new file mode 100644 index 0000000..9a62c5d --- /dev/null +++ b/Sources/Core/View/ForEach.swift @@ -0,0 +1,63 @@ +// +// ForEach.swift +// MacBackend +// +// Created by david-swift on 31.12.2024. +// + +import SwiftUI + +/// Align a dynamic number of items horizontally or vertically. +public struct ForEach: SwiftUIWidget where Item: Identifiable { + + /// The data. + var data: [Item] + /// The content. + var content: (Item) -> Body + /// Whether the items are aligned horizontally. + var horizontal: Bool + + /// The wrapped views. + public var wrappedViews: [String: Meta.AnyView] { + data.reduce([:]) { partialResult, item in + var partialResult = partialResult + partialResult[item.id.hashValue.description] = content(item) + return partialResult + } + } + + /// Initialize a ``ForEach`` view. + /// - Parameters: + /// - data: The data. + /// - horizontal: Whether the items are aligned horizontally. + /// - content: The content for each data item. + public init( + _ data: [Item], + horizontal: Bool = false, + @Meta.ViewBuilder content: @escaping (Item) -> Body + ) { + self.data = data + self.content = content + self.horizontal = horizontal + } + + /// Get the SwiftUI view. + /// - Parameter properties: The widget data. + /// - Returns: The SwiftUI view. + @SwiftUI.ViewBuilder + public static func view(properties: Self) -> some SwiftUI.View { + let forEach = SwiftUI.ForEach(properties.data) { item in + MacBackendView(item.id.hashValue.description) + } + if properties.horizontal { + SwiftUI.HStack { + forEach + } + } else { + SwiftUI.VStack { + forEach + } + } + } + +} diff --git a/Sources/Core/View/HStack.swift b/Sources/Core/View/HStack.swift index 458e2f1..e4c851b 100644 --- a/Sources/Core/View/HStack.swift +++ b/Sources/Core/View/HStack.swift @@ -31,7 +31,7 @@ public struct HStack: SwiftUIWidget { /// - Returns: The SwiftUI view. public static func view(properties: Self) -> some SwiftUI.View { SwiftUI.HStack { - ForEach(properties.content.indices, id: \.self) { index in + SwiftUI.ForEach(properties.content.indices, id: \.self) { index in MacBackendView("\(index)") } } diff --git a/Sources/Core/View/Picker.swift b/Sources/Core/View/Picker.swift index ee0e031..213efef 100644 --- a/Sources/Core/View/Picker.swift +++ b/Sources/Core/View/Picker.swift @@ -35,7 +35,7 @@ public struct Picker: SwiftUIWidget where Item: Hashable, Item: CustomStri /// - Returns: The SwiftUI view. public static func view(properties: Picker) -> some SwiftUI.View { let picker = SwiftUI.Picker(properties.label, selection: properties._selection.swiftUI) { - ForEach(properties.items, id: \.hashValue) { item in + SwiftUI.ForEach(properties.items, id: \.hashValue) { item in SwiftUI.Text(item.description) .tag(item.description) } diff --git a/Sources/Core/View/ToolbarView.swift b/Sources/Core/View/ToolbarView.swift index 00fec95..4c514c6 100644 --- a/Sources/Core/View/ToolbarView.swift +++ b/Sources/Core/View/ToolbarView.swift @@ -55,7 +55,7 @@ public struct ToolbarView: SwiftUIWidget { case .end: MacBackendView(.mainContent) .toolbar { - ForEach(properties.toolbarViews.indices, id: \.self) { index in + SwiftUI.ForEach(properties.toolbarViews.indices, id: \.self) { index in MacBackendView("\(index)") } } @@ -64,7 +64,7 @@ public struct ToolbarView: SwiftUIWidget { .toolbar { ToolbarItem(placement: .navigation) { SwiftUI.HStack { - ForEach(properties.toolbarViews.indices, id: \.self) { index in + SwiftUI.ForEach(properties.toolbarViews.indices, id: \.self) { index in MacBackendView("\(index)") } } @@ -75,7 +75,7 @@ public struct ToolbarView: SwiftUIWidget { .toolbar { ToolbarItem(placement: .principal) { SwiftUI.HStack { - ForEach(properties.toolbarViews.indices, id: \.self) { index in + SwiftUI.ForEach(properties.toolbarViews.indices, id: \.self) { index in MacBackendView("\(index)") } } diff --git a/Sources/Core/View/VStack.swift b/Sources/Core/View/VStack.swift index 7852969..87bf69f 100644 --- a/Sources/Core/View/VStack.swift +++ b/Sources/Core/View/VStack.swift @@ -31,7 +31,7 @@ public struct VStack: SwiftUIWidget, Wrapper { /// - Returns: The SwiftUI view. public static func view(properties: Self) -> some SwiftUI.View { SwiftUI.VStack { - ForEach(properties.content.indices, id: \.self) { index in + SwiftUI.ForEach(properties.content.indices, id: \.self) { index in MacBackendView("\(index)") } }