Skip to content

Commit

Permalink
Pesky jsdoc type coercions are pesky
Browse files Browse the repository at this point in the history
  • Loading branch information
zerodevx committed Mar 25, 2023
1 parent 76a52f4 commit 2d1ccf1
Show file tree
Hide file tree
Showing 5 changed files with 32 additions and 21 deletions.
6 changes: 4 additions & 2 deletions src/lib/SvelteToast.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,12 @@ export let options = {}
/** @type {(string|'default')} */
export let target = 'default'
/** @type {import('./stores').SvelteToastOptions[]} */
let items = []
/** @param {Object<string,string|number>} [theme] */
function getCss(theme) {
return Object.keys(theme).reduce((a, c) => `${a}${c}:${theme[c]};`, '')
return theme ? Object.keys(theme).reduce((a, c) => `${a}${c}:${theme[c]};`, '') : undefined
}
$: toast._init(target, options)
Expand All @@ -23,7 +25,7 @@ $: items = $toast.filter((i) => i.target === target)
<ul class="_toastContainer">
{#each items as item (item.id)}
<li
class={item.classes.join(' ')}
class={item.classes?.join(' ')}
in:fly={item.intro}
out:fade
animate:flip={{ duration: 200 }}
Expand Down
6 changes: 5 additions & 1 deletion src/lib/ToastItem.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,12 @@ import { toast } from './stores'
/** @type {import('./stores').SvelteToastOptions} */
export let item
/** @type {any} */
let next = item.initial
let prev = next
let paused = false
let cprops = {}
/** @type {any} */
let unlisten
const progress = tweened(item.initial, { duration: item.duration, easing: linear })
Expand All @@ -32,13 +34,14 @@ function pause() {
function resume() {
if (paused) {
const d = item.duration
const d = /** @type {any} */ (item.duration)
const duration = d - d * (($progress - prev) / (next - prev))
progress.set(next, { duration }).then(autoclose)
paused = false
}
}
/** @param {any} prop */
function check(prop, kind = 'undefined') {
return typeof prop === kind
}
Expand Down Expand Up @@ -73,6 +76,7 @@ onMount(listen)
onDestroy(() => {
if (check(item.onpop, 'function')) {
// @ts-ignore
item.onpop(item.id)
}
unlisten && unlisten()
Expand Down
19 changes: 10 additions & 9 deletions src/lib/stores.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import { writable } from 'svelte/store'
/**
* @typedef {Object} SvelteToastCustomComponent
* @property {SvelteComponent} src - custom Svelte Component
* @property {Object.<string, *>} [props] - props to pass into custom component
* @property {Object<string,any>} [props] - props to pass into custom component
* @property {string} [sendIdTo] - forward toast id to prop name
*/

Expand All @@ -32,7 +32,7 @@ import { writable } from 'svelte/store'
* @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.<string, string|number>} [theme] - css var overrides
* @property {Object<string,string|number>} [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
Expand All @@ -50,13 +50,13 @@ const defaults = {
intro: { x: 256 }
}

const createToast = () => {
const { subscribe, update } = writable([])
/** @type {Object.<string, SvelteToastOptions>} */
function createToast() {
const { subscribe, update } = writable(new Array())
/** @type {Object<string,SvelteToastOptions>} */
const options = {}
let count = 0

/** @param {*} obj */
/** @param {any} obj */
function _obj(obj) {
return obj instanceof Object
}
Expand Down Expand Up @@ -96,14 +96,15 @@ const createToast = () => {
* - toast.pop(0) // remove all toasts
* - toast.pop(id) // removes the toast with specified `id`
* - toast.pop({ target: 'foo' }) // remove all toasts from target `foo`
* @param {(number|Object.<'target', string>)} [id]
* @param {(number|Object<'target',string>)} [id]
*/
function pop(id) {
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((i) => i.target !== id.target)
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)
})
Expand All @@ -115,7 +116,7 @@ const createToast = () => {
* @param {SvelteToastOptions} [opts]
*/
function set(id, opts) {
/** @type {object} */
/** @type {any} */
const param = _obj(id) ? id : { ...opts, id }
update((n) => {
const idx = n.findIndex((i) => i.id === param.id)
Expand Down
16 changes: 10 additions & 6 deletions src/routes/+page.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,12 @@ if (browser) window.toast = toast
const version = PUBLIC_VERSION
let selected
let selected = ''
let code = '// Tap a button below'
let colors = false
let bottom = false
let options = {}
let formatted
let formatted = ''
const buttons = [
{
Expand Down Expand Up @@ -133,7 +133,8 @@ toast.set(id, { msg: 'Just a bit more', next: 0.8 })
await sleep(2000)
toast.set(id, { next: 1 })`,
run: async () => {
const sleep = (t) => new Promise((resolve) => setTimeout(resolve, t))
const sleep = (/** @type {number|undefined} */ t) =>
new Promise((resolve) => setTimeout(resolve, t))
const id = toast.push('Loading, please wait...', {
duration: 300,
initial: 0,
Expand Down Expand Up @@ -354,13 +355,15 @@ toast.pop(0)`,
}
]
/** @param {{ name: any; code: any; run: any; }} btn */
function clicked(btn) {
selected = btn.name
code = btn.code
btn.run()
if (browser && !dev) window.gtag('event', 'toast', { event_label: btn.name })
}
// @ts-ignore
$: formatted = Prism.highlight(code, Prism.languages.javascript, 'javascript')
</script>
Expand All @@ -385,9 +388,10 @@ $: formatted = Prism.highlight(code, Prism.languages.javascript, 'javascript')
</div>
<p class="max-w-2xl mx-auto text-center mb-6">
Simple elegant toast notifications for modern web frontends in very little lines of code.
Because a demo helps better than a thousand API docs, so here it is. Use in Vanilla JS <span
class="font-mono text-sm">(8kB gzipped)</span
> or as a Svelte component.
Because a demo helps better than a thousand API docs, so here it is. Use in Vanilla JS (<strong
>8kB</strong
>
gzipped) or as a Svelte component.
</p>
<div class="mockup-code h-80 mb-4 text-sm overflow-auto">
<pre><code class="language-javascript">{@html formatted}</code></pre>
Expand Down
6 changes: 3 additions & 3 deletions src/routes/Dummy.svelte
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
<script>
import { toast } from '$lib/index.js'
export let toastId
export let title
export let toastId = 0
export let title = ''
const clicked = (ok) => {
const clicked = (/** @type {boolean} */ ok) => {
toast.pop(toastId)
toast.push({
msg: ok ? 'Accepted!' : 'Declined!',
Expand Down

0 comments on commit 2d1ccf1

Please sign in to comment.