-
Notifications
You must be signed in to change notification settings - Fork 1
/
Loading.svelte
64 lines (60 loc) · 2.03 KB
/
Loading.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
<!-- @component
The purpose of `Loading` is to provide a visual, as well as Screen Reader friendly, cueue that associated content is loading
until the slotted content is signals it is done loading via the `loading` boolean bind at which point the slotted content
will be rendered.
-->
<script lang="ts">
import { afterUpdate } from 'svelte'
import ScreenReaderOnly from './ScreenReaderOnly.svelte'
import { resize, ResizeStore } from '$lib/actions'
export let loading: boolean | undefined
export let height: string | undefined = undefined
const store = new ResizeStore()
let containerelement: HTMLElement
let parentScrolls: boolean
afterUpdate(() => {
if (height || !containerelement) return
const parent = containerelement.offsetParent!
const overflowY = window.getComputedStyle(parent).overflowY
parentScrolls = overflowY === 'scroll' || overflowY === 'auto'
})
</script>
{#if loading}
<div bind:this={containerelement} class="container" class:parentScrolls style:height={height} style:position={height ? 'relative' : undefined}>
<div use:resize={{ store }} class="loader" style:border-width="{$store.offsetWidth ? $store.offsetWidth * 0.1 : 0}px"><ScreenReaderOnly>Loading</ScreenReaderOnly></div>
</div>
{:else}
<slot />
{/if}
<style>
.container {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
z-index: 2;
background-color: var(--loading-bg, var(--modal-bg, rgba(0, 0, 0, 0.7)));
display: flex;
align-items: center;
justify-content: center;
}
.container.parentScrolls {
position: sticky;
margin-bottom: -100%;
}
.loader {
box-sizing: content-box;
width: var(--loading-size, 10%);
padding-top: var(--loading-size, 10%);
border-color: var(--loading-bg-color, #FFFFFF);
border-top-color: var(--loading-moving-color, #333333);
border-style: solid;
border-radius: 50%;
animation: spin 2s linear infinite;
}
@keyframes spin {
0% { transform: rotate(0deg); }
100% { transform: rotate(360deg); }
}
</style>