|
7 | 7 | import IconButton from "./Menu/IconButton.svelte"; |
8 | 8 |
|
9 | 9 | export let title: string; |
| 10 | + export let position: "left" | "center" = "center"; |
10 | 11 |
|
11 | 12 | const id = `modal-${randomString()}`; |
12 | 13 | const titleId = `${id}-title`; |
13 | 14 |
|
| 15 | + let open = false; |
14 | 16 | onMount(() => { |
15 | 17 | const trap = focusTrap.createFocusTrap(`#${id}`, { |
16 | 18 | clickOutsideDeactivates: true, |
|
20 | 22 | const bodyOverflow = document.body.style.overflow; |
21 | 23 | document.body.style.overflow = "hidden"; |
22 | 24 |
|
| 25 | + setTimeout(() => { |
| 26 | + open = true; |
| 27 | + }, 0); |
| 28 | +
|
23 | 29 | return () => { |
24 | 30 | trap.deactivate(); |
25 | 31 | document.body.style.overflow = bodyOverflow; |
|
28 | 34 |
|
29 | 35 | const dispatch = createEventDispatcher(); |
30 | 36 | const onClose = () => { |
31 | | - dispatch("close"); |
| 37 | + open = false; |
| 38 | + setTimeout(() => dispatch("close"), 125); |
32 | 39 | }; |
33 | 40 | </script> |
34 | 41 |
|
35 | | -<div class="backdrop" /> |
36 | | -<div class="modal" role="dialog" aria-labelledby={titleId} {id}> |
| 42 | +<div class="backdrop" class:open /> |
| 43 | +<div |
| 44 | + class="modal {position}" |
| 45 | + class:open |
| 46 | + role="dialog" |
| 47 | + aria-labelledby={titleId} |
| 48 | + {id} |
| 49 | +> |
37 | 50 | <div class="header"> |
38 | 51 | <h2 id={titleId}>{title}</h2> |
39 | 52 | <IconButton icon="Close" label="Close" onClick={onClose} /> |
|
45 | 58 |
|
46 | 59 | <style lang="sass"> |
47 | 60 | .backdrop |
48 | | - animation: blur-background 125ms forwards |
49 | 61 | position: fixed |
50 | 62 | top: 0 |
51 | 63 | left: 0 |
|
55 | 67 |
|
56 | 68 | z-index: 4 |
57 | 69 |
|
58 | | - @keyframes blur-background |
59 | | - from |
60 | | - backdrop-filter: none |
| 70 | + backdrop-filter: none |
| 71 | + transition: backdrop-filter 125ms |
61 | 72 |
|
62 | | - to |
63 | | - backdrop-filter: blur(4px) |
| 73 | + &.open |
| 74 | + backdrop-filter: blur(4px) |
64 | 75 |
|
65 | 76 | .modal |
66 | | - animation: open-modal 125ms forwards |
67 | 77 | display: flex |
68 | 78 | flex-direction: column |
69 | 79 |
|
70 | 80 | position: fixed |
71 | | - top: 50% |
72 | | - left: 50% |
73 | 81 |
|
74 | | - background: white |
75 | | - z-index: 4 |
| 82 | + &.center |
| 83 | + top: 50% |
| 84 | + left: 50% |
76 | 85 |
|
77 | | - font-size: 1rem |
78 | | - padding: 0 1em 2em |
79 | | - overflow: hidden |
| 86 | + max-height: 90% |
| 87 | + width: 500px |
| 88 | + max-width: 100% |
80 | 89 |
|
81 | | - box-sizing: border-box |
82 | | - max-height: 90% |
83 | | - width: 500px |
84 | | - max-width: 100% |
| 90 | + padding: 0 1em 2em |
85 | 91 |
|
86 | | - box-shadow: 0 0.5rem 1rem rgba(0, 0, 0, 0.75) |
| 92 | + box-shadow: 0 0.5rem 1rem rgba(0, 0, 0, 0.75) |
87 | 93 |
|
88 | | - @keyframes open-modal |
89 | | - from |
90 | | - opacity: 0 |
91 | | - transform: translate(-50%, -25%) scale(0.25) |
| 94 | + opacity: 0 |
| 95 | + transform: translate(-50%, -25%) scale(0.25) |
| 96 | + transition: opacity 125ms, transform 125ms |
92 | 97 |
|
93 | | - to |
| 98 | + &.open |
94 | 99 | opacity: 1 |
95 | 100 | transform: translate(-50%, -50%) scale(1) |
96 | 101 |
|
97 | | - @media (min-width: 501px) |
98 | | - border-radius: 0.25em |
| 102 | + @media (min-width: 501px) |
| 103 | + border-radius: 0.25em |
| 104 | +
|
| 105 | + &.left |
| 106 | + top: -2vh |
| 107 | + left: 0 |
| 108 | +
|
| 109 | + height: 104vh |
| 110 | + max-width: 95% |
| 111 | +
|
| 112 | + .content |
| 113 | + flex: 1 |
| 114 | +
|
| 115 | + padding: 2vh 1em |
| 116 | +
|
| 117 | + box-shadow: 0.5rem 0 1rem rgba(0, 0, 0, 0.75) |
| 118 | +
|
| 119 | + opacity: 0 |
| 120 | + transform: translateX(-50%) |
| 121 | + transition: opacity 125ms, transform 125ms |
| 122 | +
|
| 123 | + &.open |
| 124 | + opacity: 1 |
| 125 | + transform: translateX(0) |
| 126 | +
|
| 127 | + background: white |
| 128 | + z-index: 4 |
| 129 | +
|
| 130 | + font-size: 1rem |
| 131 | + overflow: hidden |
| 132 | +
|
| 133 | + box-sizing: border-box |
99 | 134 |
|
100 | 135 | .header |
101 | 136 | display: flex |
|
0 commit comments