Skip to content

Commit

Permalink
Add support for for loops in View.
Browse files Browse the repository at this point in the history
Closes #20
  • Loading branch information
jverkoey committed Aug 2, 2024
1 parent 450e1ea commit 30d68f5
Show file tree
Hide file tree
Showing 4 changed files with 48 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

- ``ViewBuilder/buildBlock(_:)-eqvl``
- ``ViewBuilder/buildBlock(_:)-2hz2p``
- ``ViewBuilder/buildArray(_:)``

### Conditionally building content

Expand Down
19 changes: 19 additions & 0 deletions Sources/Slipstream/Views/Fundamentals/ViewBuilder/ArrayView.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import SwiftSoup

/// A View created from a for loop of View values.
@_documentation(visibility: private)
public struct ArrayView: View {
public typealias Content = Never

init(array: [any View]) {
self.array = array
}

private var array: [any View]

public func render(_ container: Element, environment: EnvironmentValues) throws {
for view in array {
try view.render(container, environment: environment)
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,6 @@ public struct ViewBuilder {
return .init(condition: .isTrue(first))
}


/// An if/else statement, when the condition returns false.
///
/// An example:
Expand All @@ -70,4 +69,20 @@ public struct ViewBuilder {
where TrueContent: View, FalseContent: View {
return .init(condition: .isFalse(second))
}

/// Gathers the results of a loop into a single view.
///
/// An example:
///
/// ```swift
/// var body: some View {
/// for i in 1...3 {
/// Text("\(i)")
/// }
/// }
/// ```
public static func buildArray<Content>(_ components: [Content]) -> ArrayView
where Content: View {
ArrayView(array: components)
}
}
12 changes: 12 additions & 0 deletions Tests/SlipstreamTests/ViewBuilderTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,14 @@ private struct ConditionalBlockView: View {
}
}

private struct ArrayBlockView: View {
var body: some View {
for i in 1...3 {
Text("\(i)")
}
}
}

struct ViewBuilderTests {
@Test func singleBlock() throws {
try #expect(renderHTML(SingleBlockView()) == "Hello, world!")
Expand All @@ -39,4 +47,8 @@ struct ViewBuilderTests {
try #expect(renderHTML(ConditionalBlockView(bool: true)) == "true")
try #expect(renderHTML(ConditionalBlockView(bool: false)) == "false")
}

@Test func arrayBlock() throws {
try #expect(renderHTML(ArrayBlockView()) == "123")
}
}

0 comments on commit 30d68f5

Please sign in to comment.