Generic components in Yew

Hi, I was wondering if it was possible in Yew to render components with generic type parameters.

I am imagining something like:

#[derive(Properties, Clone, Debug)]
pub struct TreeData<P: Properties> {
    pub element: P,
    pub expanded: bool,
    pub children: Vec<TreeData<P>>
}

pub struct TreeView<C: Component> {
    props: TreeData<<C as Component>::Properties>,
    link: ComponentLink<Self>,
}

impl<C: Component> Component for TreeView<C> {
    type Message = Msg;
    type Properties = TreeData<<C as Component>::Properties>;

    ...

    fn view(&self) -> Html {
        html!{
            <div class="tree-node" style="margin-left: 20px" >
                    <C // generic component
                        {self.props.element} // create with generic properties
                    />
                </div>
                {
                    if self.props.expanded {
                        html!{
                            <div>{
                                for self.props.children.iter().cloned().enumerate().map(|(i,child)| html!{
                                    <TreeView<C> // also generic
                                        element={child.element}
                                        children={child.children}
                                        expanded={child.expanded}
                                        message_parent={Some(self.child_messenger(i))}
                                    />
                                })
                            }</div>
                        }
                    } else {
                        html!{}
                    }
                }
            </div>
        }
    }

    ...

}

Would something like this already possible or would this need to be implemented first?

1 Like

There was an issue in the html! macro which prevented generic type arguments to be used in component elements. It was fixed in Yew 0.14.3

The issue was that the macro tried to implement a trait for the component type (to provide better error messages), and if that used a generic type argument, the impl was required to declare that, as usual:
impl<T> Component for TreeView<T>
However the html! can not know about the trait bounds for the generic type argument in

impl<T: Component> Component for TreeView<T> {
    ...
    html!{
        <TreeView<T> />
        // this is all the macro sees, so it can not declare T with trait bounds
    }
    ...
}

So we simply removed the impl Component in the macro and deal with the worse error message now, but if anyone knows how to get the trait bounds for a generic type in a proc macro I would be very grateful.