Skip to content
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

Remove use of ChildrenRenderer from nested_list #3436

Merged
merged 2 commits into from
Oct 3, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
53 changes: 40 additions & 13 deletions examples/nested_list/src/app.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
use std::iter;

use yew::prelude::*;

use super::header::ListHeader;
Expand Down Expand Up @@ -48,23 +50,48 @@ impl Component for App {

// note the use of `html_nested!` instead of `html!`.
let letters = ('A'..='C')
.map(|letter| html_nested! { <ListItem name={letter.to_string()} {on_hover} /> });
.map(|letter| html_nested! { <ListItem key={format!("letter-{}", letter)} name={letter.to_string()} {on_hover} /> });

html! {
<div class="main" {onmouseover}>
<h1>{ "Nested List Demo" }</h1>
<List {on_hover} weak_link={list_link}>
<ListHeader text="Calling all Rusties!" {on_hover} {list_link} />
<ListItem name="Rustin" {on_hover} />
<ListItem hide=true name="Rustaroo" {on_hover} />
<ListItem name="Rustifer" {on_hover}>
<div class="sublist" onmouseover={onmouseoversublist}>{ "Sublist!" }</div>
<List {on_hover} weak_link={sub_list_link}>
<ListHeader text="Sub Rusties!" {on_hover} list_link={sub_list_link}/>
<ListItem hide=true name="Hidden Sub" {on_hover} />
{ for letters }
</List>
</ListItem>
<List
{on_hover}
weak_link={list_link}
header={
vec![
html_nested! {
<ListHeader text="Calling all Rusties!" {on_hover} {list_link} key="header" />
}
Comment on lines +62 to +65
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would move these vec!s out into variables but it's fine if you want to merge it as-is. It's just a stylistic thing to keep Rust code out of html! . 3 levels of nested macros doesn't look that either

]
}
>
{vec![
html_nested! { <ListItem key="rustin" name="Rustin" {on_hover} /> },
html_nested! { <ListItem key="rustaroo" hide=true name="Rustaroo" {on_hover} /> },
html_nested! {
<ListItem key="rustifer" name="Rustifer" {on_hover}>
<div class="sublist" onmouseover={onmouseoversublist}>{ "Sublist!" }</div>
<List
{on_hover}
weak_link={sub_list_link}
header={
vec![html_nested! {
<ListHeader key="sub-rusties" text="Sub Rusties!" {on_hover} list_link={sub_list_link}/>
}]
}
>
{
iter::once(html_nested! { <ListItem key="hidden-sub" hide=true name="Hidden Sub" {on_hover} /> })
.chain(letters)
.collect::<Vec<_>>()
}
</List>
</ListItem>
},
]}


</List>
{ self.view_last_hovered() }
</div>
Expand Down
79 changes: 16 additions & 63 deletions examples/nested_list/src/list.rs
Original file line number Diff line number Diff line change
@@ -1,64 +1,23 @@
use std::rc::Rc;

use yew::html::ChildrenRenderer;
use yew::prelude::*;
use yew::virtual_dom::{VChild, VComp};
use yew::virtual_dom::VChild;

use crate::header::{ListHeader, Props as HeaderProps};
use crate::item::{ListItem, Props as ItemProps};
use crate::header::ListHeader;
use crate::item::ListItem;
use crate::{Hovered, WeakComponentLink};

#[derive(Clone, PartialEq)]
pub enum Variants {
Item(Rc<<ListItem as Component>::Properties>),
Header(Rc<<ListHeader as Component>::Properties>),
}

impl From<ItemProps> for Variants {
fn from(props: ItemProps) -> Self {
Variants::Item(Rc::new(props))
}
}

impl From<HeaderProps> for Variants {
fn from(props: HeaderProps) -> Self {
Variants::Header(Rc::new(props))
}
}

#[derive(PartialEq, Clone)]
pub struct ListVariant {
props: Variants,
}

impl<CHILD> From<VChild<CHILD>> for ListVariant
where
CHILD: Component,
CHILD::Properties: Into<Variants> + Clone,
{
fn from(vchild: VChild<CHILD>) -> Self {
Self {
props: (*vchild.props).clone().into(),
}
}
}

impl From<ListVariant> for Html {
fn from(variant: ListVariant) -> Html {
match variant.props {
Variants::Header(props) => VComp::new::<ListHeader>(props, None).into(),
Variants::Item(props) => VComp::new::<ListItem>(props, None).into(),
}
}
}

pub enum Msg {
HeaderClick,
}

#[derive(Clone, PartialEq, Properties)]
pub struct Props {
pub children: ChildrenRenderer<ListVariant>,
#[prop_or_default]
pub header: Vec<VChild<ListHeader>>,
#[prop_or_default]
pub children: Vec<VChild<ListItem>>,

pub on_hover: Callback<Hovered>,
pub weak_link: WeakComponentLink<List>,
}
Expand Down Expand Up @@ -97,9 +56,9 @@ impl Component for List {
html! {
<div class="list-container" {onmouseover}>
<div class={classes!("list", inactive)}>
{ Self::view_header(&ctx.props().children) }
{ ctx.props().header.clone() }
<div class="items">
{ Self::view_items(&ctx.props().children) }
{ Self::view_items(ctx.props().children.clone()) }
</div>
</div>
</div>
Expand All @@ -108,21 +67,15 @@ impl Component for List {
}

impl List {
fn view_header(children: &ChildrenRenderer<ListVariant>) -> Html {
html! { for children.iter().filter(|c| matches!(c.props, Variants::Header(_))) }
}

fn view_items(children: &ChildrenRenderer<ListVariant>) -> Html {
fn view_items(children: Vec<VChild<ListItem>>) -> Html {
children
.iter()
.filter(|c| matches!(&c.props, Variants::Item(props) if !props.hide))
.into_iter()
.filter(|c| !c.props.hide)
.enumerate()
.map(|(i, mut c)| {
if let Variants::Item(props) = c.props {
let mut props = (*props).clone();
props.name = format!("#{} - {}", i + 1, props.name);
c.props = Variants::Item(Rc::new(props));
}
let mut props = (*c.props).clone();
props.name = format!("#{} - {}", i + 1, props.name);
c.props = Rc::new(props);
c
})
.collect::<Html>()
Expand Down
Loading