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 ?
You should not re-dispatch events, instead set no handler, e.g.:
<TextInput on:change on:input />