-
-
Notifications
You must be signed in to change notification settings - Fork 49
Make Groups renderable #181
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
This change adds a `Fragment` top-level function, to render multiple elements without a parent element. It's basically the same as `Group`, except the function signature matches the style of the other functions by being variadic. But I also made `Group` renderable directly, with the important caveat that root-level attributes are _ignored_. I don't think this will give problems in practice, as the main use case for `Fragment` is basically to return root-level elements to the client using something like HTMX. Fixes #162
@JulienTant @eduardolat I ended up making a separate function |
Does |
@amrojjeh yes and no. But I've basically never used |
Gotcha. That makes sense |
@markuswustenberg This reminds me a lot of react fragments and I love it! It is a good solution (imho better than group) and a very well chosen name Regarding your mention of package components
import "github.com/maragudk/gomponents"
// GMap is a convenience function to render a gomponents.Group
// with a map inside.
func GMap[T any](ts []T, cb func(T) gomponents.Node) gomponents.Node {
return gomponents.Group(gomponents.Map(ts, cb))
} Here I give you an example of how i use the GMap function var options = []string{
"Option 1",
"Option 2",
"Option 3",
}
func Before() gomponents.Node {
return html.Select(
html.ID("picked_option"),
html.Name("picked_option"),
// I can't use map directly here, because it returns a []gomponents.Node
gomponents.Group(
gomponents.Map(
options,
func(option string) gomponents.Node {
return html.Option(
html.Value(option),
gomponents.Text(option),
)
},
),
),
)
}
func After() gomponents.Node {
return html.Select(
html.ID("picked_option"),
html.Name("picked_option"),
// Here I use the GMap function, this allows me to prevent one
// level of indentation and a bit of boilerplate.
GMap(
options,
func(option string) gomponents.Node {
return html.Option(
html.Value(option),
gomponents.Text(option),
)
},
),
)
} Maybe it would be useful to add a function to the project that does this same thing, for example a function like |
@eduardolat thank you for the feedback! I'll leave this PR open for a bit, so I and others can think it over. It is a bit weird to have |
@markuswustenberg Excellent!! Remember that in the README there is a warning that says "The API may change until version 1 is reached" Perhaps future adopters of Gomponents will be happier if the API is based on real cases tested in production and generates as few headaches as possible, which can be achieved if there is only one simple and correct way of doing things. In addition, the Golang compiler would help a lot when migrating to v1. However in any case Gomponents is fantastic, boring as golang is. Thanks again for your effort on this great project. |
I've been thinking about this over the summer on and off. What if we instead made |
Hmm. I had a small go at it. I'm hitting a compile time error, basically because I can't use |
I ended up deleting |
This change makes the result of
Group
renderable directly, instead of panicking, with the important caveat that root-level attributes are ignored. I don't think this will give problems in practice, as the main use case for renderingGroup
is basically to return root-level elements to the client using something like HTMX.I tried adding a
Fragment
, but it was weird and confusing having two functions (Group
andFragment
) do essentially the same thing, the only difference being whether the argument was a slice ofNode
s or varargs.Fixes #162