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

Spread Props for on:<event> directives #7625

Closed
ecoinomist opened this issue Jun 21, 2022 · 6 comments
Closed

Spread Props for on:<event> directives #7625

ecoinomist opened this issue Jun 21, 2022 · 6 comments

Comments

@ecoinomist
Copy link

ecoinomist commented Jun 21, 2022

Describe the problem

Currently it's possible to spread only non-event props, because on: and other directives, such as bind:, do not work inside a spread object.

Example REPL.

Use case: I'm converting an existing application from React that creates UI from JSON files to Svelte. Events, such as onChange, onClick are created dynamically at runtime and passed to components during their render lifecycle using spread props (for encapsulation/abstraction purposes due to recursive nature of the framework).

Describe the proposed solution

Enable spread props for all prop directives, including modifiers, so that this code would work:

<script>
  let props = {'on:click|once': (e) => {alert(e)}}
</script>
<div {...props}>Click Me</div>

Alternatives considered

Enable spread props for event bindings without directives

<script>
  let props = {'onClick': (e) => {alert(e)}}
</script>
<div {...props}>Click Me</div>

Importance

i cannot use svelte without it

@babichjacob
Copy link
Member

This is a duplicate of #5112. Keep up with that issue for updates.

@ecoinomist
Copy link
Author

ecoinomist commented Jun 21, 2022

In my use case, I cannot circumvent it with the use:action workaround because event handlers need to be passed down to Components, not native HTML elements. It was surprising to see this issue had been hanging for 2 years.

The ability to use:action on Components would solve it.

Hypothetical proposal:

  • use:action in Component applies action to all root nodes inside the Component by default
  • use:action|1 in Component applies to a specific root node index 1 with a modifier
  • ignore use:action If the Component is headless (no root node)

This pattern of spread events is so frequently encountered, that it may make sense to put it under $$eventProps, similar to $$restProps, and provide built-in svelte solution for it. Though not as intuitive as simply spreading a prop, but perhaps, something like this would do the trick:

<Component use:events={$$eventProps}/>

@trash-and-fire
Copy link

It is also impossible to pass down actions, binds and style directives. Actually there is no way to pass down any directives. It's not even possible to pass a className from a parent component to a child component.

svelte is unfortunately a poorly composable framework. It's hard to write common components like your own <Button> or your own <Link>. Nobody cares about it. This problem delays the development of any high-composable ui-kit library and goes against the DRY principle.

@ecoinomist
Copy link
Author

ecoinomist commented Jun 22, 2022

I agree, the lack of directives spread props, and the inability to pass down dynamic event handlers to child components in any other way is a deal breaker for serious projects.

Fortunately for my use case, I'm writing my own compiler on top of Svelte compiler, so there are hacks to work around it.

Other things considered, Svelte is such as pleasing disruptive change compared to what you have to do in other frameworks, like React. No more boilerplate reselect memoizers to setup, or manual state management edge cases to fix, especially animations, etc.

@flipkickmedia
Copy link

Some work has been done on this, in yet another duplicate thread for this. This PR does not pass all the tests but it does work (for me). Ive done some updates since so this might work for you. Ill get the newer version pushed once Ive got the tests passing.

#6876

@Rich-Harris
Copy link
Member

Closing as spreading events is supported in Svelte 5

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

No branches or pull requests

5 participants