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

HtmlElement::attrs and DynAttrs::dyn_attrs Accept &'static str Instead of Oco<'static, str> #2594

Open
Defernus opened this issue May 16, 2024 · 2 comments
Milestone

Comments

@Defernus
Copy link

Describe the bug
The leptos_dom::html::HtmlElement::attrs method does not accept Vec<(Oco<'static, str>, Attribute)>.

However, it will accept Vec<(&'static str, Attribute)> and will convert name to Oco<'static, str> in the HtmlElement::attr method.

The same issue occurs with leptos::DynAttrs::dyn_attrs, which will only accept Vec<(&'static str, Attribute)>.

Leptos Dependencies

leptos = { version = "0.6", features = ["csr", "nightly"] }

To Reproduce

use leptos::*;

#[component]
pub fn MyComponent(
    #[prop(attrs, optional)] attrs: Vec<(Oco<'static, str>, Attribute)>,
) -> impl IntoView {
    html::span().attrs(attrs)
}

Expected behavior

The method should accept Vec<(Oco<'static, str>, Attribute)> as a type for dynamic attributes.

Additional context

I am working on Storybook integration for Leptos and parsing props for components from JsValue. Currently, it is impossible to use regular arguments, so I have to do something like this:

use leptos::*;
use wasm_bindgen::prelude::*;

// we have to create wrapper type for attributes
#[derive(Default)]
pub struct AttributeSpread(pub Vec<(Oco<'static, str>, Attribute)>);

impl From<Vec<(&'static str, leptos::Attribute)>> for AttributeSpread {
    fn from(value: Vec<(&'static str, leptos::Attribute)>) -> Self {
        Self(
            value
                .into_iter()
                .map(|(name, value)| (Oco::Borrowed(name), value))
                .collect(),
        )
    }
}

#[component]
pub fn MyComponent(#[prop(attrs, optional)] attrs: AttributeSpread) -> impl IntoView {
    let mut span = html::span();

    // have to add each attr manually
    for (name, value) in attrs.0 {
        span = span.attr(name, value);
    }

    span
}
@gbj gbj added this to the 0.7 milestone May 16, 2024
@gbj
Copy link
Collaborator

gbj commented May 16, 2024

I don't think it's possible to change these function signatures in a way that isn't technically a breaking change, although I may be wrong. I do know that they will change significantly in the next release as part of the wider renderer rewrite, so I will mark this issue as 0.7 to make sure there's a decent solution then.

0.7 does support spreading arbitrary attributes of any kind onto any component, which seems to me like it should help.

@Defernus
Copy link
Author

Also, I don't see any reason why the Binding::Attribute name is &'static str instead of Oco<'static, str>. Because of this, I can't do the following:

use leptos::*;

#[component]
pub fn MyComponent(
    #[prop(attrs, optional)] attrs: Vec<(Oco<'static, str>, Attribute)>,
) -> impl IntoView {
    view! { <span {..attrs}></span> }
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants