Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 43 additions & 0 deletions Sources/Elementary/Core/Group.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
/// A container that groups HTML content without introducing any additional HTML tags.
///
/// This type is useful when you want to return multiple sibling nodes from a single `some HTML`
/// context without adding an extra wrapper element.
///
/// - Note: In Embedded mode, the HTML builder currently supports up to **6 direct child views**
/// in a single block (because variadic generics aren't available there yet). You can exceed
/// that limit by nesting content inside one or more `Group` blocks.
public struct Group<Content: HTML>: HTML {
public typealias Tag = Never
public typealias Body = Never
public typealias Content = Content

public let content: Content

@inlinable
public init(@HTMLBuilder content: () -> Content) {
self.content = content()
}

@inlinable
public static func _render<Renderer: _HTMLRendering>(
_ html: consuming Self,
into renderer: inout Renderer,
with context: consuming _RenderingContext
) {
context.assertNoAttributes(self)
Content._render(html.content, into: &renderer, with: context)
}

@inlinable
@_unavailableInEmbedded
public static func _render<Renderer: _AsyncHTMLRendering>(
_ html: consuming Self,
into renderer: inout Renderer,
with context: consuming _RenderingContext
) async throws {
context.assertNoAttributes(self)
try await Content._render(html.content, into: &renderer, with: context)
}
}

extension Group: Sendable where Content: Sendable {}
18 changes: 18 additions & 0 deletions Tests/ElementaryTests/TagRenderingTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,24 @@ final class TagRenderingTests: XCTestCase {
)
}

func testRendersGroup() async throws {
try await HTMLAssertEqual(
div {
Group {
h1 {}
Group {
if true {
p {}
p {}
}
}
h1 {}
}
},
"<div><h1></h1><p></p><p></p><h1></h1></div>"
)
}

func testRendersOptionals() async throws {
try await HTMLAssertEqual(
div {
Expand Down