I've been having trouble understanding the best way to create a reusable Modal component in Svelte. I want to have the Modal component where I can pass in other components easily, and in a scalable way. When I click the background, it should destroy the modal and the content inside.
I've created a REPL here with working version but would like to know if this is a convoluted way to achieve this: https://svelte.dev/repl/9180dd40e7304fc78d175cf4535a6423?version=3.38.2
This method works but I don't know if this is a suggested way (I'm new to both Svelte and component libraries).
App.js
<script>
import Modal from './Modal.svelte'
import Component1 from './Component1.svelte'
import Component2 from './Component2.svelte'
import {showModal} from './store.js'
let showC1, showC2 = false;
function toggleModal() {
$showModal = !$showModal;
}
function toggleC1() {
toggleModal();
showC1 = !showC1;
}
function toggleC2() {
toggleModal();
showC2 = !showC2;}
</script>
<button on:click={toggleC1}>
Toggle Component 1
</button>
<button on:click={toggleC2}>
Toggle Component 2
</button>
<Component1 {showC1} on:click={toggleC1} />
<Component2 {showC2} on:click={toggleC2} />
Modal.svelte
<script>
import {showModal} from './store.js'
</script>
{#if $showModal}
<div on:click|self class='modal'>
<div class='content'>
<slot />
</div>
</div>
{/if}
<style>
.modal {
background-color: rgba(0, 0, 0, 0.589);
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
opacity: 0.7;
display: flex;
justify-content: center;
align-items: center;
}
.content {
background-color: white;
width: 20em;
height: 20em;
}
</style>
Component1.svelte
<script>
import Modal from './Modal.svelte'
export let showC1;
</script>
{#if showC1}
<Modal on:click>
<div>
This is some content...
</div>
<button on:click>
close
</button>
</Modal>
{/if}
Component2.svelte
<script>
import Modal from './Modal.svelte'
export let showC2;
</script>
{#if showC2}
<Modal on:click>
<div>
...And some more content
</div>
<button on:click>
close
</button>
</Modal>
{/if}
store.js
import { writable } from "svelte/store";
export const showModal = writable(false);