diff --git a/packages/yew/src/html/component/children.rs b/packages/yew/src/html/component/children.rs index efd2149b6d9..911cd91fa92 100644 --- a/packages/yew/src/html/component/children.rs +++ b/packages/yew/src/html/component/children.rs @@ -3,7 +3,7 @@ use std::fmt; use crate::html::Html; -use crate::virtual_dom::{VChild, VNode}; +use crate::virtual_dom::VChild; use crate::Properties; /// A type used for accepting children elements in Component::Properties. @@ -163,7 +163,7 @@ impl PartialEq for ChildrenRenderer { impl ChildrenRenderer where - T: Clone + Into, + T: Clone, { /// Create children pub fn new(children: Vec) -> Self { @@ -186,6 +186,28 @@ where // This way `self.iter().next()` only has to clone a single node. self.children.iter().cloned() } + + /// Convert the children elements to another object (if there are any). + /// + /// ``` + /// # let children = Children::new(Vec::new()); + /// # use yew::{classes, html, Children}; + /// children.map(|children| { + /// html! { + ///
+ /// {children} + ///
+ /// } + /// }) + /// # ; + /// ``` + pub fn map(&self, closure: impl FnOnce(&Self) -> OUT) -> OUT { + if self.is_empty() { + Default::default() + } else { + closure(self) + } + } } impl Default for ChildrenRenderer { @@ -218,3 +240,18 @@ pub struct ChildrenProps { #[prop_or_default] pub children: Children, } + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn children_map() { + let children = Children::new(vec![]); + let res = children.map(|children| Some(children.clone())); + assert!(res.is_none()); + let children = Children::new(vec![Default::default()]); + let res = children.map(|children| Some(children.clone())); + assert!(res.is_some()); + } +} diff --git a/packages/yew/src/utils/mod.rs b/packages/yew/src/utils/mod.rs index 2091349ec11..56926bfb637 100644 --- a/packages/yew/src/utils/mod.rs +++ b/packages/yew/src/utils/mod.rs @@ -50,6 +50,15 @@ impl, OUT> From> for NodeSeq { } } +impl + Clone, OUT> From<&ChildrenRenderer> for NodeSeq { + fn from(val: &ChildrenRenderer) -> Self { + Self( + val.iter().map(|x| x.into()).collect(), + PhantomData::default(), + ) + } +} + impl IntoIterator for NodeSeq { type IntoIter = std::vec::IntoIter; type Item = OUT;