diff --git a/elem.go b/elem.go index 9ee87e2..610f4fd 100644 --- a/elem.go +++ b/elem.go @@ -148,9 +148,13 @@ func (e *Element) RenderTo(builder *strings.Builder, opts RenderOptions) { builder.WriteString("") } + isFragment := e.Tag == "fragment" + // Start with opening tag - builder.WriteString("<") - builder.WriteString(e.Tag) + if !isFragment { + builder.WriteString("<") + builder.WriteString(e.Tag) + } // Sort the keys for consistent order keys := make([]string, 0, len(e.Attrs)) @@ -170,18 +174,22 @@ func (e *Element) RenderTo(builder *strings.Builder, opts RenderOptions) { return } - // Close opening tag - builder.WriteString(`>`) + if !isFragment { + // Close opening tag + builder.WriteString(`>`) + } // Build the content for _, child := range e.Children { child.RenderTo(builder, opts) } - // Append closing tag - builder.WriteString(``) - builder.WriteString(e.Tag) - builder.WriteString(`>`) + if !isFragment { + // Append closing tag + builder.WriteString(``) + builder.WriteString(e.Tag) + builder.WriteString(`>`) + } } // return string representation of given attribute with its value diff --git a/elements.go b/elements.go index af540a7..6b57945 100644 --- a/elements.go +++ b/elements.go @@ -530,3 +530,8 @@ func Raw(html string) RawNode { func CSS(content string) TextNode { return TextNode(content) } + +// Fragments are a way to group multiple elements together without adding an extra node to the DOM. +func Fragment(children ...Node) *Element { + return newElement("fragment", attrs.Props{}, children...) +} diff --git a/elements_test.go b/elements_test.go index 15d8f40..223163c 100644 --- a/elements_test.go +++ b/elements_test.go @@ -696,3 +696,32 @@ func TestSingleQuote(t *testing.T) { actual := el.Render() assert.Equal(t, expected, actual) } + +func TestFragment(t *testing.T) { + expected := `
0
1
2
3
4