Add method map() on Children to wrap easily (#3039)

This commit is contained in:
Cecile Tonglet 2023-01-05 11:30:05 +01:00 committed by GitHub
parent e65ee60599
commit d4c2f03c3d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 48 additions and 2 deletions

View File

@ -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<T: PartialEq> PartialEq for ChildrenRenderer<T> {
impl<T> ChildrenRenderer<T>
where
T: Clone + Into<VNode>,
T: Clone,
{
/// Create children
pub fn new(children: Vec<T>) -> 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! {
/// <div class={classes!("container")}>
/// {children}
/// </div>
/// }
/// })
/// # ;
/// ```
pub fn map<OUT: Default>(&self, closure: impl FnOnce(&Self) -> OUT) -> OUT {
if self.is_empty() {
Default::default()
} else {
closure(self)
}
}
}
impl<T> Default for ChildrenRenderer<T> {
@ -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());
}
}

View File

@ -50,6 +50,15 @@ impl<IN: Into<OUT>, OUT> From<ChildrenRenderer<IN>> for NodeSeq<IN, OUT> {
}
}
impl<IN: Into<OUT> + Clone, OUT> From<&ChildrenRenderer<IN>> for NodeSeq<IN, OUT> {
fn from(val: &ChildrenRenderer<IN>) -> Self {
Self(
val.iter().map(|x| x.into()).collect(),
PhantomData::default(),
)
}
}
impl<IN, OUT> IntoIterator for NodeSeq<IN, OUT> {
type IntoIter = std::vec::IntoIter<Self::Item>;
type Item = OUT;