Open giantpand2000 opened 2 years ago
I'm on board :) I think this is very useful when using this crate more directly.
Additions:
Using NodeRef(s) might be a better way to get information about individual nodes from the tree builder. The idea comes from Yew's NodeRef. Both interior mutability and initialization tests are provided.
Inspired by this discussion on Discord, I have come to the opinion that an API that automatically creates a Style::DEFAULT
and then passes a mutable reference to the created style object into a closure might be particularly nice to use:
Something like:
Style::build(|style| {
style.width = points(100.);
style.height = points(200.);
});
where the style
parameter is an &mut Style
.
With setters on Style
this could become:
Style::build(|style| style.width(100.).height(200.))
where the style
parameter is an &mut Style
.
And if trait a were used to accept a tuple of callbacks / types implementing a trait, than we could potentially create an API like the following (which would also allow the easier creation of user-defined style helpers):
Style::build((width(100.), height(200.))
Style::build((width(100.), height(200.))
I really like this pattern!
I think something like the following would be quite easy to create:
let root_node = Style::column()
.width(800)
.height(100)
.with_children(|tree| {
Style::leaf().width(800).height(100).build(&mut tree);
Style::leaf().width(800).flex_grow(1.0).build(&mut tree);
})
.build(&mut tree);
This is the same as the example in the README. It's quite an improvement!
A couple of other API idea that I think would be doable.
With nested builders, closures taking &mut Style
and dedicated constructors for row/column/grid:
let root_node_id = taffy.new_flex_column(
|style| style.width(800).height(600),
|cx| {
cx.new_leaf(|style| style.height(100));
cx.new_leaf(|style| style.flex_grow(1.0));
},
);
Using a macro (yoga-rs
implements an API like this using a simple macro_rules macro):
let root_node_id = taffy.new_flex_column(style! {width: 800 px, height: 600 px}, |cx| {
cx.new_leaf(style! {height: 800 px});
cx.new_leaf(style! {flex_grow: 1.0});
});
The builder approach is my favorite here stylistically :) Would like to avoid macros if possible, and closures can be rough for beginners.
What problem does this solve or what need does it fill?
Provides a more compact, write-friendly, ergonomic interface
What solution would you like?
What alternative(s) have you considered?
Since many anonymous nodes are used, a method of result feedback is needed, such as having the node save a callback function, or a Trait that provides result feedback
Additional context
The sample code comes from the Yoga home page, a Java package called litho. But it can be translated quite directly to Rust code.