From 551042b4dd69b5ab4da3944a4ab18651837f7ff1 Mon Sep 17 00:00:00 2001 From: Jason Lee Date: Sun, 6 Oct 2024 15:40:48 +0800 Subject: [PATCH 01/31] Update `.gitignore` --- .gitignore | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.gitignore b/.gitignore index a020e0e..7e7bd66 100644 --- a/.gitignore +++ b/.gitignore @@ -10,3 +10,5 @@ vite.config.js.timestamp-* vite.config.ts.timestamp-* /temp /test-results +/.vscode +.spellignore From a86148252a1407a5841639669b26479ad19d9ac4 Mon Sep 17 00:00:00 2001 From: Jason Lee Date: Mon, 7 Oct 2024 00:36:57 +0800 Subject: [PATCH 02/31] Set default opts from container instead --- src/lib/SvelteToast.svelte | 13 ++++++++++++- src/lib/stores.js | 13 ------------- 2 files changed, 12 insertions(+), 14 deletions(-) diff --git a/src/lib/SvelteToast.svelte b/src/lib/SvelteToast.svelte index bee4374..e881884 100644 --- a/src/lib/SvelteToast.svelte +++ b/src/lib/SvelteToast.svelte @@ -9,6 +9,17 @@ export let options = {} /** @type {(string|'default')} */ export let target = 'default' +/** @type {import('./stores.js').SvelteToastOptions} */ +const defaults = { + duration: 4000, + initial: 1, + next: 0, + pausable: false, + dismissable: true, + reversed: false, + intro: { x: 256 } +} + /** @type {import('./stores.js').SvelteToastOptions[]} */ let items = [] @@ -17,7 +28,7 @@ function getCss(theme) { return theme ? Object.keys(theme).reduce((a, c) => `${a}${c}:${theme[c]};`, '') : undefined } -$: toast._init(target, options) +$: toast._init(target, { ...defaults, ...options }) $: items = $toast.filter((i) => i.target === target) diff --git a/src/lib/stores.js b/src/lib/stores.js index 4ba5471..14af331 100644 --- a/src/lib/stores.js +++ b/src/lib/stores.js @@ -40,17 +40,6 @@ import { writable } from 'svelte/store' * @property {number} [progress] - DEPRECATED */ -/** @type {SvelteToastOptions} */ -const defaults = { - duration: 4000, - initial: 1, - next: 0, - pausable: false, - dismissable: true, - reversed: false, - intro: { x: 256 } -} - function createToast() { const { subscribe, update } = writable(new Array()) /** @type {Object} */ @@ -64,7 +53,6 @@ function createToast() { function _init(target = 'default', opts = {}) { options[target] = opts - return options } /** @@ -80,7 +68,6 @@ function createToast() { } const conf = options[param.target] || {} const entry = { - ...defaults, ...conf, ...param, theme: { ...conf.theme, ...param.theme }, From 63c5cafae58ab0efde3ec944a9bc4b0aa5b3f437 Mon Sep 17 00:00:00 2001 From: Jason Lee Date: Mon, 7 Oct 2024 15:37:42 +0800 Subject: [PATCH 03/31] Decouple `ToastItem` into `Controller` and `View` --- src/lib/Controller.svelte | 91 +++++++++++++++++++ src/lib/SvelteToast.svelte | 10 ++- src/lib/{ToastItem.svelte => View.svelte} | 105 +++------------------- src/lib/stores.js | 9 +- 4 files changed, 108 insertions(+), 107 deletions(-) create mode 100644 src/lib/Controller.svelte rename src/lib/{ToastItem.svelte => View.svelte} (50%) diff --git a/src/lib/Controller.svelte b/src/lib/Controller.svelte new file mode 100644 index 0000000..fd66d46 --- /dev/null +++ b/src/lib/Controller.svelte @@ -0,0 +1,91 @@ + + +
{ + if (item.pausable) pause() + }} + on:mouseleave={resume} +> + +
diff --git a/src/lib/SvelteToast.svelte b/src/lib/SvelteToast.svelte index e881884..f1599d6 100644 --- a/src/lib/SvelteToast.svelte +++ b/src/lib/SvelteToast.svelte @@ -2,11 +2,12 @@ import { fade, fly } from 'svelte/transition' import { flip } from 'svelte/animate' import { toast } from './stores.js' -import ToastItem from './ToastItem.svelte' +import Controller from './Controller.svelte' +import View from './View.svelte' /** @type {import('./stores.js').SvelteToastOptions} */ export let options = {} -/** @type {(string|'default')} */ +/** @type {string|'default'} */ export let target = 'default' /** @type {import('./stores.js').SvelteToastOptions} */ @@ -17,7 +18,8 @@ const defaults = { pausable: false, dismissable: true, reversed: false, - intro: { x: 256 } + intro: { x: 256 }, + component: View } /** @type {import('./stores.js').SvelteToastOptions[]} */ @@ -42,7 +44,7 @@ $: items = $toast.filter((i) => i.target === target) animate:flip={{ duration: 200 }} style={getCss(item.theme)} > - + {/each} diff --git a/src/lib/ToastItem.svelte b/src/lib/View.svelte similarity index 50% rename from src/lib/ToastItem.svelte rename to src/lib/View.svelte index 248f5e7..d618145 100644 --- a/src/lib/ToastItem.svelte +++ b/src/lib/View.svelte @@ -1,113 +1,28 @@ -
{ - if (item.pausable) pause() - }} - on:mouseleave={resume} -> -
- {#if item.component} - - {:else} - {@html item.msg} - {/if} +
+
+ {@html item.msg}
{#if item.dismissable}
close(ev)} + on:click={dismiss} on:keydown={(ev) => { - if (ev instanceof KeyboardEvent && ['Enter', ' '].includes(ev.key)) close(ev) + if (ev instanceof KeyboardEvent && ['Enter', ' '].includes(ev.key)) dismiss() }} /> {/if} diff --git a/src/lib/stores.js b/src/lib/stores.js index 14af331..41c513b 100644 --- a/src/lib/stores.js +++ b/src/lib/stores.js @@ -8,13 +8,6 @@ import { writable } from 'svelte/store' * @typedef {import('svelte/transition').FlyParams} FlyParams */ -/** - * @typedef {Object} SvelteToastCustomComponent - * @property {SvelteComponent} src - custom Svelte Component - * @property {Object} [props] - props to pass into custom component - * @property {string} [sendIdTo] - forward toast id to prop name - */ - /** * @callback SvelteToastOnPopCallback * @param {number} [id] - optionally get the toast id if needed @@ -36,7 +29,7 @@ import { writable } from 'svelte/store' * @property {Object} [theme] - css var overrides * @property {string[]} [classes] - user-defined classes * @property {SvelteToastOnPopCallback} [onpop] - callback that runs on toast dismiss - * @property {SvelteToastCustomComponent} [component] - send custom Svelte Component as a message + * @property {SvelteComponent} [component] - send custom Svelte Component as a message * @property {number} [progress] - DEPRECATED */ From 652fdacc26056cc6d85589516f06d222963168ac Mon Sep 17 00:00:00 2001 From: Jason Lee Date: Mon, 7 Oct 2024 15:44:34 +0800 Subject: [PATCH 04/31] Remove deprecated `progress` references --- src/lib/Controller.svelte | 5 ----- src/lib/View.svelte | 5 ++--- src/lib/stores.js | 29 ++++++++++++++--------------- 3 files changed, 16 insertions(+), 23 deletions(-) diff --git a/src/lib/Controller.svelte b/src/lib/Controller.svelte index fd66d46..6a32443 100644 --- a/src/lib/Controller.svelte +++ b/src/lib/Controller.svelte @@ -65,11 +65,6 @@ $: if (next !== item.next) { progress.set(next).then(autoclose) } -// `progress` has been renamed to `next`; shim included for backward compatibility, to remove in next major -$: if (!check(item.progress)) { - item.next = item.progress -} - onMount(listen) onDestroy(() => { diff --git a/src/lib/View.svelte b/src/lib/View.svelte index d618145..89be686 100644 --- a/src/lib/View.svelte +++ b/src/lib/View.svelte @@ -93,11 +93,10 @@ function dismiss() { ._toastBar::-webkit-progress-bar { background: transparent; } -/* `--toastProgressBackground` renamed to `--toastBarBackground`; override included for backward compatibility */ ._toastBar::-webkit-progress-value { - background: var(--toastProgressBackground, var(--toastBarBackground, rgba(33, 150, 243, 0.75))); + background: var(--toastBarBackground, rgba(33, 150, 243, 0.75)); } ._toastBar::-moz-progress-bar { - background: var(--toastProgressBackground, var(--toastBarBackground, rgba(33, 150, 243, 0.75))); + background: var(--toastBarBackground, rgba(33, 150, 243, 0.75)); } diff --git a/src/lib/stores.js b/src/lib/stores.js index 41c513b..c2fdc96 100644 --- a/src/lib/stores.js +++ b/src/lib/stores.js @@ -16,21 +16,20 @@ import { writable } from 'svelte/store' /** * @typedef {Object} SvelteToastOptions - * @property {number} [id] - unique id generated for every toast - * @property {string} [target] - container target name to send toast to - * @property {string} [msg] - toast message - * @property {number} [duration] - duration of progress bar tween from initial to next - * @property {number} [initial] - initial progress bar value - * @property {number} [next] - next progress bar value - * @property {boolean} [pausable] - pause progress bar tween on mouse hover - * @property {boolean} [dismissable] - allow dissmiss with close button - * @property {boolean} [reversed] - display toasts in reverse order - * @property {FlyParams} [intro] - toast intro fly animation settings - * @property {Object} [theme] - css var overrides - * @property {string[]} [classes] - user-defined classes - * @property {SvelteToastOnPopCallback} [onpop] - callback that runs on toast dismiss - * @property {SvelteComponent} [component] - send custom Svelte Component as a message - * @property {number} [progress] - DEPRECATED + * @prop {number} [id] - unique id generated for every toast + * @prop {string} [target] - container target name to send toast to + * @prop {string} [msg] - toast message + * @prop {number} [duration] - duration of progress bar tween from initial to next + * @prop {number} [initial] - initial progress bar value + * @prop {number} [next] - next progress bar value + * @prop {boolean} [pausable] - pause progress bar tween on mouse hover + * @prop {boolean} [dismissable] - allow dissmiss with close button + * @prop {boolean} [reversed] - display toasts in reverse order + * @prop {FlyParams} [intro] - toast intro fly animation settings + * @prop {Object} [theme] - css var overrides + * @prop {string[]} [classes] - user-defined classes + * @prop {SvelteToastOnPopCallback} [onpop] - callback that runs on toast dismiss + * @prop {SvelteComponent} [component] - send custom Svelte Component as a message */ function createToast() { From e2366bc2fe9a099fa353c110ecd53c858aad2996 Mon Sep 17 00:00:00 2001 From: Jason Lee Date: Mon, 7 Oct 2024 16:01:24 +0800 Subject: [PATCH 05/31] Add feat `unsafe` html toast msg --- src/lib/View.svelte | 6 +++++- src/lib/stores.js | 1 + 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/src/lib/View.svelte b/src/lib/View.svelte index 89be686..ebcdc23 100644 --- a/src/lib/View.svelte +++ b/src/lib/View.svelte @@ -13,7 +13,11 @@ function dismiss() {
- {@html item.msg} + {#if item.unsafe} + {@html item.msg} + {:else} + {item.msg} + {/if}
{#if item.dismissable}
Date: Mon, 7 Oct 2024 21:39:04 +0800 Subject: [PATCH 06/31] Replace `onpop` callback with promise-based impl --- src/lib/Controller.svelte | 13 +++--- src/lib/stores.js | 90 +++++++++++++++++++++------------------ 2 files changed, 54 insertions(+), 49 deletions(-) diff --git a/src/lib/Controller.svelte b/src/lib/Controller.svelte index 6a32443..a7f988b 100644 --- a/src/lib/Controller.svelte +++ b/src/lib/Controller.svelte @@ -13,15 +13,12 @@ let prev = next let paused = false /** @type {any} */ let unlisten -/** @type {MouseEvent | KeyboardEvent} */ -let event const progress = tweened(item.initial, { duration: item.duration, easing: linear }) -/** @param {MouseEvent|KeyboardEvent|undefined} [ev] */ -function close(ev) { - if (ev) event = ev - toast.pop(item.id) +/** @param {{value:any}|undefined} [detail] */ +function close(detail) { + toast.pop(item.id, detail) } function autoclose() { @@ -68,7 +65,7 @@ $: if (next !== item.next) { onMount(listen) onDestroy(() => { - item.onpop && item.onpop(item.id, { event }) + //item.onpop && item.onpop(item.id, { event }) unlisten && unlisten() }) @@ -82,5 +79,5 @@ onDestroy(() => { }} on:mouseleave={resume} > - + close(e.detail)} />
diff --git a/src/lib/stores.js b/src/lib/stores.js index ee3d187..b8cfdfb 100644 --- a/src/lib/stores.js +++ b/src/lib/stores.js @@ -9,85 +9,93 @@ import { writable } from 'svelte/store' */ /** - * @callback SvelteToastOnPopCallback - * @param {number} [id] - optionally get the toast id if needed - * @param {object} [details] + * @typedef {Object} SvelteToastPushed + * @prop {number} id - toast id + * @prop {Promise} onpop - promise that resolves to value when toast closed + */ + +/** + * @typedef {Object} SvelteToastPop + * @prop {number} [id] - remove toast with specified id + * @prop {any} [value] - onpop resolve value + * @prop {string} [target] - remove all toasts from target container */ /** * @typedef {Object} SvelteToastOptions - * @prop {number} [id] - unique id generated for every toast + * @prop {number} [id] - unique id generated for each toast * @prop {string} [target] - container target name to send toast to * @prop {string} [msg] - toast message - * @prop {boolean} [unsafe] - allow unsafe html toast message + * @prop {boolean} [unsafe] - allow unsafe html in toast message * @prop {number} [duration] - duration of progress bar tween from initial to next * @prop {number} [initial] - initial progress bar value * @prop {number} [next] - next progress bar value * @prop {boolean} [pausable] - pause progress bar tween on mouse hover - * @prop {boolean} [dismissable] - allow dissmiss with close button + * @prop {boolean} [dismissable] - allow dismiss with close button * @prop {boolean} [reversed] - display toasts in reverse order * @prop {FlyParams} [intro] - toast intro fly animation settings * @prop {Object} [theme] - css var overrides * @prop {string[]} [classes] - user-defined classes - * @prop {SvelteToastOnPopCallback} [onpop] - callback that runs on toast dismiss * @prop {SvelteComponent} [component] - send custom Svelte Component as a message + * @prop {any} [_resolve] */ function createToast() { const { subscribe, update } = writable(new Array()) + /** @type {Object} */ - const options = {} + const defaults = {} let count = 0 - - /** @param {any} obj */ - function _obj(obj) { - return obj instanceof Object - } + const _obj = (/** @type {any} */ obj) => obj instanceof Object function _init(target = 'default', opts = {}) { - options[target] = opts + defaults[target] = opts } /** * Send a new toast - * @param {(string|SvelteToastOptions)} msg + * @param {string|SvelteToastOptions} msg * @param {SvelteToastOptions} [opts] - * @returns {number} + * @returns {SvelteToastPushed} */ function push(msg, opts) { - const param = { - target: 'default', - ...(_obj(msg) ? /** @type {SvelteToastOptions} */ (msg) : { ...opts, msg }) - } - const conf = options[param.target] || {} - const entry = { - ...conf, - ...param, - theme: { ...conf.theme, ...param.theme }, - classes: [...(conf.classes || []), ...(param.classes || [])], - id: ++count - } - update((n) => (entry.reversed ? [...n, entry] : [entry, ...n])) - return count + /** @type {any} */ + const param = _obj(msg) ? msg : { ...opts, msg } + const target = param.target || 'default' + const base = defaults[target] || {} + const classes = [...(base.classes || []), ...(param.classes || [])] + const id = ++count + let _resolve + const onpop = new Promise((resolve) => (_resolve = resolve)) + const item = { ...base, ...param, target, classes, id, _resolve } + //update((n) => [...n, entry]) + update((n) => [item, ...n]) + return { id, onpop } } /** * Remove toast(s) - * - toast.pop() // removes the last toast + * - toast.pop() // remove the lastest toast * - toast.pop(0) // remove all toasts - * - toast.pop(id) // removes the toast with specified `id` + * - toast.pop(id) // remove toast with specified id * - toast.pop({ target: 'foo' }) // remove all toasts from target `foo` - * @param {(number|Object<'target',string>)} [id] + * @param {number|SvelteToastPop} [id] - remove toast with specified id + * @param {SvelteToastPop} [opts] */ - function pop(id) { + function pop(id, opts) { update((n) => { - if (!n.length || id === 0) return [] - // Filter function is deprecated; shim added for backward compatibility - if (typeof id === 'function') return n.filter((i) => id(i)) - if (_obj(id)) - return n.filter(/** @type {SvelteToastOptions[]} i */ (i) => i.target !== id.target) - const found = id || Math.max(...n.map((i) => i.id)) - return n.filter((i) => i.id !== found) + if (!n.length) return n + /** @type {any} */ + const { id: _id, target, value } = _obj(id) ? id : { ...opts, id } + const resolve = (/** @type {any[]} */ items) => items.forEach((i) => i._resolve(value)) + if (target || _id) { + const key = target ? 'target' : 'id' + const val = target || _id + resolve(n.filter((i) => i[key] === val)) + return n.filter((i) => i[key] !== val) + } + resolve(_id === 0 ? n : n.slice(-1)) + return _id === 0 ? [] : n.slice(0, -1) }) } From b8c33172d1969853bc5727fb9209d814b78f7f61 Mon Sep 17 00:00:00 2001 From: Jason Lee Date: Mon, 7 Oct 2024 21:51:17 +0800 Subject: [PATCH 07/31] Uno reverse the `reversed` setting :) --- src/lib/SvelteToast.svelte | 17 ++++++++++++----- src/lib/stores.js | 3 +-- 2 files changed, 13 insertions(+), 7 deletions(-) diff --git a/src/lib/SvelteToast.svelte b/src/lib/SvelteToast.svelte index f1599d6..6af6d4e 100644 --- a/src/lib/SvelteToast.svelte +++ b/src/lib/SvelteToast.svelte @@ -17,11 +17,12 @@ const defaults = { next: 0, pausable: false, dismissable: true, - reversed: false, + reversed: true, intro: { x: 256 }, component: View } - +/** @type {import('./stores.js').SvelteToastOptions} */ +let merged /** @type {import('./stores.js').SvelteToastOptions[]} */ let items = [] @@ -30,9 +31,15 @@ function getCss(theme) { return theme ? Object.keys(theme).reduce((a, c) => `${a}${c}:${theme[c]};`, '') : undefined } -$: toast._init(target, { ...defaults, ...options }) - -$: items = $toast.filter((i) => i.target === target) +$: { + merged = { ...defaults, ...options } + toast._init(target, merged) +} +$: { + const _items = $toast.filter((i) => i.target === target) + if (merged.reversed) _items.reverse() + items = _items +}
    diff --git a/src/lib/stores.js b/src/lib/stores.js index b8cfdfb..ba40a03 100644 --- a/src/lib/stores.js +++ b/src/lib/stores.js @@ -68,8 +68,7 @@ function createToast() { let _resolve const onpop = new Promise((resolve) => (_resolve = resolve)) const item = { ...base, ...param, target, classes, id, _resolve } - //update((n) => [...n, entry]) - update((n) => [item, ...n]) + update((n) => [...n, item]) return { id, onpop } } From 213be9d2be89744770f4fa11fc9079e58985423a Mon Sep 17 00:00:00 2001 From: Jason Lee Date: Tue, 8 Oct 2024 01:56:41 +0800 Subject: [PATCH 08/31] Valid `id` takes precedence over `target` --- src/lib/stores.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/lib/stores.js b/src/lib/stores.js index ba40a03..e71ea97 100644 --- a/src/lib/stores.js +++ b/src/lib/stores.js @@ -78,7 +78,7 @@ function createToast() { * - toast.pop(0) // remove all toasts * - toast.pop(id) // remove toast with specified id * - toast.pop({ target: 'foo' }) // remove all toasts from target `foo` - * @param {number|SvelteToastPop} [id] - remove toast with specified id + * @param {number|SvelteToastPop} [id] * @param {SvelteToastPop} [opts] */ function pop(id, opts) { @@ -87,9 +87,9 @@ function createToast() { /** @type {any} */ const { id: _id, target, value } = _obj(id) ? id : { ...opts, id } const resolve = (/** @type {any[]} */ items) => items.forEach((i) => i._resolve(value)) - if (target || _id) { - const key = target ? 'target' : 'id' - const val = target || _id + const val = _id || target + if (val) { + const key = _id ? 'id' : 'target' resolve(n.filter((i) => i[key] === val)) return n.filter((i) => i[key] !== val) } From 76f13bedee3534d842e16c82a947409880740568 Mon Sep 17 00:00:00 2001 From: Jason Lee Date: Tue, 8 Oct 2024 02:02:45 +0800 Subject: [PATCH 09/31] Expose `outro` fade animation settings --- src/lib/SvelteToast.svelte | 2 +- src/lib/stores.js | 5 +++++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/src/lib/SvelteToast.svelte b/src/lib/SvelteToast.svelte index 6af6d4e..1485cb2 100644 --- a/src/lib/SvelteToast.svelte +++ b/src/lib/SvelteToast.svelte @@ -47,7 +47,7 @@ $: {
  • diff --git a/src/lib/stores.js b/src/lib/stores.js index e71ea97..ab4f306 100644 --- a/src/lib/stores.js +++ b/src/lib/stores.js @@ -8,6 +8,10 @@ import { writable } from 'svelte/store' * @typedef {import('svelte/transition').FlyParams} FlyParams */ +/** + * @typedef {import('svelte/transition').FadeParams} FadeParams + */ + /** * @typedef {Object} SvelteToastPushed * @prop {number} id - toast id @@ -34,6 +38,7 @@ import { writable } from 'svelte/store' * @prop {boolean} [dismissable] - allow dismiss with close button * @prop {boolean} [reversed] - display toasts in reverse order * @prop {FlyParams} [intro] - toast intro fly animation settings + * @prop {FadeParams} [outro] - toast outro fade animation settings * @prop {Object} [theme] - css var overrides * @prop {string[]} [classes] - user-defined classes * @prop {SvelteComponent} [component] - send custom Svelte Component as a message From 610057fd8f3af46dcd4c3fa1498836c8ba92a13f Mon Sep 17 00:00:00 2001 From: Jason Lee Date: Tue, 8 Oct 2024 03:03:09 +0800 Subject: [PATCH 10/31] Decouple container and item themes --- src/lib/Controller.svelte | 3 ++- src/lib/SvelteToast.svelte | 18 +++++++----------- src/lib/stores.js | 9 ++++++++- 3 files changed, 17 insertions(+), 13 deletions(-) diff --git a/src/lib/Controller.svelte b/src/lib/Controller.svelte index a7f988b..38656cf 100644 --- a/src/lib/Controller.svelte +++ b/src/lib/Controller.svelte @@ -2,7 +2,7 @@ import { onMount, onDestroy } from 'svelte' import { tweened } from 'svelte/motion' import { linear } from 'svelte/easing' -import { toast } from './stores.js' +import { toast, themeToStyle } from './stores.js' /** @type {import('./stores.js').SvelteToastOptions} */ export let item @@ -74,6 +74,7 @@ onDestroy(() => { role="status" class="_toastItem" class:pe={item.pausable} + style={themeToStyle(item.theme)} on:mouseenter={() => { if (item.pausable) pause() }} diff --git a/src/lib/SvelteToast.svelte b/src/lib/SvelteToast.svelte index 1485cb2..30baa15 100644 --- a/src/lib/SvelteToast.svelte +++ b/src/lib/SvelteToast.svelte @@ -1,7 +1,7 @@ -
      +
        {#each items as item (item.id)}
      • diff --git a/src/lib/stores.js b/src/lib/stores.js index ab4f306..6b45276 100644 --- a/src/lib/stores.js +++ b/src/lib/stores.js @@ -123,4 +123,11 @@ function createToast() { return { subscribe, push, pop, set, _init } } -export const toast = createToast() +const toast = createToast() + +/** @param {Object} [theme] */ +function themeToStyle(theme) { + return theme ? Object.keys(theme).reduce((a, c) => `${a}${c}:${theme[c]};`, '') : undefined +} + +export { toast, themeToStyle } From 852f15cdc39bf7b8b0a53d6e5a3cc4a0a94c161c Mon Sep 17 00:00:00 2001 From: Jason Lee Date: Tue, 8 Oct 2024 03:04:23 +0800 Subject: [PATCH 11/31] Don't use magical z-index --- src/lib/SvelteToast.svelte | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lib/SvelteToast.svelte b/src/lib/SvelteToast.svelte index 30baa15..45c06bb 100644 --- a/src/lib/SvelteToast.svelte +++ b/src/lib/SvelteToast.svelte @@ -63,6 +63,6 @@ $: { padding: 0; list-style-type: none; pointer-events: none; - z-index: var(--toastContainerZIndex, 9999); + z-index: var(--toastContainerZIndex, auto); } From 352a2f25eedd5c4dd52696e9face0eac451cc2be Mon Sep 17 00:00:00 2001 From: Jason Lee Date: Thu, 10 Oct 2024 14:56:25 +0700 Subject: [PATCH 12/31] Use `fly` transition for outro too --- src/lib/SvelteToast.svelte | 2 +- src/lib/stores.js | 6 +----- 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/src/lib/SvelteToast.svelte b/src/lib/SvelteToast.svelte index 45c06bb..5baadd7 100644 --- a/src/lib/SvelteToast.svelte +++ b/src/lib/SvelteToast.svelte @@ -44,7 +44,7 @@ $: {
      • diff --git a/src/lib/stores.js b/src/lib/stores.js index 6b45276..6c0e59d 100644 --- a/src/lib/stores.js +++ b/src/lib/stores.js @@ -8,10 +8,6 @@ import { writable } from 'svelte/store' * @typedef {import('svelte/transition').FlyParams} FlyParams */ -/** - * @typedef {import('svelte/transition').FadeParams} FadeParams - */ - /** * @typedef {Object} SvelteToastPushed * @prop {number} id - toast id @@ -38,7 +34,7 @@ import { writable } from 'svelte/store' * @prop {boolean} [dismissable] - allow dismiss with close button * @prop {boolean} [reversed] - display toasts in reverse order * @prop {FlyParams} [intro] - toast intro fly animation settings - * @prop {FadeParams} [outro] - toast outro fade animation settings + * @prop {FlyParams} [outro] - toast outro fade animation settings * @prop {Object} [theme] - css var overrides * @prop {string[]} [classes] - user-defined classes * @prop {SvelteComponent} [component] - send custom Svelte Component as a message From 16e114b38a3c0244a384619bc16024ae5050d6a6 Mon Sep 17 00:00:00 2001 From: Jason Lee Date: Fri, 11 Oct 2024 11:53:40 +0700 Subject: [PATCH 13/31] Add four states of `pausable` --- src/lib/Controller.svelte | 36 +++++++++++++++++------------------- src/lib/SvelteToast.svelte | 2 +- src/lib/View.svelte | 6 +----- src/lib/stores.js | 2 +- 4 files changed, 20 insertions(+), 26 deletions(-) diff --git a/src/lib/Controller.svelte b/src/lib/Controller.svelte index 38656cf..ba6d313 100644 --- a/src/lib/Controller.svelte +++ b/src/lib/Controller.svelte @@ -11,8 +11,6 @@ export let item let next = item.initial let prev = next let paused = false -/** @type {any} */ -let unlisten const progress = tweened(item.initial, { duration: item.duration, easing: linear }) @@ -41,20 +39,19 @@ function resume() { } } -/** @param {any} prop */ -function check(prop, kind = 'undefined') { - return typeof prop === kind +function handler() { + document.hidden ? ['hidden', 'both'].includes(item.pausable || '') && pause() : resume() } -function listen(d = document) { - if (check(d.hidden)) return - const handler = () => (d.hidden ? pause() : resume()) - const name = 'visibilitychange' - d.addEventListener(name, handler) - unlisten = () => d.removeEventListener(name, handler) +function listen() { + document.addEventListener('visibilitychange', handler) handler() } +function unlisten() { + document.removeEventListener('visibilitychange', handler) +} + $: if (next !== item.next) { next = item.next prev = $progress @@ -63,22 +60,23 @@ $: if (next !== item.next) { } onMount(listen) - -onDestroy(() => { - //item.onpop && item.onpop(item.id, { event }) - unlisten && unlisten() -}) +onDestroy(unlisten)
        { - if (item.pausable) pause() + if (['hover', 'both'].includes(item.pausable || '')) pause() }} on:mouseleave={resume} > close(e.detail)} />
        + + diff --git a/src/lib/SvelteToast.svelte b/src/lib/SvelteToast.svelte index 5baadd7..19455ba 100644 --- a/src/lib/SvelteToast.svelte +++ b/src/lib/SvelteToast.svelte @@ -15,7 +15,7 @@ const defaults = { duration: 4000, initial: 1, next: 0, - pausable: false, + pausable: 'hidden', dismissable: true, reversed: true, intro: { x: 256 }, diff --git a/src/lib/View.svelte b/src/lib/View.svelte index ebcdc23..1ebcdcb 100644 --- a/src/lib/View.svelte +++ b/src/lib/View.svelte @@ -21,7 +21,7 @@ function dismiss() {
{#if item.dismissable}
Date: Fri, 11 Oct 2024 11:56:25 +0700 Subject: [PATCH 14/31] Typing improvements --- src/lib/stores.js | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/src/lib/stores.js b/src/lib/stores.js index 0de875f..a9c17fe 100644 --- a/src/lib/stores.js +++ b/src/lib/stores.js @@ -42,12 +42,12 @@ import { writable } from 'svelte/store' */ function createToast() { + /** @type {import('svelte/store').Writable} */ const { subscribe, update } = writable(new Array()) /** @type {Object} */ const defaults = {} let count = 0 - const _obj = (/** @type {any} */ obj) => obj instanceof Object function _init(target = 'default', opts = {}) { defaults[target] = opts @@ -60,8 +60,7 @@ function createToast() { * @returns {SvelteToastPushed} */ function push(msg, opts) { - /** @type {any} */ - const param = _obj(msg) ? msg : { ...opts, msg } + const param = typeof msg === 'object' ? msg : { ...opts, msg } const target = param.target || 'default' const base = defaults[target] || {} const classes = [...(base.classes || []), ...(param.classes || [])] @@ -85,8 +84,7 @@ function createToast() { function pop(id, opts) { update((n) => { if (!n.length) return n - /** @type {any} */ - const { id: _id, target, value } = _obj(id) ? id : { ...opts, id } + const { id: _id, target, value } = typeof id === 'object' ? id : { ...opts, id } const resolve = (/** @type {any[]} */ items) => items.forEach((i) => i._resolve(value)) const val = _id || target if (val) { @@ -105,8 +103,7 @@ function createToast() { * @param {SvelteToastOptions} [opts] */ function set(id, opts) { - /** @type {any} */ - const param = _obj(id) ? id : { ...opts, id } + const param = typeof id === 'object' ? id : { ...opts, id } update((n) => { const idx = n.findIndex((i) => i.id === param.id) if (idx > -1) { From b052f6e999dbc76ac8e09f775f64f4cb092da9cc Mon Sep 17 00:00:00 2001 From: Jason Lee Date: Fri, 11 Oct 2024 15:33:54 +0700 Subject: [PATCH 15/31] Lower CSS specificity --- src/lib/Controller.svelte | 2 +- src/lib/SvelteToast.svelte | 7 ++++--- src/lib/View.svelte | 9 ++++----- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/lib/Controller.svelte b/src/lib/Controller.svelte index ba6d313..fc44dff 100644 --- a/src/lib/Controller.svelte +++ b/src/lib/Controller.svelte @@ -76,7 +76,7 @@ onDestroy(unlisten)
diff --git a/src/lib/SvelteToast.svelte b/src/lib/SvelteToast.svelte index 19455ba..43aa3e8 100644 --- a/src/lib/SvelteToast.svelte +++ b/src/lib/SvelteToast.svelte @@ -1,5 +1,5 @@ -
    +
      {#each items as item (item.id)}
    • } [theme] */ -export function themeToStyle(theme) { - return theme ? Object.keys(theme).reduce((a, c) => `${a}${c}:${theme[c]};`, '') : undefined -} - export const PRESET = { /** @param {string} args */ _p(args) { From b7e507f9ad3125c779536dc6e7a7805b9687d4a2 Mon Sep 17 00:00:00 2001 From: Jason Lee Date: Sun, 13 Oct 2024 15:35:34 +0700 Subject: [PATCH 18/31] Mirror `class` prop to toast container --- src/lib/SvelteToast.svelte | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/lib/SvelteToast.svelte b/src/lib/SvelteToast.svelte index 47c9862..941eecd 100644 --- a/src/lib/SvelteToast.svelte +++ b/src/lib/SvelteToast.svelte @@ -9,6 +9,9 @@ import View from './View.svelte' export let options = {} /** @type {string|'default'} */ export let target = 'default' +/** @type {string|undefined} */ +let _class = undefined +export { _class as class } /** @type {import('./stores.js').SvelteToastOptions} */ const defaults = { @@ -44,7 +47,7 @@ $: { } -
        +
          {#each items as item (item.id)}
        • Date: Sun, 13 Oct 2024 15:36:51 +0700 Subject: [PATCH 19/31] Move presets to `index.js` --- src/lib/index.js | 35 ++++++++++++++++++++++++++++++++++- src/lib/stores.js | 34 ---------------------------------- 2 files changed, 34 insertions(+), 35 deletions(-) diff --git a/src/lib/index.js b/src/lib/index.js index 9d54b95..c2b2f88 100644 --- a/src/lib/index.js +++ b/src/lib/index.js @@ -1,5 +1,38 @@ export { default as SvelteToast } from './SvelteToast.svelte' -export { toast, PRESET } from './stores.js' +export { toast } from './stores.js' +export const PRESET = { + /** @param {string} args */ + _p(args) { + const [t, r, b, l, w, x, y, v] = args.split(';') + return JSON.parse( + `{"theme":{"--toastContainerTop":"${t}","--toastContainerRight":"${r}","--toastContainerBottom":"${b}","--toastContainerLeft":"${l}"${w ? `,"--toastWidth":"${w}"` : ''}},"intro":{${x ? `"x":"${x}"` : `"y":"${y}"`}},"reversed":${v}}` + ) + }, + /** @returns {SvelteToastOptions} - Top-right positioning preset */ + get TOP_RIGHT() { + return this._p('1.5rem;2rem;auto;auto;;256;;true') + }, + /** @returns {SvelteToastOptions} - Bottom-right positioning preset */ + get BOTTOM_RIGHT() { + return this._p('auto;2rem;1.5rem;auto;;256;;false') + }, + /** @returns {SvelteToastOptions} - Bottom-left positioning preset */ + get BOTTOM_LEFT() { + return this._p('auto;auto;1.5rem;2rem;;-256;;false') + }, + /** @returns {SvelteToastOptions} - Top-left positioning preset */ + get TOP_LEFT() { + return this._p('1.5rem;auto;auto;2rem;;-256;;true') + }, + /** @returns {SvelteToastOptions} - Top-center positioning preset */ + get TOP_CENTER() { + return this._p('1.5rem;auto;auto;calc(50vw - var(--toastWidth)/2);16rem;;-64;true') + }, + /** @returns {SvelteToastOptions} - Bottom-center positioning preset */ + get BOTTOM_CENTER() { + return this._p('auto;auto;1.5rem;calc(50vw - var(--toastWidth)/2);16rem;;64;false') + } +} /** * @typedef {import('./stores.js').SvelteToastOptions} SvelteToastOptions diff --git a/src/lib/stores.js b/src/lib/stores.js index 04d3aa9..d1fccdc 100644 --- a/src/lib/stores.js +++ b/src/lib/stores.js @@ -117,37 +117,3 @@ function createToast() { } export const toast = createToast() - -export const PRESET = { - /** @param {string} args */ - _p(args) { - const [t, r, b, l, w, x, y, v] = args.split(';') - return JSON.parse( - `{"theme":{"--toastContainerTop":"${t}","--toastContainerRight":"${r}","--toastContainerBottom":"${b}","--toastContainerLeft":"${l}"${w ? `,"--toastWidth":"${w}"` : ''}},"intro":{${x ? `"x":"${x}"` : `"y":"${y}"`}},"reversed":${v}}` - ) - }, - /** @returns {SvelteToastOptions} - Top-right positioning preset */ - get TOP_RIGHT() { - return this._p('1.5rem;2rem;auto;auto;;256;;true') - }, - /** @returns {SvelteToastOptions} - Bottom-right positioning preset */ - get BOTTOM_RIGHT() { - return this._p('auto;2rem;1.5rem;auto;;256;;false') - }, - /** @returns {SvelteToastOptions} - Bottom-left positioning preset */ - get BOTTOM_LEFT() { - return this._p('auto;auto;1.5rem;2rem;;-256;;false') - }, - /** @returns {SvelteToastOptions} - Top-left positioning preset */ - get TOP_LEFT() { - return this._p('1.5rem;auto;auto;2rem;;-256;;true') - }, - /** @returns {SvelteToastOptions} - Top-center positioning preset */ - get TOP_CENTER() { - return this._p('1.5rem;auto;auto;calc(50vw - var(--toastWidth)/2);16rem;;-64;true') - }, - /** @returns {SvelteToastOptions} - Bottom-center positioning preset */ - get BOTTOM_CENTER() { - return this._p('auto;auto;1.5rem;calc(50vw - var(--toastWidth)/2);16rem;;64;false') - } -} From 4a890c2a188601481750fb985e45a549786790e2 Mon Sep 17 00:00:00 2001 From: Jason Lee Date: Sun, 13 Oct 2024 16:46:47 +0700 Subject: [PATCH 20/31] Deprecate `classes` array into `class` string instead --- src/lib/Controller.svelte | 7 ------- src/lib/SvelteToast.svelte | 15 ++++++++++----- src/lib/stores.js | 5 ++--- 3 files changed, 12 insertions(+), 15 deletions(-) diff --git a/src/lib/Controller.svelte b/src/lib/Controller.svelte index 09b4af3..1bba51b 100644 --- a/src/lib/Controller.svelte +++ b/src/lib/Controller.svelte @@ -65,7 +65,6 @@ onDestroy(unlisten)
          { if (['hover', 'both'].includes(item.pausable || '')) pause() }} @@ -73,9 +72,3 @@ onDestroy(unlisten) > close(e.detail)} />
          - - diff --git a/src/lib/SvelteToast.svelte b/src/lib/SvelteToast.svelte index 941eecd..ff91bb8 100644 --- a/src/lib/SvelteToast.svelte +++ b/src/lib/SvelteToast.svelte @@ -10,8 +10,8 @@ export let options = {} /** @type {string|'default'} */ export let target = 'default' /** @type {string|undefined} */ -let _class = undefined -export { _class as class } +let classes = '' +export { classes as class } /** @type {import('./stores.js').SvelteToastOptions} */ const defaults = { @@ -30,6 +30,8 @@ let items = [] let merged /** @type {Object|undefined} */ let theme +/** @type {string|undefined} */ +let _class /** @param {Object} [obj] */ function toStyles(obj) { @@ -37,7 +39,7 @@ function toStyles(obj) { } $: { - ;({ theme, ...merged } = { ...defaults, ...options }) + ;({ theme, class: _class, ...merged } = { ...defaults, ...options }) toast._init(target, merged) } $: { @@ -47,10 +49,10 @@ $: { } -
            +
              {#each items as item (item.id)}
            • li) { + pointer-events: auto; +} diff --git a/src/lib/stores.js b/src/lib/stores.js index d1fccdc..8f96467 100644 --- a/src/lib/stores.js +++ b/src/lib/stores.js @@ -36,7 +36,7 @@ import { writable } from 'svelte/store' * @prop {FlyParams} [intro] - toast intro fly animation settings * @prop {FlyParams} [outro] - toast outro fade animation settings * @prop {Object} [theme] - css var overrides - * @prop {string[]} [classes] - user-defined classes + * @prop {string} [class] - user-defined classes * @prop {SvelteComponent} [component] - send custom Svelte Component as a message * @prop {any} [_resolve] */ @@ -63,11 +63,10 @@ function createToast() { const param = typeof msg === 'object' ? msg : { ...opts, msg } const target = param.target || 'default' const base = defaults[target] || {} - const classes = [...(base.classes || []), ...(param.classes || [])] const id = ++count let _resolve const onpop = new Promise((resolve) => (_resolve = resolve)) - const item = { ...base, ...param, target, classes, id, _resolve } + const item = { ...base, ...param, target, id, _resolve } update((n) => [...n, item]) return { id, onpop } } From d8fc28d289f00c4f13ff03099b8535c3efd30ec3 Mon Sep 17 00:00:00 2001 From: Jason Lee Date: Sun, 13 Oct 2024 16:52:38 +0700 Subject: [PATCH 21/31] Rename `component` opt to `view` instead --- src/lib/Controller.svelte | 2 +- src/lib/SvelteToast.svelte | 2 +- src/lib/stores.js | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/lib/Controller.svelte b/src/lib/Controller.svelte index 1bba51b..e9bb5c6 100644 --- a/src/lib/Controller.svelte +++ b/src/lib/Controller.svelte @@ -70,5 +70,5 @@ onDestroy(unlisten) }} on:mouseleave={resume} > - close(e.detail)} /> + close(e.detail)} />
diff --git a/src/lib/SvelteToast.svelte b/src/lib/SvelteToast.svelte index ff91bb8..2bf999e 100644 --- a/src/lib/SvelteToast.svelte +++ b/src/lib/SvelteToast.svelte @@ -22,7 +22,7 @@ const defaults = { dismissable: true, reversed: true, intro: { x: 256 }, - component: View + view: View } /** @type {import('./stores.js').SvelteToastOptions[]} */ let items = [] diff --git a/src/lib/stores.js b/src/lib/stores.js index 8f96467..1c16f58 100644 --- a/src/lib/stores.js +++ b/src/lib/stores.js @@ -37,7 +37,7 @@ import { writable } from 'svelte/store' * @prop {FlyParams} [outro] - toast outro fade animation settings * @prop {Object} [theme] - css var overrides * @prop {string} [class] - user-defined classes - * @prop {SvelteComponent} [component] - send custom Svelte Component as a message + * @prop {SvelteComponent} [view] - toast view Svelte component * @prop {any} [_resolve] */ From 8d4c9d936f3997410b261e245eeba6bdb19bc516 Mon Sep 17 00:00:00 2001 From: Jason Lee Date: Mon, 14 Oct 2024 23:51:24 +0700 Subject: [PATCH 22/31] Clean up toasts on destroy --- src/lib/SvelteToast.svelte | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/lib/SvelteToast.svelte b/src/lib/SvelteToast.svelte index 2bf999e..43f21da 100644 --- a/src/lib/SvelteToast.svelte +++ b/src/lib/SvelteToast.svelte @@ -1,15 +1,16 @@
    From 3a0158f9247526eb788354516d7336b36e2ed9d2 Mon Sep 17 00:00:00 2001 From: Jason Lee Date: Mon, 21 Oct 2024 02:30:31 +0700 Subject: [PATCH 23/31] Better typings --- src/lib/Controller.svelte | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/lib/Controller.svelte b/src/lib/Controller.svelte index e9bb5c6..d079ad3 100644 --- a/src/lib/Controller.svelte +++ b/src/lib/Controller.svelte @@ -7,16 +7,16 @@ import { toast } from './stores.js' /** @type {import('./stores.js').SvelteToastOptions} */ export let item -/** @type {any} */ -let next = item.initial +let next = item.initial || 0 let prev = next let paused = false const progress = tweened(item.initial, { duration: item.duration, easing: linear }) -/** @param {{value:any}|undefined} [detail] */ -function close(detail) { - toast.pop(item.id, detail) +/** @param {CustomEvent} [ev] */ +function close(ev) { + const { value } = ev?.detail || {} + toast.pop(item.id, { value }) } function autoclose() { @@ -32,7 +32,7 @@ function pause() { function resume() { if (paused) { - const d = /** @type {any} */ (item.duration) + const d = item.duration || 0 const duration = d - d * (($progress - prev) / (next - prev)) progress.set(next, { duration }).then(autoclose) paused = false @@ -53,7 +53,7 @@ function unlisten() { } $: if (next !== item.next) { - next = item.next + next = item.next || 0 prev = $progress paused = false progress.set(next).then(autoclose) @@ -70,5 +70,5 @@ onDestroy(unlisten) }} on:mouseleave={resume} > - close(e.detail)} /> +
From ff93f5eb8b94360909014ff0dca445ae5c811262 Mon Sep 17 00:00:00 2001 From: Jason Lee Date: Tue, 22 Oct 2024 15:05:31 +0700 Subject: [PATCH 24/31] Deprecate `class` in favour of spread props --- src/lib/SvelteToast.svelte | 18 ++++++++---------- src/lib/stores.js | 4 ++-- 2 files changed, 10 insertions(+), 12 deletions(-) diff --git a/src/lib/SvelteToast.svelte b/src/lib/SvelteToast.svelte index 43f21da..26f2e23 100644 --- a/src/lib/SvelteToast.svelte +++ b/src/lib/SvelteToast.svelte @@ -10,9 +10,6 @@ import View from './View.svelte' export let options = {} /** @type {string|'default'} - toast container target name */ export let target = 'default' -/** @type {string|undefined} - toast container class */ -let classes = '' -export { classes as class } /** @type {import('./stores.js').SvelteToastOptions} */ const defaults = { @@ -31,8 +28,8 @@ let items = [] let merged /** @type {Object|undefined} */ let theme -/** @type {string|undefined} */ -let _class +/** @type {Object|undefined} */ +let props /** @param {Object} [obj] */ function toStyles(obj) { @@ -40,7 +37,7 @@ function toStyles(obj) { } $: { - ;({ theme, class: _class, ...merged } = { ...defaults, ...options }) + ;({ theme, props, ...merged } = { ...defaults, ...options }) toast._init(target, merged) } $: { @@ -52,14 +49,15 @@ $: { onDestroy(() => toast.pop({ target })) -
    +
      {#each items as item (item.id)}
    • @@ -67,7 +65,7 @@ onDestroy(() => toast.pop({ target }))
    diff --git a/src/lib/stores.js b/src/lib/stores.js index 1c16f58..3a2726b 100644 --- a/src/lib/stores.js +++ b/src/lib/stores.js @@ -34,9 +34,9 @@ import { writable } from 'svelte/store' * @prop {boolean} [dismissable] - allow dismiss with close button * @prop {boolean} [reversed] - display toasts in reverse order * @prop {FlyParams} [intro] - toast intro fly animation settings - * @prop {FlyParams} [outro] - toast outro fade animation settings + * @prop {FlyParams} [outro] - toast outro fly animation settings * @prop {Object} [theme] - css var overrides - * @prop {string} [class] - user-defined classes + * @prop {Object} [props] - spread props onto toast item wrapper * @prop {SvelteComponent} [view] - toast view Svelte component * @prop {any} [_resolve] */ From e5b66b9e9a77ade847f096a7a2672e62dabc5e5d Mon Sep 17 00:00:00 2001 From: Jason Lee Date: Wed, 23 Oct 2024 17:50:57 +0700 Subject: [PATCH 25/31] Use `output` element for implicit `role="status"` --- src/lib/Controller.svelte | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/lib/Controller.svelte b/src/lib/Controller.svelte index d079ad3..000f301 100644 --- a/src/lib/Controller.svelte +++ b/src/lib/Controller.svelte @@ -63,12 +63,11 @@ onMount(listen) onDestroy(unlisten) -
    { if (['hover', 'both'].includes(item.pausable || '')) pause() }} on:mouseleave={resume} > -
    + From 62fe355b9c2e954787df3fcf4e6fe21191846969 Mon Sep 17 00:00:00 2001 From: Jason Lee Date: Wed, 23 Oct 2024 19:33:33 +0700 Subject: [PATCH 26/31] Use CSS nesting and remove fixed class names --- src/lib/SvelteToast.svelte | 6 +- src/lib/View.svelte | 115 ++++++++++++++++++------------------- 2 files changed, 58 insertions(+), 63 deletions(-) diff --git a/src/lib/SvelteToast.svelte b/src/lib/SvelteToast.svelte index 26f2e23..fa78521 100644 --- a/src/lib/SvelteToast.svelte +++ b/src/lib/SvelteToast.svelte @@ -77,8 +77,8 @@ onDestroy(() => toast.pop({ target })) list-style-type: none; pointer-events: none; will-change: contents; -} -:where(ul > li) { - pointer-events: auto; + & li { + pointer-events: auto; + } } diff --git a/src/lib/View.svelte b/src/lib/View.svelte index aa06849..ec0db1c 100644 --- a/src/lib/View.svelte +++ b/src/lib/View.svelte @@ -11,30 +11,18 @@ function dismiss() { } -
    -
    - {#if item.unsafe} - {@html item.msg} - {:else} - {item.msg} - {/if} -
    +
    + {#if item.unsafe}{@html item.msg}{:else}{item.msg}{/if} {#if item.dismissable} -
    { - if (ev instanceof KeyboardEvent && ['Enter', ' '].includes(ev.key)) dismiss() - }} - /> +
    From e1993d2bb5920dffbabe317d841a1015cf8dd29f Mon Sep 17 00:00:00 2001 From: Jason Lee Date: Thu, 24 Oct 2024 20:07:01 +0700 Subject: [PATCH 27/31] Revert deprecated `class` --- src/lib/SvelteToast.svelte | 14 ++++++++------ src/lib/stores.js | 5 +++-- 2 files changed, 11 insertions(+), 8 deletions(-) diff --git a/src/lib/SvelteToast.svelte b/src/lib/SvelteToast.svelte index fa78521..12f6fa2 100644 --- a/src/lib/SvelteToast.svelte +++ b/src/lib/SvelteToast.svelte @@ -10,6 +10,9 @@ import View from './View.svelte' export let options = {} /** @type {string|'default'} - toast container target name */ export let target = 'default' +/** @type {string|undefined} - toast container class */ +let classes = '' +export { classes as class } /** @type {import('./stores.js').SvelteToastOptions} */ const defaults = { @@ -28,8 +31,8 @@ let items = [] let merged /** @type {Object|undefined} */ let theme -/** @type {Object|undefined} */ -let props +/** @type {string|undefined} */ +let _class /** @param {Object} [obj] */ function toStyles(obj) { @@ -37,7 +40,7 @@ function toStyles(obj) { } $: { - ;({ theme, props, ...merged } = { ...defaults, ...options }) + ;({ theme, class: _class, ...merged } = { ...defaults, ...options }) toast._init(target, merged) } $: { @@ -49,15 +52,14 @@ $: { onDestroy(() => toast.pop({ target })) -
      +
        {#each items as item (item.id)}
      • diff --git a/src/lib/stores.js b/src/lib/stores.js index 3a2726b..f9943ae 100644 --- a/src/lib/stores.js +++ b/src/lib/stores.js @@ -36,9 +36,10 @@ import { writable } from 'svelte/store' * @prop {FlyParams} [intro] - toast intro fly animation settings * @prop {FlyParams} [outro] - toast outro fly animation settings * @prop {Object} [theme] - css var overrides - * @prop {Object} [props] - spread props onto toast item wrapper - * @prop {SvelteComponent} [view] - toast view Svelte component + * @prop {string} [class] - class string applied to toast item + * @prop {SvelteComponent} [view] - Svelte component used as toast view * @prop {any} [_resolve] + * @prop {any} [_props] */ function createToast() { From 7044484050208c8fbbeba701ccfb0e0e9f82f160 Mon Sep 17 00:00:00 2001 From: Jason Lee Date: Fri, 25 Oct 2024 15:00:17 +0700 Subject: [PATCH 28/31] Revert `pointer-events` behaviour --- src/lib/SvelteToast.svelte | 3 --- src/lib/View.svelte | 52 ++++++++++++++++++++------------------ 2 files changed, 27 insertions(+), 28 deletions(-) diff --git a/src/lib/SvelteToast.svelte b/src/lib/SvelteToast.svelte index 12f6fa2..5003bcb 100644 --- a/src/lib/SvelteToast.svelte +++ b/src/lib/SvelteToast.svelte @@ -79,8 +79,5 @@ onDestroy(() => toast.pop({ target })) list-style-type: none; pointer-events: none; will-change: contents; - & li { - pointer-events: auto; - } } diff --git a/src/lib/View.svelte b/src/lib/View.svelte index ec0db1c..633588b 100644 --- a/src/lib/View.svelte +++ b/src/lib/View.svelte @@ -12,13 +12,13 @@ function dismiss() {
        - {#if item.unsafe}{@html item.msg}{:else}{item.msg}{/if} {#if item.dismissable} -
        From 6cdbfcc99c4397976b588e6fd16febb9e98e3d16 Mon Sep 17 00:00:00 2001 From: Jason Lee Date: Sat, 26 Oct 2024 16:28:01 +0700 Subject: [PATCH 29/31] Fix `pausable` pointer events --- src/lib/View.svelte | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lib/View.svelte b/src/lib/View.svelte index 633588b..135efe4 100644 --- a/src/lib/View.svelte +++ b/src/lib/View.svelte @@ -12,7 +12,7 @@ function dismiss() {
        - {#if item.unsafe}{@html item.msg}{:else}{item.msg}{/if} {#if item.dismissable} From 60014c7ac108c9d15c4aab70b294a175eef27333 Mon Sep 17 00:00:00 2001 From: Jason Lee Date: Sun, 27 Oct 2024 21:13:45 +0700 Subject: [PATCH 30/31] Refactor object coercion --- src/lib/stores.js | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/src/lib/stores.js b/src/lib/stores.js index f9943ae..5b32ae4 100644 --- a/src/lib/stores.js +++ b/src/lib/stores.js @@ -17,8 +17,8 @@ import { writable } from 'svelte/store' /** * @typedef {Object} SvelteToastPop * @prop {number} [id] - remove toast with specified id - * @prop {any} [value] - onpop resolve value * @prop {string} [target] - remove all toasts from target container + * @prop {any} [value] - onpop resolve value */ /** @@ -38,8 +38,8 @@ import { writable } from 'svelte/store' * @prop {Object} [theme] - css var overrides * @prop {string} [class] - class string applied to toast item * @prop {SvelteComponent} [view] - Svelte component used as toast view - * @prop {any} [_resolve] - * @prop {any} [_props] + * @prop {Object} [_props] + * @prop {(value:any)=>void} [_resolve] */ function createToast() { @@ -61,30 +61,29 @@ function createToast() { * @returns {SvelteToastPushed} */ function push(msg, opts) { - const param = typeof msg === 'object' ? msg : { ...opts, msg } - const target = param.target || 'default' - const base = defaults[target] || {} + const param = { target: 'default', ...(typeof msg === 'object' ? msg : { msg }), ...opts } const id = ++count + /** @type {(value:any)=>void} */ let _resolve const onpop = new Promise((resolve) => (_resolve = resolve)) - const item = { ...base, ...param, target, id, _resolve } - update((n) => [...n, item]) + update((n) => [...n, { ...defaults[param.target], ...param, id, _resolve }]) return { id, onpop } } /** * Remove toast(s) * - toast.pop() // remove the lastest toast - * - toast.pop(0) // remove all toasts * - toast.pop(id) // remove toast with specified id * - toast.pop({ target: 'foo' }) // remove all toasts from target `foo` + * - toast.pop(0) // remove all toasts + * * @param {number|SvelteToastPop} [id] * @param {SvelteToastPop} [opts] */ function pop(id, opts) { update((n) => { if (!n.length) return n - const { id: _id, target, value } = typeof id === 'object' ? id : { ...opts, id } + const { id: _id, target, value } = { ...(typeof id === 'object' ? id : { id }), ...opts } const resolve = (/** @type {any[]} */ items) => items.forEach((i) => i._resolve(value)) const val = _id || target if (val) { @@ -103,7 +102,7 @@ function createToast() { * @param {SvelteToastOptions} [opts] */ function set(id, opts) { - const param = typeof id === 'object' ? id : { ...opts, id } + const param = { ...(typeof id === 'object' ? id : { id }), ...opts } update((n) => { const idx = n.findIndex((i) => i.id === param.id) if (idx > -1) { From 16c65cdd12f32894637f3a7d92509e7d5e4d1955 Mon Sep 17 00:00:00 2001 From: Jason Lee Date: Mon, 28 Oct 2024 22:38:22 +0700 Subject: [PATCH 31/31] Refactor CSS --- src/lib/View.svelte | 35 ++++++++++++++++++----------------- 1 file changed, 18 insertions(+), 17 deletions(-) diff --git a/src/lib/View.svelte b/src/lib/View.svelte index 135efe4..2405ba4 100644 --- a/src/lib/View.svelte +++ b/src/lib/View.svelte @@ -11,14 +11,14 @@ function dismiss() { } -
        +
        {#if item.unsafe}{@html item.msg}{:else}{item.msg}{/if} {#if item.dismissable} -