Modal.svelte 1.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485
  1. <script lang="ts">
  2. import { onMount } from 'svelte';
  3. import { fade } from 'svelte/transition';
  4. import { flyAndScale } from '$lib/utils/transitions';
  5. export let show = true;
  6. export let size = 'md';
  7. let modalElement = null;
  8. let mounted = false;
  9. const sizeToWidth = (size) => {
  10. if (size === 'xs') {
  11. return 'w-[16rem]';
  12. } else if (size === 'sm') {
  13. return 'w-[30rem]';
  14. } else {
  15. return 'w-[44rem]';
  16. }
  17. };
  18. const handleKeyDown = (event: KeyboardEvent) => {
  19. if (event.key === 'Escape') {
  20. console.log('Escape');
  21. show = false;
  22. }
  23. };
  24. onMount(() => {
  25. mounted = true;
  26. });
  27. $: if (mounted) {
  28. if (show) {
  29. window.addEventListener('keydown', handleKeyDown);
  30. document.body.style.overflow = 'hidden';
  31. } else {
  32. window.removeEventListener('keydown', handleKeyDown);
  33. document.body.style.overflow = 'unset';
  34. }
  35. }
  36. </script>
  37. {#if show}
  38. <!-- svelte-ignore a11y-click-events-have-key-events -->
  39. <!-- svelte-ignore a11y-no-static-element-interactions -->
  40. <div
  41. bind:this={modalElement}
  42. class=" fixed top-0 right-0 left-0 bottom-0 bg-black/60 w-full min-h-screen h-screen flex justify-center z-50 overflow-hidden overscroll-contain"
  43. in:fade={{ duration: 10 }}
  44. on:click={() => {
  45. show = false;
  46. }}
  47. >
  48. <div
  49. class=" m-auto rounded-2xl max-w-full {sizeToWidth(
  50. size
  51. )} mx-2 bg-gray-50 dark:bg-gray-900 shadow-3xl"
  52. in:flyAndScale
  53. on:click={(e) => {
  54. e.stopPropagation();
  55. }}
  56. >
  57. <slot />
  58. </div>
  59. </div>
  60. {/if}
  61. <style>
  62. .modal-content {
  63. animation: scaleUp 0.1s ease-out forwards;
  64. }
  65. @keyframes scaleUp {
  66. from {
  67. transform: scale(0.985);
  68. opacity: 0;
  69. }
  70. to {
  71. transform: scale(1);
  72. opacity: 1;
  73. }
  74. }
  75. </style>