Add `merge_class` and `build` (or similar) methods to builder.
Closed this issue · 4 comments
Imo 2 features missing from variant()
builders:
- A way to add custom classes (via merge (like
with_class
but outputs the builder) without converting to string. build()
on the builder to output the mainTwClass
struct.
Why?
I started thinking about this when there's a component with 2 layers (e.g. div
inside div
). I need to apply one of the variant's classes to the inner div, and the others to the outer. If I could supply the TwClass
struct to the component, it would be able to render variants and decompose as needed. Hence the need to build()
the builder into the TwClass
and allow the external code to override classes on the builder, without actually converting to a string yet, as the component handles that part.
If there's a better way to solve the use case, that would be fine too!
Update: I solved this with nested specifiers.
Feel free to close if that's how you want to support this use case but could still be useful in more complex cases. :)
I think this is reasonable, thank you for the suggestion. Makes me re-think the API a bit.
- Add
add_class()
method to Builder struct, that will write to anOption<String>
field. - Rename
variant()
method tobuilder()
for the sake of clarity
#[derive(TwClass)]
struct Btn {
size: BtnSize,
color: BtnColor,
}
#[derive(TwVariant)]
enum BtnSize {
#[tw(default, class = "h-9 px-4 py-2")]
Default,
#[tw(class = "h-8 px-3")]
Sm,
#[tw(class = "h-10 px-8")]
Lg,
}
#[derive(TwVariant)]
enum BtnColor {
#[tw(default, class = "bg-blue-500 text-blue-100")]
Blue,
#[tw(class = "bg-red-500 text-red-100")]
Red,
}
let builder1 = Btn::builder().add_class("flex");
// Now you can clone the builder.
let builder2 = builder1.clone()
let class1 = builder1.to_class()
// more that one add_class call would append to end of string.
let class2 = builder2.add_class("items-center").to_class()
The build method also makes sense. I will probably implement From<BtnBuilder> for Btn
and vice-versa, and just invoke these conversions from the appropriately named methods.
Let me know what you think @zakstucke @friendlymatthew
closed by #17
elected to not have string field in builder because that would prevent it from implementing Copy
@nicoburniske thanks for this! The build()
is great, it allows ways of getting around the custom classes thing too.
Main pattern I'm normally using now is accepting the fuse class (after build()
), then any class string overrides (usually just for the main class struct, but sometimes for variants too) that can be all managed internally in the component if needed.