Skip to content

Commit 528b560

Browse files
cectonWorldSEnder
authored andcommitted
Add method map() on Children to wrap easily (yewstack#3039)
1 parent 5a49bc4 commit 528b560

File tree

2 files changed

+48
-2
lines changed

2 files changed

+48
-2
lines changed

packages/yew/src/html/component/children.rs

Lines changed: 39 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
use std::fmt;
44

55
use crate::html::Html;
6-
use crate::virtual_dom::{VChild, VNode};
6+
use crate::virtual_dom::VChild;
77
use crate::Properties;
88

99
/// A type used for accepting children elements in Component::Properties.
@@ -163,7 +163,7 @@ impl<T: PartialEq> PartialEq for ChildrenRenderer<T> {
163163

164164
impl<T> ChildrenRenderer<T>
165165
where
166-
T: Clone + Into<VNode>,
166+
T: Clone,
167167
{
168168
/// Create children
169169
pub fn new(children: Vec<T>) -> Self {
@@ -186,6 +186,28 @@ where
186186
// This way `self.iter().next()` only has to clone a single node.
187187
self.children.iter().cloned()
188188
}
189+
190+
/// Convert the children elements to another object (if there are any).
191+
///
192+
/// ```
193+
/// # let children = Children::new(Vec::new());
194+
/// # use yew::{classes, html, Children};
195+
/// children.map(|children| {
196+
/// html! {
197+
/// <div class={classes!("container")}>
198+
/// {children}
199+
/// </div>
200+
/// }
201+
/// })
202+
/// # ;
203+
/// ```
204+
pub fn map<OUT: Default>(&self, closure: impl FnOnce(&Self) -> OUT) -> OUT {
205+
if self.is_empty() {
206+
Default::default()
207+
} else {
208+
closure(self)
209+
}
210+
}
189211
}
190212

191213
impl<T> Default for ChildrenRenderer<T> {
@@ -218,3 +240,18 @@ pub struct ChildrenProps {
218240
#[prop_or_default]
219241
pub children: Children,
220242
}
243+
244+
#[cfg(test)]
245+
mod tests {
246+
use super::*;
247+
248+
#[test]
249+
fn children_map() {
250+
let children = Children::new(vec![]);
251+
let res = children.map(|children| Some(children.clone()));
252+
assert!(res.is_none());
253+
let children = Children::new(vec![Default::default()]);
254+
let res = children.map(|children| Some(children.clone()));
255+
assert!(res.is_some());
256+
}
257+
}

packages/yew/src/utils/mod.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,15 @@ impl<IN: Into<OUT>, OUT> From<ChildrenRenderer<IN>> for NodeSeq<IN, OUT> {
5050
}
5151
}
5252

53+
impl<IN: Into<OUT> + Clone, OUT> From<&ChildrenRenderer<IN>> for NodeSeq<IN, OUT> {
54+
fn from(val: &ChildrenRenderer<IN>) -> Self {
55+
Self(
56+
val.iter().map(|x| x.into()).collect(),
57+
PhantomData::default(),
58+
)
59+
}
60+
}
61+
5362
impl<IN, OUT> IntoIterator for NodeSeq<IN, OUT> {
5463
type IntoIter = std::vec::IntoIter<Self::Item>;
5564
type Item = OUT;

0 commit comments

Comments
 (0)