-
Notifications
You must be signed in to change notification settings - Fork 44
/
Copy pathNotice.svelte
118 lines (93 loc) · 2.13 KB
/
Notice.svelte
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
<script context="module">
const allowedProps = ['active', 'position', 'duration'];
export function filterProps(props) {
const newProps = {}
Object.keys(props).forEach(key => {
if (allowedProps.includes(key)) newProps[key] = props[key]
})
return newProps
}
</script>
<script>
import { createEventDispatcher, onDestroy, onMount, tick } from 'svelte'
import { fly, fade } from 'svelte/transition'
import Notices, { notices } from './Notices.svelte'
const dispatch = createEventDispatcher()
export let active = true
export let position = 'is-top'
export let duration = 2000
export let transitionOut = true
let el
let parent
let timer
$: transitionY = ~position.indexOf('is-top') ? -200 : 200
export function close() {
active = false
}
function remove() {
clearTimeout(timer)
// Just making sure
active = false
dispatch('destroyed')
}
async function setupContainers() {
await tick
if (!notices.top) {
notices.top = new Notices({
target: document.body,
props: {
position: 'top'
},
});
}
if (!notices.bottom) {
notices.bottom = new Notices({
target: document.body,
props: {
position: 'bottom',
},
});
}
}
function chooseParent() {
parent = notices.top
if (position && position.indexOf('is-bottom') === 0) parent = notices.bottom
parent.insert(el)
}
onMount(async () => {
await setupContainers()
chooseParent()
timer = setTimeout(() => {
close()
}, duration)
})
</script>
<style lang="scss">
.notice {
display: inline-flex;
pointer-events: auto;
&.is-top,
&.is-bottom {
align-self: center;
}
&.is-top-left,
&.is-bottom-left {
align-self: flex-start;
}
&.is-top-right,
&.is-bottom-right {
align-self: flex-end;
}
}
</style>
{#if active}
<div
class="notice {position}"
aria-hidden={!active}
in:fly={{ y: transitionY }}
out:fade={{ duration: transitionOut ? 400 : 0 }}
on:outroend={remove}
bind:this={el}>
<slot />
</div>
{/if}