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

Allow spread attributes to be set directly #3881

Open
wants to merge 2 commits into
base: main
Choose a base branch
from

Conversation

ealmloff
Copy link
Member

@ealmloff ealmloff commented Mar 15, 2025

Currently, you cannot forward spread attributes through components like this:

#[derive(Props, Clone, PartialEq)]
struct Comp1Props {
    #[props(extends = GlobalAttributes)]
    attributes: Vec<Attribute>,
}

#[component]
fn Comp1(props: Comp1Props) -> Element {
    rsx! {
        Comp2 {
            height: "100%",
            ..props
        }
    }
}

#[derive(Props, Clone, PartialEq)]
struct CompProps2 {
    #[props(extends = GlobalAttributes)]
    attributes: Vec<Attribute>,
}

#[component]
fn Comp2(props: CompProps2) -> Element {
    let attributes = props.attributes;
    rsx! {
        div {
            ..attributes
        }
    }
}

That makes it difficult to build component libraries with many general nested components. This PR implements the simpler fix for spreading attributes through components which lets you set the extends prop directly:

#[derive(Props, Clone, PartialEq)]
struct Comp1Props {
    #[props(extends = GlobalAttributes)]
    attributes: Vec<Attribute>,
}

#[component]
fn Comp1(props: Comp1Props) -> Element {
    rsx! {
        Comp2 {
            attributes: props.attributes.clone(),
            height: "100%",
        }
    }
}

#[derive(Props, Clone, PartialEq)]
struct CompProps2 {
    #[props(extends = GlobalAttributes)]
    attributes: Vec<Attribute>,
}

#[component]
fn Comp2(props: CompProps2) -> Element {
    let attributes = props.attributes;
    rsx! {
        div {
            ..attributes
        }
    }
}

I do think we should look into developing a structural typing system for props, but that will probably not fit into this release. https://docs.rs/frunk/latest/frunk/labelled/trait.Transmogrifier.html looks close to what we would need, but it would require more integration

Fixes #3844

@ealmloff ealmloff added core relating to the core implementation of the virtualdom breaking This is a breaking change rsx Related to rsx or the dioxus-rsx crate labels Mar 15, 2025
@ealmloff ealmloff marked this pull request as ready for review March 20, 2025 13:31
@ealmloff ealmloff requested a review from a team as a code owner March 20, 2025 13:31
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
breaking This is a breaking change core relating to the core implementation of the virtualdom rsx Related to rsx or the dioxus-rsx crate
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Spread attributes through components
1 participant