Reputation: 270
I have the popup modal in one of my app. I would like to close this popup while clicking outside of modal. I can achieve this behaviour using JavaScript but I can't quite find a way to make this work using Svelte framework. For now I'm achieving that behaviour like this
if (e.target.classList.contains('my-modal')){
e.target.style.display="none";
}
but I would like to have this worked using Svelte.
Upvotes: 8
Views: 7761
Reputation: 51
For anyone reading this in 2023 or later, the syntax has been updated to <svelte:window />
instead of <:window />
.
<svelte:window on:click='set({ message: "clicked outside the box" })' />
Upvotes: 3
Reputation: 334
Check out this repo for on:outclick
event:
https://github.com/babakfp/svelte-outclick
Upvotes: 2
Reputation: 3147
You just need to add the "onclick" handler on the root div:
<div class="modal" tabindex="-1" on:click={ () => send('CLOSE') }>
I use XState to send the 'CLOSE' event to the state machine, on another examples where people just use a flag variable you can do like this:
<script>
export let open = false;
export let onClosed;
const modalClose = () => {
open = false;
if (onClosed) {
onClosed();
}
}
</script>
{#if open}
<div class="modal" on:click={modalClose} >
...
I didn't have to add the stopPropagation
flag on the internal buttons as I think Svelte manage automatically, but just in case you need it, inside your modal on:click
logic you can add the flag: on:click|stopPropagation
<div class="modal-footer">
<button type="button" class="btn btn-secondary" on:click={modalClose}>
Close
</button>
<button type="button" class="btn btn-primary" on:click|stopPropagation={yourSaveLogic()}>
Save changes
</button>
</div>
Upvotes: 1
Reputation: 29605
A common way to solve this is to have a background element behind the modal that covers the screen and intercepts click events: https://svelte.technology/repl?version=1.57.1&example=modal-with-slot
This is also a good way to (for example) fade out the background to make the modal more visible.
Another approach is to use the special <:Window>
component to listen for clicks, and stop the propagation of any clicks that begin inside the modal: https://svelte.technology/repl?version=1.57.1&gist=ba5f8a78263f2cdfbc16b1ae8732da5d
<:Window on:click='set({ message: "clicked outside the box" })'/>
<div class='clickzone' on:click='event.stopPropagation()'>
<div class='inner' on:click='set({ message: "clicked inside the box" })'>
{{message}}
</div>
</div>
Upvotes: 15