From 7445eb582cc9b6769ae3c5fc224ecc4e2f5b3ae2 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=D0=94=D0=BC=D0=B8=D1=82=D1=80=D0=B8=D0=B9=20=D0=9C=D0=B0?=
 =?UTF-8?q?=D0=BB=D1=8E=D0=B3=D0=B8=D0=BD?= <d.malygin@iqdev.digital>
Date: Tue, 11 Feb 2025 21:28:35 +0500
Subject: [PATCH] fix: trying to fix bugs in 'Toast'

---
 src/Playground.vue             |  2 +-
 src/components/Toast/Toast.vue | 78 ++++++++++++++++++----------------
 2 files changed, 42 insertions(+), 38 deletions(-)

diff --git a/src/Playground.vue b/src/Playground.vue
index 1135975..922f5f9 100644
--- a/src/Playground.vue
+++ b/src/Playground.vue
@@ -197,7 +197,7 @@ const openDrawer = () => (visibleDrawer.value = true);
     "
   />
   <Button label="Open toast" @click="toast2 = true" />
-  <Toast v-model="toast" type="success" position="top" width="500px" />
+  <Toast v-model="toast" static type="success" position="top" width="500px" />
   <Toast v-model="toast4" type="info" position="top" width="500px" />
   <Toast v-model="toast3" type="warn" position="top" width="500px" />
   <Toast v-model="toast2" type="error" position="top" width="500px" />
diff --git a/src/components/Toast/Toast.vue b/src/components/Toast/Toast.vue
index b7850eb..67a6509 100644
--- a/src/components/Toast/Toast.vue
+++ b/src/components/Toast/Toast.vue
@@ -38,17 +38,13 @@ const typeToIcon: Record<TToastType, string> = {
 
 const active = defineModel() as Ref<boolean>;
 
-let toastsContainer = document.querySelector(`.toasts-container.${props.position}`);
+let toastsContainer: HTMLElement = document.querySelector(`.toasts-container.${props.position}`)!;
 
-const toast = ref();
-watch([toast, () => props.static], () => {
-  console.log('watch 2');
-  if (toast.value && !props.static) {
+const toast = ref<HTMLElement>() as Ref<HTMLElement>;
+watch([toast], () => {
+  if (toast.value) {
     toastsContainer?.appendChild(toast.value);
   }
-  if (props.static) {
-    toastsContainer?.removeChild(toast.value);
-  }
 });
 
 const themeColor = computed<TThemeColor>(() => props.theme ?? typeToTheme[props.type]);
@@ -77,7 +73,7 @@ const iconSize = computed(() => fontSize.value.slice(0, -2));
 const textMargin = computed(() => {
   return +iconSize.value + +gap.value.slice(0, -2) + 'px';
 });
-const positionParts = computed(() => {
+const positionParts = computed<string[]>(() => {
   const result = [];
   if (props.position.length < 7) return [props.position];
 
@@ -89,17 +85,17 @@ const positionParts = computed(() => {
 
   return result;
 });
+const topOrBottom = computed(() => props.position[0]);
 const styles = computed(() => {
   if (props.static) return '';
   if (positionParts.value.length === 1) {
     const position = positionParts.value[0];
-    if (position === 'left' || position === 'right')
-      return `${position}: -100%; top: 50%; transform: translateY(-50%);`;
+    // if (position === 'left' || position === 'right')
+    //   return `${position}: -100%; top: 50%; transform: translateY(-50%);`;
     return `${position}: -100%; left: 50%; transform: translateX(-50%);`;
   }
-  return `${positionParts.value[0]}: -100%; ${positionParts.value[1]}: 20px`;
+  return `${positionParts.value[0]}: -100%; ${positionParts.value[1]}: 20px;`;
 });
-
 const initContainer = () => {
   if (!toastsContainer) {
     toastsContainer = document.createElement('div');
@@ -108,7 +104,7 @@ const initContainer = () => {
     toastsContainer.style = `
     position: fixed;
     display: flex;
-    flex-direction: column;
+    flex-direction: ${positionParts.value.find((i) => i === 'bottom') ? 'column-reverse' : 'column'};
     gap: 20px;
     transition: all 0.4s ease-in-out;
     ${styles.value}
@@ -119,27 +115,12 @@ const initContainer = () => {
 watch(
   () => props.position,
   () => {
-    console.log('watch 1');
-
     initContainer();
   },
   {
     immediate: true,
   },
 );
-// const activeStyles = computed(() => {
-//   const activeToasts = document.querySelectorAll(`.toast-container.${props.position}.active`);
-//   let activeToastsHeight = 0;
-//   for (const toast of activeToasts) {
-//     activeToastsHeight += toast.offsetHeight;
-//   }
-//
-//   const offset = activeToastsHeight + 20 * activeToasts.length + 20 + 'px';
-//   console.log('activeToasts: ', `${positionParts.value[0]}: ${offset}`);
-//
-//   if (positionParts.value.length === 1) return `${positionParts.value[0]}: ${offset}`;
-//   return `${positionParts.value[0]}: ${offset}; ${positionParts.value[1]}: 20px`;
-// });
 const closeToast = () => (active.value = false);
 
 let timeout: number;
@@ -153,24 +134,20 @@ if (props.duration) {
       for (const toast of activeToasts) {
         activeToastsHeight += toast.offsetHeight;
       }
-      console.log('activeToasts.length: ', activeToasts.length);
+      toast.value.style.order = '9999';
       const offset = activeToastsHeight + 20 * activeToasts.length;
-      console.log('offset: ', offset, offset - toastsContainer?.clientHeight, toastsContainer?.clientHeight);
-      toast.value.style.order = 9999;
-      toastsContainer.style[positionParts.value[0]] = offset - toastsContainer?.clientHeight + 'px';
-      console.log('toast.value.style: ', toast.value.style);
+      toastsContainer.style[positionParts.value[0] as 'top' | 'bottom'] = offset - toastsContainer?.clientHeight + 'px';
       timeout = setTimeout(() => (active.value = false), (props.duration as number) * 1000);
     } else {
-      console.log('inactive');
       toast.value.classList.remove('active');
       const activeToasts = document.querySelectorAll(`.toast-container.${props.position}.active`);
       let activeToastsHeight = 0;
       for (const toast of activeToasts) {
         activeToastsHeight += toast.offsetHeight;
       }
+      toast.value.style.order = '1';
       const offset = activeToastsHeight + 20 * activeToasts.length;
-      toastsContainer.style[positionParts.value[0]] = offset - toastsContainer?.clientHeight + 'px';
-      toast.value.style.order = 1;
+      toastsContainer.style[positionParts.value[0] as 'top' | 'bottom'] = offset - toastsContainer?.clientHeight + 'px';
       clearTimeout(timeout);
     }
   });
@@ -184,6 +161,8 @@ if (props.duration) {
       `toast-container ${position}`,
       {
         active,
+        topOrBottom,
+        oneAxis: positionParts.length === 1,
       },
     ]"
     :style="`position: relative;
@@ -210,6 +189,7 @@ if (props.duration) {
   padding: v-bind(padding);
   border: 1px solid v-bind(borderColor);
   border-radius: 7px;
+  transition: all 0.5s ease-in-out;
   width: v-bind(width);
   ::before {
     content: '';
@@ -244,4 +224,28 @@ if (props.duration) {
   cursor: pointer;
   display: block;
 }
+.top {
+  transform: translateY(-1000px);
+}
+.bottom {
+  transform: translateY(1000px);
+}
+.active.top {
+  transform: translateY(0);
+}
+.active.bottom {
+  transform: translateY(0);
+}
+.oneAxis.top {
+  transform: translate(-50%, -1000px) !important;
+}
+.oneAxis.bottom {
+  transform: translate(-50%, 1000px) !important;
+}
+.oneAxis.active.top {
+  transform: translate(-50%, 0) !important;
+}
+.oneAxis.active.bottom {
+  transform: translate(-50%, 0) !important;
+}
 </style>
-- 
GitLab