Generic Components

Components can be generic just the way you would expect.

extern crate natrix;
use natrix::prelude::*;

#[derive(Component)]
struct MyComponent<T>(T, T);

impl<T: Eq + 'static> Component for MyComponent<T> {
    fn render() -> impl Element<Self> {
        e::div()
            .text(|ctx: R<Self>| {
                if *ctx.0 == *ctx.1 {
                    "Equal"
                } else {
                    "Not Equal"
                }
            })
    }
}

Generic over Element/ToAttribute

If you want to be generic over something with a Element bound you will run into a recursion error in the type checker.

extern crate natrix;
use natrix::prelude::*;

#[derive(Component)]
struct MyComponent<T>(T);

impl<T: Element<Self> + Clone> Component for MyComponent<T> {
    fn render() -> impl Element<Self> {
        e::div()
            .child(|ctx: R<Self>| ctx.0.clone())
    }
}

fn main() {
    mount(MyComponent("Hello World".to_string()));
}

The problem here is that Element needs to be generic over the component, so Element<Self>, but its also enforces a Component bound on its generic, this means that in order to prove MyComponent<T> implements Component it must first prove MyComponent<T> implements Component, which rust doesnt like and errors out on. To solve this you can use the NonReactive wrapper which will allow you to use Element<()> as the generic bound. As the name implies this essentially means that part of the dom tree cant be reactive.

NonReactive is essentially a wrapper that swaps out the component instance its given with ().

extern crate natrix;
use natrix::prelude::*;
use natrix::component::NonReactive;

#[derive(Component)]
struct MyComponent<T>(T);

impl<T: Element<()> + Clone> Component for MyComponent<T> {
    fn render() -> impl Element<Self> {
        e::div()
            .child(|ctx: R<Self>| NonReactive(ctx.0.clone()))
    }
}

fn main() {
    mount(MyComponent("Hello World".to_string()));
}

NonReactive also implements ToAttribute so a similar trick can be used for it.