8000 Make Groups renderable by markuswustenberg · Pull Request #181 · maragudk/gomponents · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content

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

Merged
merged 5 commits into from
Sep 19, 2024
Merged

Make Groups renderable #181

merged 5 commits into from
Sep 19, 2024

Conversation

markuswustenberg
Copy link
Member
@markuswustenberg markuswustenberg commented Jun 25, 2024

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 rendering Group 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 and Fragment) do essentially the same thing, the only difference being whether the argument was a slice of Nodes or varargs.

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.

@markuswustenberg
Copy link
Member Author

I've been thinking about this over the summer on and off.

What if we instead made Group accept a generic type T that is either a slice of Nodes, or just a Node, and made the argument varargs? If possible, that would be backwards-compatible and essentially do exactly what Fragment does.

@markuswustenberg
Copy link
Member Author

Hmm. I had a small go at it. I'm hitting a compile time error, basically because I can't use interface { Node | []Node} as a type constraint. Will investigate further.

@markuswustenberg markuswustenberg changed the title Add Fragment Make Groups renderable Sep 19, 2024
@markuswustenberg
Copy link
Member Author

I ended up deleting Fragment and just making the Group renderable. I think this is a good compromise.

@markuswustenberg markuswustenberg merged commit c97605a into main Sep 19, 2024
9 checks passed
@markuswustenberg markuswustenberg deleted the fragment branch September 19, 2024 15:03
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
0