DuyTa's picture
Upload folder using huggingface_hub
bc20498 verified
import { usePortal } from '../../internal/actions/index.js';
import { addMeltEventListener, makeElement, createElHelpers, executeCallbacks, generateId, isTouch, kbd, noop, toWritableStores, } from '../../internal/helpers/index.js';
import { derived, readonly, writable } from 'svelte/store';
const { name } = createElHelpers('toast');
const defaults = {
closeDelay: 5000,
type: 'foreground',
};
export function createToaster(props) {
const withDefaults = { ...defaults, ...props };
const options = toWritableStores(withDefaults);
const { closeDelay, type } = options;
const toastsMap = writable(new Map());
const addToast = (props) => {
const propsWithDefaults = {
closeDelay: closeDelay.get(),
type: type.get(),
...props,
};
const ids = {
content: generateId(),
title: generateId(),
description: generateId(),
};
const timeout = propsWithDefaults.closeDelay === 0
? null
: window.setTimeout(() => {
removeToast(ids.content);
}, propsWithDefaults.closeDelay);
const getPercentage = () => {
const { createdAt, pauseDuration, closeDelay, pausedAt } = toast;
if (closeDelay === 0)
return 0;
if (pausedAt) {
return (100 * (pausedAt - createdAt - pauseDuration)) / closeDelay;
}
else {
const now = performance.now();
return (100 * (now - createdAt - pauseDuration)) / closeDelay;
}
};
const toast = {
id: ids.content,
ids,
...propsWithDefaults,
timeout,
createdAt: performance.now(),
pauseDuration: 0,
getPercentage,
};
toastsMap.update((currentMap) => {
currentMap.set(ids.content, toast);
return new Map(currentMap);
});
return toast;
};
const removeToast = (id) => {
toastsMap.update((currentMap) => {
currentMap.delete(id);
return new Map(currentMap);
});
};
const updateToast = (id, data) => {
toastsMap.update((currentMap) => {
const toast = currentMap.get(id);
if (!toast)
return currentMap;
currentMap.set(id, { ...toast, data });
return new Map(currentMap);
});
};
const content = makeElement(name('content'), {
stores: toastsMap,
returned: ($toasts) => {
return (id) => {
const t = $toasts.get(id);
if (!t)
return null;
const { ...toast } = t;
return {
id,
role: 'alert',
'aria-describedby': toast.ids.description,
'aria-labelledby': toast.ids.title,
'aria-live': toast.type === 'foreground' ? 'assertive' : 'polite',
tabindex: -1,
};
};
},
action: (node) => {
let destroy = noop;
destroy = executeCallbacks(addMeltEventListener(node, 'pointerenter', (e) => {
if (isTouch(e))
return;
toastsMap.update((currentMap) => {
const currentToast = currentMap.get(node.id);
if (!currentToast || currentToast.closeDelay === 0)
return currentMap;
if (currentToast.timeout !== null) {
window.clearTimeout(currentToast.timeout);
}
currentToast.pausedAt = performance.now();
return new Map(currentMap);
});
}), addMeltEventListener(node, 'pointerleave', (e) => {
if (isTouch(e))
return;
toastsMap.update((currentMap) => {
const currentToast = currentMap.get(node.id);
if (!currentToast || currentToast.closeDelay === 0)
return currentMap;
const pausedAt = currentToast.pausedAt ?? currentToast.createdAt;
const elapsed = pausedAt - currentToast.createdAt - currentToast.pauseDuration;
const remaining = currentToast.closeDelay - elapsed;
currentToast.timeout = window.setTimeout(() => {
removeToast(node.id);
}, remaining);
currentToast.pauseDuration += performance.now() - pausedAt;
currentToast.pausedAt = undefined;
return new Map(currentMap);
});
}), () => {
removeToast(node.id);
});
return {
destroy,
};
},
});
const title = makeElement(name('title'), {
stores: toastsMap,
returned: ($toasts) => {
return (id) => {
const toast = $toasts.get(id);
if (!toast)
return null;
return {
id: toast.ids.title,
};
};
},
});
const description = makeElement(name('description'), {
stores: toastsMap,
returned: ($toasts) => {
return (id) => {
const toast = $toasts.get(id);
if (!toast)
return null;
return {
id: toast.ids.description,
};
};
},
});
const close = makeElement(name('close'), {
returned: () => {
return (id) => ({
type: 'button',
'data-id': id,
});
},
action: (node) => {
function handleClose() {
if (!node.dataset.id)
return;
removeToast(node.dataset.id);
}
const unsub = executeCallbacks(addMeltEventListener(node, 'click', () => {
handleClose();
}), addMeltEventListener(node, 'keydown', (e) => {
if (e.key !== kbd.ENTER && e.key !== kbd.SPACE)
return;
e.preventDefault();
handleClose();
}));
return {
destroy: unsub,
};
},
});
const toasts = derived(toastsMap, ($toastsMap) => {
return Array.from($toastsMap.values());
});
return {
elements: {
content,
title,
description,
close,
},
states: {
toasts: readonly(toasts),
},
helpers: {
addToast,
removeToast,
updateToast,
},
actions: {
portal: usePortal,
},
options,
};
}