@shopware-ag/meteor-component-library
Version:
The meteor component library is a Vue component library developed by Shopware. It is based on the [Meteor Design System](https://shopware.design/).
324 lines (323 loc) • 11.4 kB
JavaScript
import '../mt-snackbar-notification.css';
;
const vue = require("vue");
const mtIcon_vue_vue_type_style_index_0_lang = require("../mt-icon.vue_vue_type_style_index_0_lang-0a28c7b6.js");
const MtText = require("./MtText.js");
const MtLink = require("./MtLink.js");
const MtLoader = require("./MtLoader.js");
const _pluginVue_exportHelper = require("../_plugin-vue_export-helper-9c783a34.js");
const _hoisted_1 = ["role", "aria-live", "data-mounted", "data-removed"];
const _hoisted_2 = { class: "mt-snackbar-notification__content" };
const _hoisted_3 = { class: "mt-snackbar-notification__text-content" };
const _hoisted_4 = {
key: 0,
class: "mt-snackbar-notification__symbol-container"
};
const _hoisted_5 = {
key: 1,
class: "mt-snackbar-notification__progress"
};
const _sfc_main = /* @__PURE__ */ vue.defineComponent({
__name: "mt-snackbar-notification",
props: {
snackbar: {
type: Object,
required: true
},
isHovered: {
type: Boolean,
default: false
},
heights: {
type: Array,
default: () => []
}
},
emits: ["remove-snackbar", "update:height"],
setup(__props, { emit: __emit }) {
const emit = __emit;
const props = __props;
const mounted = vue.ref(false);
const removed = vue.ref(false);
const offsetBeforeRemove = vue.ref(0);
const classes = vue.computed(() => {
return {
"mt-snackbar-notification--success": snackbar.value.variant === "success" || isUploadComplete.value,
"mt-snackbar-notification--error": snackbar.value.variant === "error" || isUploadError.value,
"mt-snackbar-notification--progress": snackbar.value.variant === "progress"
};
});
const heightIndex = vue.computed(() => {
const index = props.heights.findIndex((height) => height.snackbarId === props.snackbar.id);
return index >= 0 ? index : 0;
});
const toastsHeightBefore = vue.computed(() => {
return props.heights.reduce((prev, curr, reducerIndex) => {
if (reducerIndex >= heightIndex.value) {
return prev;
}
return prev + curr.height;
}, 0);
});
const offset = vue.computed(() => heightIndex.value * 16 + toastsHeightBefore.value || 0);
const progressPercentage = vue.computed(() => {
return `(${snackbar.value.progressPercentage || 0}%)`;
});
const isUploadComplete = vue.computed(() => {
return snackbar.value.variant === "progress" && snackbar.value.uploadState === "success";
});
const isUploadError = vue.computed(() => {
return snackbar.value.variant === "progress" && snackbar.value.uploadState === "error";
});
const isUploading = vue.computed(() => {
return snackbar.value.variant === "progress" && !snackbar.value.uploadState;
});
const displayMessage = vue.computed(() => {
if (isUploadComplete.value) {
return snackbar.value.successMessage || "Upload completed";
}
if (isUploadError.value) {
return snackbar.value.errorMessage || "Upload failed";
}
return snackbar.value.message;
});
const icon = vue.computed(() => {
switch (snackbar.value.variant) {
case "error":
return "solid-exclamation-circle";
case "success":
return "solid-check-circle";
case "progress":
if (isUploadComplete.value) {
return "solid-check-circle";
}
if (isUploadError.value) {
return "solid-exclamation-circle";
}
return void 0;
default:
return void 0;
}
});
const role = vue.computed(() => {
switch (snackbar.value.variant) {
case "error":
return "alert";
case "success":
return "log";
default:
return "log";
}
});
const ariaLive = vue.computed(() => {
switch (snackbar.value.variant) {
case "error":
case "warning":
return "assertive";
case "success":
case "progress":
default:
return "polite";
}
});
const { snackbar, isHovered } = vue.toRefs(props);
const snackbarEl = vue.ref(null);
const timeoutId = vue.ref(void 0);
const successTimeoutId = vue.ref(void 0);
const remainingTimeOut = vue.ref(snackbar.value.duration || 5e3);
const pausedAt = vue.ref(null);
const isPaused = vue.ref(false);
const successPausedAt = vue.ref(null);
const isSuccessPaused = vue.ref(false);
vue.watch(mounted, () => {
if (!mounted.value || !snackbarEl.value)
return;
const snackbarNode = snackbarEl.value;
const originalHeight = snackbarNode.style.height;
snackbarNode.style.height = "auto";
const newHeight = snackbarNode.getBoundingClientRect().height;
snackbarNode.style.height = originalHeight;
emit("update:height", {
snackbarId: props.snackbar.id,
height: newHeight
});
});
vue.watch(isHovered, (newIsHovered) => {
if (newIsHovered) {
pauseTimer();
pauseSuccessTimer();
} else {
resumeTimer();
resumeSuccessTimer();
}
});
vue.watch(
() => snackbar.value.duration,
(newDuration) => {
if (snackbar.value.variant === "progress") {
return;
}
if (newDuration === 0) {
if (timeoutId.value) {
window.clearTimeout(timeoutId.value);
timeoutId.value = void 0;
remainingTimeOut.value = newDuration || 5e3;
}
return;
}
if (!isPaused.value) {
timeoutId.value = window.setTimeout(() => {
onRemoveSnackbar();
}, remainingTimeOut.value);
}
},
{ immediate: true }
);
vue.watch(
() => snackbar.value.uploadState,
(newUploadState) => {
if (snackbar.value.variant === "progress" && (newUploadState === "success" || newUploadState === "error")) {
if (!isSuccessPaused.value) {
successTimeoutId.value = window.setTimeout(() => {
onRemoveSnackbar();
}, 2e3);
}
}
}
);
function pauseTimer() {
if (timeoutId.value && !isPaused.value) {
window.clearTimeout(timeoutId.value);
timeoutId.value = void 0;
pausedAt.value = Date.now();
isPaused.value = true;
}
}
function resumeTimer() {
if (isPaused.value && pausedAt.value) {
const elapsed = Date.now() - pausedAt.value;
const newRemainingTime = Math.max(0, remainingTimeOut.value - elapsed);
remainingTimeOut.value = newRemainingTime;
if (newRemainingTime > 0) {
timeoutId.value = window.setTimeout(() => {
onRemoveSnackbar();
}, newRemainingTime);
} else {
onRemoveSnackbar();
}
pausedAt.value = null;
isPaused.value = false;
}
}
function pauseSuccessTimer() {
if (successTimeoutId.value && !isSuccessPaused.value) {
window.clearTimeout(successTimeoutId.value);
successTimeoutId.value = void 0;
successPausedAt.value = Date.now();
isSuccessPaused.value = true;
}
}
function resumeSuccessTimer() {
if (isSuccessPaused.value && successPausedAt.value) {
const elapsed = Date.now() - successPausedAt.value;
const newRemainingTime = Math.max(0, 2e3 - elapsed);
if (newRemainingTime > 0) {
successTimeoutId.value = window.setTimeout(() => {
onRemoveSnackbar();
}, newRemainingTime);
} else {
onRemoveSnackbar();
}
successPausedAt.value = null;
isSuccessPaused.value = false;
}
}
function onRemoveSnackbar() {
removed.value = true;
offsetBeforeRemove.value = offset.value;
setTimeout(() => {
emit("remove-snackbar", props.snackbar);
}, 500);
}
vue.onMounted(() => {
mounted.value = true;
if (snackbarEl.value) {
snackbarEl.value.focus();
}
});
vue.onBeforeUnmount(() => {
if (timeoutId.value) {
window.clearTimeout(timeoutId.value);
}
if (successTimeoutId.value) {
window.clearTimeout(successTimeoutId.value);
}
isPaused.value = false;
isSuccessPaused.value = false;
pausedAt.value = null;
successPausedAt.value = null;
});
return (_ctx, _cache) => {
return vue.openBlock(), vue.createElementBlock("div", {
ref_key: "snackbarEl",
ref: snackbarEl,
class: vue.normalizeClass(["mt-snackbar-notification", classes.value]),
role: role.value,
"aria-live": ariaLive.value,
tabindex: "0",
"data-mounted": mounted.value,
"data-removed": removed.value,
style: vue.normalizeStyle({
"--offset": `${removed.value ? offsetBeforeRemove.value : offset.value}px`
})
}, [
vue.createElementVNode("div", _hoisted_2, [
vue.createElementVNode("div", _hoisted_3, [
icon.value || vue.unref(snackbar).variant === "progress" ? (vue.openBlock(), vue.createElementBlock("div", _hoisted_4, [
isUploading.value ? (vue.openBlock(), vue.createBlock(MtLoader, {
key: 0,
class: "mt-snackbar-notification__loader",
size: "16px"
})) : icon.value ? (vue.openBlock(), vue.createBlock(mtIcon_vue_vue_type_style_index_0_lang._sfc_main, {
key: 1,
class: "mt-snackbar-notification__icon",
name: icon.value,
size: "16px"
}, null, 8, ["name"])) : vue.createCommentVNode("", true)
])) : vue.createCommentVNode("", true),
vue.createVNode(MtText, {
class: "mt-snackbar-notification__message",
color: "color-text-primary-default",
weight: "medium",
size: "xs"
}, {
default: vue.withCtx(() => [
vue.createTextVNode(vue.toDisplayString(displayMessage.value), 1)
]),
_: 1
}),
isUploading.value ? (vue.openBlock(), vue.createElementBlock("div", _hoisted_5, [
vue.createElementVNode("span", null, vue.toDisplayString(progressPercentage.value), 1)
])) : vue.createCommentVNode("", true)
]),
vue.unref(snackbar).link ? (vue.openBlock(), vue.createBlock(MtLink, {
key: 0,
class: "mt-snackbar-notification__link",
as: "a",
variant: "primary",
to: vue.unref(snackbar).link.url
}, {
default: vue.withCtx(() => [
vue.createTextVNode(vue.toDisplayString(vue.unref(snackbar).link.text), 1)
]),
_: 1
}, 8, ["to"])) : vue.createCommentVNode("", true)
])
], 14, _hoisted_1);
};
}
});
const mtSnackbarNotification_vue_vue_type_style_index_0_scoped_fd922274_lang = "";
const MtSnackbarNotification = /* @__PURE__ */ _pluginVue_exportHelper._export_sfc(_sfc_main, [["__scopeId", "data-v-fd922274"]]);
module.exports = MtSnackbarNotification;
//# sourceMappingURL=MtSnackbarNotification.js.map