diff --git a/Sources/Elementary/Core/Html+Attributes.swift b/Sources/Elementary/Core/Html+Attributes.swift index c35b89c..688f26f 100644 --- a/Sources/Elementary/Core/Html+Attributes.swift +++ b/Sources/Elementary/Core/Html+Attributes.swift @@ -79,6 +79,15 @@ public extension HTMLElement { self.attributes = .init(attributes) self.content = content() } + + /// Creates a new HTML element with the specified attributes and content. + /// - Parameters: + /// - attributes: The attributes to apply to the element as an array. + /// - content: The content of the element. + init(attributes: [HTMLAttribute], @HTMLBuilder content: () -> Content) { + self.attributes = .init(attributes) + self.content = content() + } } public extension HTMLVoidElement { @@ -93,6 +102,12 @@ public extension HTMLVoidElement { init(_ attributes: HTMLAttribute...) { self.attributes = .init(attributes) } + + /// Creates a new HTML void element with the specified attributes. + /// - Parameter attributes: The attributes to apply to the element as an array. + init(attributes: [HTMLAttribute]) { + self.attributes = .init(attributes) + } } public extension HTML where Tag: HTMLTrait.Attributes.Global { @@ -117,6 +132,15 @@ public extension HTML where Tag: HTMLTrait.Attributes.Global { func attributes(_ attributes: HTMLAttribute..., when condition: Bool = true) -> _AttributedElement { _AttributedElement(content: self, attributes: .init(condition ? attributes : [])) } + + /// Adds the specified attributes to the element. + /// - Parameters: + /// - attributes: The attributes to add to the element as an array. + /// - condition: If set to false, the attributes will not be added. + /// - Returns: A new element with the specified attributes added. + func attributes(contentsOf attributes: [HTMLAttribute], when condition: Bool = true) -> _AttributedElement { + _AttributedElement(content: self, attributes: .init(condition ? attributes : [])) + } } private extension _RenderingContext { diff --git a/Tests/ElementaryTests/AttributeRenderingTests.swift b/Tests/ElementaryTests/AttributeRenderingTests.swift index 8e93164..81ebb9a 100644 --- a/Tests/ElementaryTests/AttributeRenderingTests.swift +++ b/Tests/ElementaryTests/AttributeRenderingTests.swift @@ -102,4 +102,25 @@ final class AttributeRenderingTests: XCTestCase { #""# ) } + + func testRendersAttributesArray() async throws { + try await HTMLAssertEqual( + p(attributes: [.id("foo"), .class("foo"), .hidden]) {}, + #""# + ) + } + + func testRendersAttributesArrayOnVoidElement() async throws { + try await HTMLAssertEqual( + input(attributes: [.type(.text), .required]), + #""# + ) + } + + func testRendersAppliedConditionalAttributesArray() async throws { + try await HTMLAssertEqual( + img(.id("1")).attributes(contentsOf: [.class("2"), .id("no")], when: false).attributes(contentsOf: [.style("2")], when: true), + #""# + ) + } }