From 6d2fb0eeb15d6b9774f127517d160137251264a4 Mon Sep 17 00:00:00 2001
From: Markus Wüstenberg
Date: Thu, 22 Oct 2020 09:07:57 +0200
Subject: Add Group function to group Nodes (#29)

---
 gomponents.go | 47 ++++++++++++++++++++++++++++++++++++-----------
 1 file changed, 36 insertions(+), 11 deletions(-)

(limited to 'gomponents.go')

diff --git a/gomponents.go b/gomponents.go
index 52d5355..c0aa510 100644
--- a/gomponents.go
+++ b/gomponents.go
@@ -64,17 +64,7 @@ func El(name string, children ...Node) NodeFunc {
 		}
 
 		for _, c := range children {
-			if p, ok := c.(Placer); ok {
-				switch p.Place() {
-				case Inside:
-					inside.WriteString(c.Render())
-				case Outside:
-					outside.WriteString(c.Render())
-				}
-				continue
-			}
-			// If c doesn't implement Placer, default to outside
-			outside.WriteString(c.Render())
+			renderChild(c, &inside, &outside)
 		}
 
 		b.WriteString(inside.String())
@@ -93,6 +83,26 @@ func El(name string, children ...Node) NodeFunc {
 	}
 }
 
+func renderChild(c Node, inside, outside *strings.Builder) {
+	if g, ok := c.(group); ok {
+		for _, groupC := range g.children {
+			renderChild(groupC, inside, outside)
+		}
+		return
+	}
+	if p, ok := c.(Placer); ok {
+		switch p.Place() {
+		case Inside:
+			inside.WriteString(c.Render())
+		case Outside:
+			outside.WriteString(c.Render())
+		}
+		return
+	}
+	// If c doesn't implement Placer, default to outside
+	outside.WriteString(c.Render())
+}
+
 // Attr creates an attr DOM Node.
 // If one parameter is passed, it's a name-only attribute (like "required").
 // If two parameters are passed, it's a name-value attribute (like `class="header"`).
@@ -156,3 +166,18 @@ func Write(w io.Writer, n Node) error {
 	_, err := w.Write([]byte(n.Render()))
 	return err
 }
+
+type group struct {
+	children []Node
+}
+
+func (g group) Render() string {
+	panic("cannot render group")
+}
+
+// Group multiple Nodes into one Node. Useful for concatenation of Nodes in variadic functions.
+// The resulting Node cannot Render directly, trying it will panic.
+// Render must happen through a parent element created with El or a helper.
+func Group(children []Node) Node {
+	return group{children: children}
+}
-- 
cgit 1.4.1