import { defineComponent, h, provide, ref, nextTick } from "vue";
import { cx, iconNode, normalizeVariant } from "../utils.js";
import { toastKey } from "../composables/toast-context.js";
const iconByVariant = {
info: "ph-info",
success: "ph-check-circle",
warning: "ph-warning",
danger: "ph-warning-octagon",
error: "ph-warning-octagon",
primary: "ph-info",
secondary: "ph-info"
};
export default defineComponent({
name: "GnToastProvider",
props: {
lifetime: { type: Number, default: 4000 }
},
setup(props, { slots, expose }) {
const toast = ref(null);
const closing = ref(false);
const showing = ref(false);
let timer = null;
let closeTimer = null;
const dismiss = () => {
window.clearTimeout(closeTimer);
closing.value = true;
showing.value = false;
closeTimer = window.setTimeout(() => {
toast.value = null;
closing.value = false;
window.clearTimeout(timer);
timer = null;
}, 300);
};
const close = () => {
window.clearTimeout(closeTimer);
window.clearTimeout(timer);
closing.value = false;
showing.value = false;
toast.value = null;
};
const show = options => {
window.clearTimeout(closeTimer);
closing.value = false;
showing.value = false;
const variant = normalizeVariant(options.variant || options.type || "info", "info");
toast.value = {
id: Date.now(),
variant: variant === "error" ? "danger" : variant,
title: options.title || "",
text: options.text || options.message || "",
icon: options.icon || iconByVariant[variant] || iconByVariant.info
};
window.clearTimeout(timer);
if(options.lifetime !== 0) {
timer = window.setTimeout(dismiss, options.lifetime || props.lifetime);
}
nextTick(() => {
requestAnimationFrame(() => {
showing.value = true;
});
});
};
const api = {
show,
close,
info: options => show({ ...options, variant: "info" }),
success: options => show({ ...options, variant: "success" }),
warning: options => show({ ...options, variant: "warning" }),
danger: options => show({ ...options, variant: "danger" }),
error: options => show({ ...options, variant: "danger" })
};
provide(toastKey, api);
expose(api);
const toastClass = () => {
if (closing.value) return "a-hide";
if (showing.value) return "a-show";
return "";
};
return () => [
slots.default?.(),
toast.value && h("div", {
class: cx("toast", toastClass(), `toast-${toast.value.variant}`),
role: "alert"
}, [
h("div", { class: "toast-content" }, [
h("h4", { class: "toast-title" }, [
iconNode(toast.value.icon),
toast.value.title
]),
h("p", { class: "toast-text" }, toast.value.text)
]),
h("button", {
class: "btn-icon toast-close",
type: "button",
"aria-label": "Close",
onClick: dismiss
}, [iconNode("ph-x")])
])
];
}
});