Skip to content

Feature Request: Implement way to spread event handlers, only currently supported for traditional props #7548

@brandonmcconnell

Description

@brandonmcconnell

Describe the problem

On several occasions, I've found myself taking in the props for an array of components in an array of objects and then building out the component instances by iterating over the array using an {#each} block.

Each object in the array will have a unique event that should fire on:click.

It would be great if there were a way to naturally spread event handlers onto functions as well.

Describe the proposed solution

I propose adding a new convention when spreading props where Svelte will accept event handlers by their natural HTML name and convert them to their on: directive counterparts.

For example:

<script>
  import MyComponent from './MyComponent.svelte';
  let data = [
    {
      id: 184638,
      postCount: 17,
      $$on_click: () => console.log('Hello world'),
      $$transition_fade: true,
    },
    {
      id: 473892,
      postCount: 4,
      $$on_click: doSomething,
      $$transition_fade: {
        y: 200,
        duration: 2000,
      },
    },
  ];
</script>

{#each data as child}
  <MyComponent
    {...child}
  />
{/each}

This would automatically spread the onclick handlers onto the components'/elements' on:click directive. This is my proposal, but I'd be interested in any naming or syntax that would make spreading event handlers in this way possible. It could be something more inline with the other magic Svelte $$ naming conventions, like the examples mentioned above, or just use strings (less preferable to me, like this):

{
  id: 184638,
  postCount: 17,
  'on:click': () => console.log('Hello world'),
}

Alternatives considered

Currently, to work around this, I am spreading the other non-event-handler props into a separate variable using a {@const} block in an intermediary wrapper component, like this:

<script>
  import MyComponent from './MyComponent.svelte';
  let data = [
    {
      id: 184638,
      postCount: 17,
      $$on_click: () => console.log('Hello world'),
    },
    {
      id: 473892,
      postCount: 4,
      $$on_click: doSomething,
    },
  ];
</script>

{#each data as child}
  {@const { $$on_click, ...props }}
  <MyComponent
    {...props}
    on:click={$$on_click}
  />
{/each}

While I do value the explicit nature of this method, it does often require creating an intermediary wrapper component as the component(s) I'm feeding into often forward the on:click directive and do not expect an onclick prop.

Importance

would make my life easier

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions