Skip to content
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

Add Fragment #181

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open

Add Fragment #181

wants to merge 2 commits into from

Conversation

markuswustenberg
Copy link
Member

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

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
@markuswustenberg
Copy link
Member Author

@JulienTant @eduardolat I ended up making a separate function Fragment AND made Group renderable. If you like and have the time, could you have a look?

@amrojjeh
Copy link
Contributor

Does Fragment make Group obsolete?

@markuswustenberg
Copy link
Member Author

@amrojjeh yes and no. But I've basically never used Group and not used Map with it, so I think Fragment is more useful when not using Map. See the updated doc comments for the two functions.

@amrojjeh
Copy link
Contributor

Gotcha. That makes sense

@eduardolat
Copy link

@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 gomponents.Map, I have created a utility function in my project that uses both concepts (map and group), basically it works exactly the same as Map, but it only returns one node, it has been very useful to me, maybe it can help you:

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 MapToFragment that directly returns a gomponents.Fragment and not a []gomponents.Group. Or if your vision of the project is to remove the group function, you can modify the Map function signature directly

@markuswustenberg
Copy link
Member Author

@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 Group now, but maybe that's a bit too late to change now without breaking a lot of people's code.

@eduardolat
Copy link

@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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Make Group renderable
4 participants