-
-
Notifications
You must be signed in to change notification settings - Fork 1.4k
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 html_nested!
macro to support nested iterable children access
#843
Conversation
@jstarry This work is complete. |
tests/macro/html-component-pass.rs
Outdated
if true { | ||
html! { <Container int=1 /> } | ||
} else { | ||
html! {} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks
html_nested!
macro to support nested iterable children access
@jstarry are you sure that you want to remove the If a developer is trying to write code like this:
This forces the developer to remember that |
Otherwise maybe we could call it something like: |
I don't think we can determine implicitly when |
Just tested this and it is breaking my code now. Getting:
For: return html! {
<>
{
self.props
.children
.iter()
.filter(|c| match &c.props {
Variants::Row(_) => true,
})
.map(|mut c| {
if let Variants::Row(ref mut props) = c.props {
props.context = Some(TableContext::Body);
}
c
})
.map(|c| c.into())
.collect::<Vec<VComp>>()
}
</>
}; Here is the expansion: return {
enum ProcMacroHack {
Nested = ( "< >\n{\n self . props . children . iter () . filter\n (| c | match & c . props { Variants :: Row (_) => true, }) . map\n (| mut c |\n {\n if let Variants :: Row (ref mut props) = c . props\n { props . context = Some (TableContext :: Body) ; } c\n }) . map (| c | c . into ()) . collect :: < Vec < VComp >> ()\n} < / >" , 0 ) . 1 , }
::yew::virtual_dom::VNode::VList(
::yew::virtual_dom::vlist::VList::new_with_children({
let mut v = ::std::vec::Vec::new();
v.extend(::yew::utils::NodeSeq::from(
::yew::virtual_dom::VNode::from({
self.props
.children
.iter()
.filter(|c| match &c.props {
Variants::Row(_) => true,
})
.map(|mut c| {
if let Variants::Row(ref mut props) = c.props {
props.context = Some(TableContext::Body);
}
c
})
.map(|c| c.into())
.collect::<Vec<VComp>>()
}),
));
v
}),
)
}; The expansion before the return {
enum ProcMacroHack {
Nested = ( "< >\n{\n self . props . children . iter () . filter\n (| c | match & c . props { Variants :: Row (_) => true, }) . map\n (| mut c |\n {\n if let Variants :: Row (ref mut props) = c . props\n { props . context = Some (TableContext :: Body) ; } c\n }) . map (| c | c . into ()) . collect :: < Vec < VComp >> ()\n} < / >" , 0 ) . 1 , }
::yew::virtual_dom::VNode::from(::yew::virtual_dom::VNode::VList(
::yew::virtual_dom::vlist::VList::new_with_children({
let mut v = ::std::vec::Vec::new();
let comps = ({
self.props
.children
.iter()
.filter(|c| match &c.props {
Variants::Row(_) => true,
})
.map(|mut c| {
if let Variants::Row(ref mut props) = c.props {
props.context = Some(TableContext::Body);
}
c
})
.map(|c| c.into())
.collect::<Vec<VComp>>()
},);
::yew::utils::NodeSeq::from(comps.0)
.into_iter()
.for_each(|x| v.push(x.into()));
v
}),
))
}; The reason this works and the other doesn't is because a tuple can hold multiple different types whereas a vector cannot. And the type coercion was happening when the tuple was iterated over and unloaded. This way it is impossible. |
@trivigy the reason your example code breaks is because I added back Why do you have |
@jstarry Consider the following example: There is collection into three different types. All need to be handled in such way so that the underlying table can have access to their props.
Statically this would work absolutely fine.
|
@trivigy what's the error? |
Because for right now I have this: return html! {
<>
{
self.props
.children
.iter()
.filter(|c| match c.props {
Variants::Head(_) => true,
_ => false,
})
.map(|c| c.into())
.collect::<Vec<VComp>>()
}
{
self.props
.children
.iter()
.filter(|c| match c.props {
Variants::Body(_) => true,
_ => false,
})
.map(|c| c.into())
.collect::<Vec<VComp>>()
}
{
self.props
.children
.iter()
.filter(|c| match c.props {
Variants::Foot(_) => true,
_ => false,
})
.map(|c| c.into())
.collect::<Vec<VComp>>()
}
</>
}; With this: impl Into<VComp> for Variant {
fn into(self) -> VComp {
match self.props {
Variants::Head(props) => VComp::new::<table_head::TableHead>(props, NodeRef::default()),
Variants::Body(props) => VComp::new::<table_body::TableBody>(props, NodeRef::default()),
Variants::Foot(props) => VComp::new::<table_foot::TableFoot>(props, NodeRef::default()),
Variants::Row(props) => VComp::new::<table_row::TableRow>(props, NodeRef::default()),
}
}
} Because I could not implement: impl Into<VChild<TableHead>> for Variant {
fn into(self) -> VChild<TableHead> {
match self.props {
Variants::Head(props) => VChild::<table_head::TableHead>::new(props, NodeRef::default()),
}
}
} The whole vdom is quite a mess and I could not figure out how to make it do what I was slowly actually headed towards. |
…ewstack#843) * Revert "Revert "Improve nested html! expansion by unwrapping VNodes (yewstack#820)" (yewstack#842)" This reverts commit 70862a4 * Add minor fix to VList to conform with yewstack#820 * Add unittest for the regression bug yewstack#839 * Resolve yewstack#839 regression issue introduced by yewstack#820 * wip * Revert "Resolve yewstack#839 regression issue introduced by yewstack#820" This reverts commit 34dc935. * Use explicit html_nested * Remove NodeSeq from prelude * Clean up tests * Add list and tag tests * Revert vtag children change Co-authored-by: Justin Starry <[email protected]>
Requirements: