Search code examples
javascriptevent-handlingsveltewrappersvelte-component

How to properly wrap a third party component in Svelte


I'm trying to wrap a third party svelte component, but I can't figure the proper and clean way to do this.

Context : I'm using a design system (carbon design system through carbon-components-svelte). I want to wrap their <TextInput> in a custom component with my own validation rules to use through my whole application.

Problem : I can't figure out how to forward all events from <TextInput> through my custom component.

https://github.com/sveltejs/svelte/issues/2837 talks about an on:* directive that would be nice but after some research, it seems like Svelte devs don't really like the idea.

https://github.com/hperrin/svelte-material-ui/blob/273ded17c978ece3dd87f32a58dd9839e5c61325/components/forwardEvents.js could be a solution but it uses svelte actions through use: directive but it not available on components, only on DOM elements.

So what is the correct way of doing this then ? Should I add my handlers one by one with on:possibleEvent={event => dispatch(event)} ? Thats seems really heavy, especially for a textInput, and not dynamic at all.

Code :

Here is my wrapper Component : sanitizedField.svelte

<script>
  import { TextInput } from 'carbon-components-svelte'
  import { createEventDispatcher } from "svelte";

  const dispatch = createEventDispatcher();

  export let value
  
  function thirdPartyForwarder(ev) {
    dispatch(ev.type, ev.detail)
  }

</script>

<TextInput {...$$props} bind:value 
on:event1={thirdPartyForwarder} 
on:event2={thirdPartyForwarder} // <==== this I would like to avoid
on:event3={thirdPartyForwarder} .../>

And How I use it : Page.svelte

<script>
    import SanitizedField from '$lib/components/sanitizedField/sanitizedField.svelte'
  
    let bindedValue
  
    function doSomething(ev) {
    //   ...do something
    }
  
  </script>
  
<SanitizedField bind:value={bindedValue} on:thirdPartyEvent1={doSomething} />

Isn't there a cleaner way to forward every event to parent in svelte ?


Solution

  • You should not re-dispatch events, instead set no handler, e.g.:

    <TextInput on:change on:input />