In this post, we will learn the basic concept of Svelte Event Forwarding along with a practical example.

A typical web application has several components where each component is doing its job. However, many times, it is important for one component to know about an event occurring in another component. This is where event forwarding comes into the picture.

With event forwarding, we can have an event occurring in one component handled by another component. For example, a user click in the child component being handled in the parent component.

Let us consider this with a real example.

1 – An Example Requirement

Consider that we have the below App component. This component is very simple. Apart from a hello message, it only has a Modal component. If you are interested to know more about components, do check out this detailed post on Svelte Nested Components.

<script>
	import Modal from './Modal.svelte'

	export let name;
</script>

<Modal/>
<main>
	<h1>Hello {name}!</h1>
</main>

<style>
	main {
		text-align: center;
		padding: 1em;
		max-width: 240px;
		margin: 0 auto;
	}

	h1 {
		color: #ff3e00;
		text-transform: uppercase;
		font-size: 4em;
		font-weight: 100;
	}

	@media (min-width: 640px) {
		main {
			max-width: none;
		}
	}
</style>

Below is the code for the Modal component. The Modal is shown when the variable showModal is true. Currently, its value is hard-coded to false.

<script>
    let showModal = false;
    let isInteresting = true;
</script>

{#if showModal}
    <div class="backdrop" class:interesting={isInteresting}>
        <div class="modal">
            <p>This is a boring modal!</p>
        </div>
    </div>
{/if}

<style>
    .backdrop {
        width:100%;
        height: 100%;
        position: fixed;
        background: rgba(0,0,0,0.6)
    }

    .modal {
        padding: 10px;
        border-radius: 10px;
        max-width: 400px;
        margin: 10% auto;
        text-align: center;
        background: white;
    }

    .interesting .modal {
        background: crimson;
    }

    .interesting p {
        color: white
    }
</style>

Our requirement is to show the Modal when the user clicks a button.

2 – Toggling the Modal

In order to control the showing of the Modal, we will make the showModal variable as a prop to the Modal component.

<script>
    export let showModal;
    let isInteresting = true;
</script>

{#if showModal}
    <div class="backdrop" class:interesting={isInteresting}>
        <div class="modal">
            <p>This is a boring modal!</p>
        </div>
    </div>
{/if}

In the App component, we pass the showModal variable as a prop. Also, we introduce a button with an on:click event handler.

<script>
	import Modal from './Modal.svelte'

	export let name;

	let showModal = false;

	const toggleModal = () => {
	  showModal = !showModal;
	}
</script>

<Modal showModal={showModal}>
<main>
	<h1>Hello {name}!</h1>
	<button on:click={toggleModal}>Show Modal</button>
</main>

When the user clicks the button, the toggleModal() function flips the value of the showModal variable. The showModal variable is available to the Modal component as a prop.

This change basically solves our requirement of showing the Modal when the click happens.

svelte event forwarding

However, once the Modal opens up, there is no way to close it again because the button is inaccessible.

condition styling svelte

In other words, we need a way to call the toggleModal() function from within the Modal component.

3 – Event Forwarding in Svelte

To enable event forwarding, we first need to make the below changes to the Modal component.

<script>
    export let showModal;
    let isInteresting = true;
</script>

{#if showModal}
    <div class="backdrop" class:interesting={isInteresting} on:click|self>
        <div class="modal">
            <p>This is a boring modal!</p>
        </div>
    </div>
{/if}

Basically, we add the on:click directive to the backdrop <div>. However, there is no handler function. This is because a child component cannot directly access the toggleModal() function from the parent. However, when we don’t specify a handler, the event is automatically forwarded to the parent component.

The modifier self next to the on:click specifies that the click is only applicable for the backdrop <div>. This ensures that the click event does not register when the user clicks within the boundary of the modal. Only when the user clicks outside the modal box, the click event is fired.

Now, we need to handle the click event in the App component.

<script>
	import Modal from './Modal.svelte'

	export let name;

	let showModal = false;

	const toggleModal = () => {
		showModal = !showModal;
	}
</script>

<Modal showModal={showModal} on:click={toggleModal}/>
<main>
	<h1>Hello {name}!</h1>
	<button on:click={toggleModal}>Show Modal</button>
</main>

Basically, here we add the on:click handler to trigger the toggleModal() function. This will catch any events coming up from the child component and deal with it appropriately. In other words, we are now supporting event forwarding.

Conclusion

With this, we successfully explored the basic concept of Svelte Event Forwarding.

If you have any comments or queries about this post, please feel free to mention in the comments section below.

Categories: Svelte

0 Comments

Leave a Reply

Avatar placeholder

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