Is your feature request related to a problem? Please describe.
At the moment, there is no way to manage component events for a dynamic component, with spread props. Let consider this example:
<script>
const props = {
'label': 'Click me'
'on:action': () => {}
}
</script>
<svelte:component this={Comp} {...props} />
on:action will not be called.
Describe the solution you'd like
To have the code above working ๐
Describe alternatives you've considered
The workaround is to consider callbacks instead of events, like this :
<script>
const props = {
'label': 'Click me'
'onAction': () => {}
}
</script>
<svelte:component this={Comp} {...props} />
But then the code in Comp must be different compared to a normal dispatch usage.
How important is this feature to you?
It's just annoying because the workaround works pretty well, but maybe it can be a useful feature to keep consistency with the spread props.
In cases like this I fire a single known event name such as event and then use the event's detail to hold the inner event name and properties.
I'm pretty sure what you're suggesting isn't possible, since the expectation would be that events could be computed at runtime and appended to components, but I'm not 100% sure of that.
Thanks for your answer @antony, and sorry for the late answer here !
Using a generic event is another way to do it, indeed. I didn't think about this solution.
So it's definitely not a blocking issue, but sure, if there is way to standardize the way dynamic components are used (compared to a static one), it would be a plus.
The on:myevent set as a prop seems the more natural way to do it, and it was my first try without reading the documentation, before defaulting to a workaround.
This would be really useful to allow reusing behavior between multiple components, similar to React Hooks. For example, I'd like to try to port React Aria to Svelte. These hooks return DOM props that should be spread onto an element to provide some behavior. Part of the functionality that is returned are event handlers. I'd like to avoid needing to manually copy the events over one by one so the hook implementation details are hidden.
<button {...$buttonProps} on:pointerdown={$buttonProps.onPointerDown} on:pointerup={$buttonProps.onPointerUp}>
Clicked {count} {count === 1 ? 'time' : 'times'}
</button>
Is there a good way to do this given the compiler won't know at build time what events are needed? Should I make a wrapper that does addEventListener myself with a bind:this? Would be nice if Svelte could handle dynamic events though.
I think you could probably use an action and pass in the buttonProps there,then manually add event listeners for each of the handlers.
@devongovett I believe use: is something you are looking for
Ooh nice. Thanks for the super quick responses. Heading to sleep now but will try in the morning! ๐
@devongovett Here is a use action example:
Update: it worked! ๐ https://github.com/devongovett/svelte-hooks
I was so excited to see that there was a decent workaround for this missing feature (using an action like use:applyEvents={eventProps})... but then when I tried to use this action to attach some event handler props on my _component_, I discovered I actually _can't_ :disappointed: :
Actions can only be applied to DOM elements, not components
Does anyone know why actions (i.e., Svelte's closest equivalent to react hooks, which is the background where I'm coming from) _can't_ be applied to components? Okay, I mean, I understand that it would have to work a _little_ bit differently because we don't necessarily have a single root element (though #5218 could provide a way to mark which element(s) are considered the root), but I wish the node argument of an action could be polymorphic so you could easily apply some reusable pattern/concern/behavior/action to a component too (more thoughts in https://github.com/sveltejs/svelte/issues/5218#issuecomment-698731991...).
And, does anyone have a good generic reusable solution for how to attach a bunch of event handlers (defined in an object in your component) to a child _component_ used inside of your component?
Needless to say, I would like to see this feature implemented, so that we could just spread ("pass through") an object containing on: keys and have them automatically attached as event handlers โ instead of having passed through as regular ("inert") props/attributes โ which is probably _never_ what you actually want to happen, so it's surprising when that's what actually happens instead.
Since that current behavior is surprising/useless, could that be an argument in favor of making on: keys in a spread object semantically equivalent to explicitly listing out/hard-coding each of those like <component on:something={handleSomething} on:else={handleElse}>.
Of course I know nothing about how hard this would be to implement; I'm speaking only in the context of developer experience as a Svelte user... But the fact that it's pretty easy to implement in a generic/reusable way for _elements_ means I am at least hopeful that it could be easy to make something like this available for components too... :crossed_fingers:
Most helpful comment
@devongovett Here is a use action example: