Closed cryptoquick closed 2 years ago
Thanks for the issue @cryptoquick. There is a way to get this done now, without changes, though it is a bit of an HTML hack. The solution involves using the slot
element, which is a special type of HTML element used for presenting separate DOM trees at the same time together.
fn component() -> ViewBuilder<Vec<HtmlElement>> {
builder! {
<slot>
<div></div>
<div></div>
</slot>
}
}
fn parent_component() -> ViewBuilder<HtmlElement> {
builder! {
<div id="wrap">
{component()}
</div>
}
}
The slot
element has no style of its own and is effectively not rendered, but the content inside it is rendered. The only bummer is that it doesn't work on IE.
Let me know your thoughts.
I'd prefer not having any extraneous markup rendering in the document. That's the point of using fragments, to omit, say, a wrapper div in the HTML from the returned component.
I'm investigating this now. The main issue is SsrNode
needs to be expanded to support fragments.
:rubber_ducking:
Another complication is that after a DocumentFragment
is added to the DOM, its child nodes are drained and given to the parent the fragment was added to. This has the ramification that any streams with side-effects affecting the fragment are either on the wrong target (they should be on the new parent) or are mutating the out-of-band fragment.
Turns out I was thinking too hard about this. Instead of ViewBuilder<Vec<Dom>>
we can simply allow appending iterators of ViewBuilder
or Into<ViewBuilder>
:
let vs: Vec<ViewBuilder<Dom>> = builder! {
<div>"hello"</div>
<div>"hola"</div>
<div>"kia ora"</div>
};
let s: ViewBuilder<Dom> = builder! {
<section>{vs}</section>
};
let view: View<Dom> = s.try_into().unwrap();
assert_eq!(
String::from(view).as_str(),
"<section><div>hello</div> <div>hola</div> <div>kia ora</div></section>"
);
This will be available in the 0.5 release.
Love it! Looking forward to it.
also, Rust rly do be like that sometimes uwu
I'm aware not all JSX idioms don't always map to TEA projects, but I was wondering if it might be nice to be able to do either of these:
JSX Fragment Syntax
ViewBuilder<Vec<HtmlElement>>
Right now I have to do it this way, which is perfectly fine, I suppose:
Just a nice-to-have.