Skip to content

Commit c7a1103

Browse files
committed
Prepare first release
1 parent c215ea2 commit c7a1103

File tree

4 files changed

+175
-0
lines changed

4 files changed

+175
-0
lines changed

src/SvelteToast.svelte

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
<script>
2+
import { fade, fly } from 'svelte/transition'
3+
import { flip } from 'svelte/animate'
4+
import { toast } from './stores.js'
5+
import ToastItem from './ToastItem.svelte'
6+
7+
export let options = {}
8+
const defaults = {
9+
duration: 4000,
10+
dismissable: true,
11+
initial: 1,
12+
progress: 0,
13+
reversed: false,
14+
intro: { x: 256 },
15+
theme: {}
16+
}
17+
toast._opts(defaults)
18+
19+
$: toast._opts(options)
20+
21+
const getCss = theme => {
22+
let css = ''
23+
for (const [key, val] of Object.entries(theme)) {
24+
css += `${key}:${val};`
25+
}
26+
return css || undefined
27+
}
28+
</script>
29+
30+
<style>
31+
ul {
32+
position: fixed;
33+
margin: 0;
34+
padding: 0;
35+
list-style-type: none;
36+
z-index: 9999;
37+
pointer-events: none;
38+
top: var(--toastContainerTop,1.5rem);
39+
right: var(--toastContainerRight,2rem);
40+
bottom: var(--toastContainerBottom,auto);
41+
left: var(--toastContainerLeft,auto);
42+
}
43+
</style>
44+
45+
<ul>
46+
{#each $toast as item (item.id)}
47+
<li
48+
in:fly={item.intro}
49+
out:fade
50+
animate:flip={{ duration: 200 }}
51+
style={getCss(item.theme)}
52+
>
53+
<ToastItem {item} />
54+
</li>
55+
{/each}
56+
</ul>

src/ToastItem.svelte

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
<script>
2+
import { tweened } from 'svelte/motion'
3+
import { linear } from 'svelte/easing'
4+
import { toast } from './stores.js'
5+
6+
export let item
7+
8+
const progress = tweened(item.initial, { duration: item.duration, easing: linear })
9+
10+
let prevProgress = item.initial
11+
12+
$: if (prevProgress !== item.progress) {
13+
if (item.progress === 1 || item.progress === 0) {
14+
progress.set(item.progress).then(() => toast.pop(item.id))
15+
} else {
16+
progress.set(item.progress)
17+
}
18+
prevProgress = item.progress
19+
}
20+
21+
</script>
22+
23+
<style>
24+
._toastItem {
25+
width: var(--toastWidth,16rem);
26+
height: var(--toastHeight,3.5rem);
27+
margin-bottom: var(--toastMarginBottom,0.5rem);
28+
background: var(--toastBackground,rgba(74,85,104,0.98));
29+
color: var(--toastColor,#FFF);
30+
box-shadow: 0 4px 6px -1px rgba(0,0,0,0.1),0 2px 4px -1px rgba(0,0,0,0.06);
31+
border-radius: 0.125rem;
32+
position: relative;
33+
display: flex;
34+
flex-direction: row;
35+
align-items: center;
36+
will-change: transform,opacity;
37+
-webkit-tap-highlight-color: transparent;
38+
}
39+
._toastMsg {
40+
font-size: var(--toastFontSize,1rem);
41+
flex: 1 1 0%;
42+
padding: 0 0.5rem;
43+
}
44+
._toastBtn {
45+
width: 2rem;
46+
height: 100%;
47+
font: 1rem sans-serif;
48+
display: flex;
49+
align-items: center;
50+
justify-content: center;
51+
cursor: pointer;
52+
outline: none;
53+
pointer-events: auto;
54+
}
55+
._toastBar {
56+
display: block;
57+
appearance: none;
58+
border: none;
59+
position: absolute;
60+
bottom: 0;
61+
width: 100%;
62+
height: 6px;
63+
background: transparent;
64+
}
65+
._toastBar::-webkit-progress-bar {
66+
background: transparent;
67+
}
68+
._toastBar::-webkit-progress-value {
69+
background: var(--toastProgressBackground,rgba(66,153,225,0.98));
70+
}
71+
._toastBar::-moz-progress-bar {
72+
background: var(--toastProgressBackground,rgba(66,153,225,0.98));
73+
}
74+
</style>
75+
76+
<div class="_toastItem">
77+
<div class="_toastMsg">{item.msg}</div>
78+
79+
{#if item.dismissable}
80+
<div class="_toastBtn" role="button" tabindex="-1" on:click={() => toast.pop(item.id)}>✕</div>
81+
{/if}
82+
83+
<progress class="_toastBar" value={$progress}></progress>
84+
</div>

src/index.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
import SvelteToast from './SvelteToast.svelte'
2+
import { toast } from './stores'
3+
4+
export { SvelteToast, toast }

src/stores.js

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
import { writable } from 'svelte/store'
2+
3+
const createToast = () => {
4+
const { subscribe, update } = writable([])
5+
let count = 0
6+
let defaults = {}
7+
const push = (msg, opts = {}) => {
8+
const entry = { id: ++count, msg: msg, ...defaults, ...opts, theme: { ...defaults.theme, ...opts.theme } }
9+
update(n => entry.reversed ? [...n, entry] : [entry, ...n])
10+
return count
11+
}
12+
const pop = id => {
13+
update(n => id ? n.filter(i => i.id !== id) : n.splice(1))
14+
}
15+
const set = (id, obj) => {
16+
update(n => {
17+
const idx = n.findIndex(i => i.id === id)
18+
if (idx > -1) {
19+
n[idx] = { ...n[idx], ...obj }
20+
}
21+
return n
22+
})
23+
}
24+
const _opts = (obj = {}) => {
25+
defaults = { ...defaults, ...obj, theme: { ...defaults.theme, ...obj.theme } }
26+
return defaults
27+
}
28+
return { subscribe, push, pop, set, _opts }
29+
}
30+
31+
export const toast = createToast()

0 commit comments

Comments
 (0)