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

feat: AttributeInterceptor component to allow passing attributes to other elements #3340

Merged
merged 4 commits into from
Dec 16, 2024

Conversation

paul-hansen
Copy link
Contributor

By default, Leptos passes any attributes passed to your component (e.g. <MyComponent attr:class="some-class"/>) to the top-level element in the view returned by your component. AttributeInterceptor allows you to intercept this behavior and pass it onto any element in your component instead.

Greg solved the trait bound so we can cloned into the child builder.
Also added docs with example.
@paul-hansen
Copy link
Contributor Author

Nits welcome! Tried to follow styles of the rest of the Leptos codebase where I noticed.

Thanks again to @gbj for helping figure this out! Feel welcome to change your mind if you don't want it as a component or anything.

It felt weird for this to be it's own top level module in Leptos (doesn't feel that important), but since the attr module is in tachys it couldn't go there and didn't see a better place. Happy to move it somewhere if desired.

@mscofield0
Copy link
Contributor

I wonder if it would be possible to have a sort of namespace before attributes that denote where they ought to go.

#[component]
fn Foo() -> impl IntoView {
  view! {
    <div {..main} >
      <div {..inner} />
    </div>
  }
}

<Foo main:on:click=move |_| handler() inner:id="epic"/>

@paul-hansen
Copy link
Contributor Author

paul-hansen commented Dec 10, 2024

I wonder if it would be possible to have a sort of namespace before attributes that denote where they ought to go.

#[component]
fn Foo() -> impl IntoView {
  view! {
    <div {..main} >
      <div {..inner} />
    </div>
  }
}

<Foo main:on:click=move |_| handler() inner:id="epic"/>

I do think I like that better from the perspective of a consumer of the library. Idk how annoying or problematic that might be to implement though.

Maybe use something like @inner:on:click so the "namespace" is easier to identify? And if no "namespace" it defaults to targeting the top-level element? Defaulting to top-level would allow all components to still automatically support attributes.

I don't think I'd have the time to attempt that for a month or two (trying to launch our site in Jan), but if this is something Leptos (pinging @gbj for opinion) wants to go for, I'd be happy to spin this PR into a temporary crate people can use for now.

@gbj
Copy link
Collaborator

gbj commented Dec 10, 2024

The beauty of this current implementation is that it includes no special rules or additional behavior at all — while it is very useful, it could also have been implemented in user space and doesn't require any "magic" from the framework.

Adding an additional syntax like main:on:click, on the other hand, would require some significant changes to the view macro, at the very least, and it's always important to be careful about this kind of proliferation of special syntax, as it's harder to document and discover.

I'd imagined a component like this and not gotten around to implementing it yet, so am happy to have this contribution as is. I'm also happy to have other discussions about other possible syntaxes in the future.

@paul-hansen
Copy link
Contributor Author

paul-hansen commented Dec 10, 2024

Since Greg still wants to merge the implementation in this PR, maybe we should spin your idea in to a separate issue/feature request if you want to get that started @mscofield0 ? I do think it could be a cool idea, if some things around it can be solved (like automatic documentation of "namespaces" provided by components) and the implementation required isn't too gnarly/hard to maintain.

@mscofield0
Copy link
Contributor

My main qualm with the current implementation is that it doesn't really support separating attributes. It's just one unified set of attributes that are passed to one or more components down the line. But this covers one aspect of what I personally need in my projects so I'm fine with this one too of course.

@gbj
Copy link
Collaborator

gbj commented Dec 16, 2024

My main qualm with the current implementation is that it doesn't really support separating attributes. It's just one unified set of attributes that are passed to one or more components down the line.

That's a fair point, but none of the attribute spreading APIs we currently have (or have had in the past?) support that, so it seems like a much bigger conversation than this PR.

@gbj gbj merged commit 0bb825f into leptos-rs:main Dec 16, 2024
74 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants