Skip to content

Instantly share code, notes, and snippets.

@boriscy
Last active May 11, 2021 21:06
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save boriscy/c962b358d649931d06c8ca153314f6c8 to your computer and use it in GitHub Desktop.
Save boriscy/c962b358d649931d06c8ca153314f6c8 to your computer and use it in GitHub Desktop.
<script lang="ts">
import { createEventDispatcher } from "svelte"
import { fade, fly } from "svelte/transition"
import Fa from "svelte-fa"
import { faTimes } from "@fortawesome/free-solid-svg-icons"
let open = false
export let closeButton = true
export let closeOnEsc = true
export let closeOnOuterClick = true
export let large = false
let background
let wrap
let modalWindow
const dispatch = createEventDispatcher()
function openModal() {
open = true
}
function closeModal() {
dispatch("close")
open = false
}
const handleKeyup = ({ key }) => {
if (closeOnEsc && key === "Escape") {
closeModal()
}
}
function handleOuterClick(_evt): void {
if (closeOnOuterClick) {
closeModal()
}
}
</script>
<svelte:window on:keyup|preventDefault={handleKeyup} />
{#if open}
<div
class="fixed z-10 inset-0 overflow-y-auto"
on:click|preventDefault={handleOuterClick}
bind:this={background}
transition:fade
>
<div
class="flex items-end justify-center min-h-screen pt-4 px-4 pb-20 text-center sm:block sm:p-0"
>
<div class="fixed inset-0 transition-opacity" aria-hidden="true">
<div class="absolute inset-0 bg-gray-500 opacity-75" bind:this={wrap} />
</div>
<!-- This element is to trick the browser into centering the modal contents. -->
<span class="hidden sm:inline-block sm:align-middle sm:h-screen" aria-hidden="true"
>&#8203;</span
>
<div
class="{large
? 'lg:max-w-5xl md:max-w-3xl max-w-2xl'
: 'lg:max-w-3xl sm:max-w-sm sm:max-w-sm'}
inline-block align-bottom bg-white rounded-lg px-4 pt-5 pb-4 text-left overflow-hidden shadow-xl transform transition-all sm:my-8 sm:align-middle sm:w-full sm:p-6"
role="dialog"
aria-modal="true"
aria-labelledby="modal-headline"
bind:this={modalWindow}
transition:fly={{ y: 300 }}
>
{#if closeButton}
<div class="hidden sm:block absolute top-0 right-0 pt-4 pr-4">
<button
type="button"
on:click={closeModal}
class="bg-white rounded-md text-gray-400 hover:text-gray-500 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500"
>
<span class="sr-only">Close</span>
<Fa icon={faTimes} class="w-6 h-6" />
</button>
</div>
{/if}
<div class="sm:flex sm:items-start" />
<slot />
</div>
</div>
</div>
{/if}
<script>
import Modal from "./Modal.svelte"
// You can use
// modal.openModal(). modal.closeModal()
let modal
<script>
<Modal bind:this={modal}>
My content
</Modal>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment