Svelte: How to pass action to component?

There is a similar question asked here but I do not believe the answer applies to my use case.

I’m using Svelte MaterialUI and attempting to extend the DataTable component with the ability to drag and drop rows. I’m using the svelte-dnd-action module to support the drag and drop behaviors.

The following works just fine. I’m able to drag and drop rows of the table.

<table>
  <thead>...</thead>
  <tbody use:dndzone{...opts}>
     ...data
  <tbody>
</table>

However, when attempting to plug the module into a Material UI Component, I receive an error stating “actions can only be applied to DOM elements, not components.”

<DataTable>
  <Head>...</Head>
  <Body use:dndzone={...opts}>
    ...Data
  </Body>
</DataTable>

The definition of the Body component looks like this:

<tbody
  use:useActions={use}
  use:forwardEvents
  class="mdc-data-table__content {className}"
  {...exclude($$props, ['use', 'class'])}
><slot></slot></tbody>

<script>
  import {setContext} from 'svelte';
  import {get_current_component} from 'svelte/internal';
  import {forwardEventsBuilder} from '@smui/common/forwardEvents.js';
  import {exclude} from '@smui/common/exclude.js';
  import {useActions} from '@smui/common/useActions.js';
  const forwardEvents = forwardEventsBuilder(get_current_component());
  export let use = [];
  let className = '';
  export {className as class};
  setContext('SMUI:data-table:row:header', false);
</script>

Is there a way to forward my Action to this component? Or a better way to handle this use case? Thank you in advance.

Answer

The general answer is that you cannot pass actions to a component. That is, unless the component has this exposed for you.

Luckily the library you mention has it, as is written in their documentation:

You can add actions to the components with use={[Action1, [Action2, action2Props], Action3]}.

So in your case the code I believe would be

<Body use={[[dndzone, opts]]}>

Leave a Reply

Your email address will not be published. Required fields are marked *