diff --git a/src/components/toast/index.js b/src/components/toast/index.js index 17eccf0d0..8589ecd7b 100644 --- a/src/components/toast/index.js +++ b/src/components/toast/index.js @@ -1,4 +1,5 @@ import "./style.scss"; +import { animate } from "motion"; /**@type {Array} */ const toastQueue = []; @@ -33,17 +34,27 @@ export default function toast(message, duration = 0, bgColor, color) { Object.defineProperties($toast, { hide: { value() { - this.classList.add("hide"); - setTimeout(() => { + animate( + this, + { opacity: 0, transform: "translateY(15px) scale(0.95)" }, + { duration: 0.25, ease: "easeIn" }, + ).then(() => { this.remove(); const $toast = toastQueue.splice(0, 1)[0]; if ($toast) $toast.show(); - }, 500); + }); }, }, show: { value() { app.append(this); + this.style.opacity = "0"; + this.style.transform = "translateY(20px) scale(0.95)"; + animate( + this, + { opacity: 1, transform: "translateY(0) scale(1)" }, + { type: "spring", stiffness: 300, damping: 25 }, + ); if (typeof duration === "number") { setTimeout(() => { diff --git a/src/components/toast/style.scss b/src/components/toast/style.scss index dd679f792..4f2654c52 100644 --- a/src/components/toast/style.scss +++ b/src/components/toast/style.scss @@ -16,15 +16,10 @@ max-width: 80vw; width: fit-content; overflow: auto; - animation: slow-appear 500ms linear 1; z-index: 9999; border-radius: 4px; pointer-events: none; - - &.hide { - transition: all 1s linear; - opacity: 0; - } + will-change: transform, opacity; &[clickable='true'] { pointer-events: all; diff --git a/src/lib/notificationManager.js b/src/lib/notificationManager.js index 90e399aa4..6ff6036e4 100644 --- a/src/lib/notificationManager.js +++ b/src/lib/notificationManager.js @@ -1,6 +1,7 @@ import sidebarApps from "sidebarApps"; import DOMPurify from "dompurify"; import Ref from "html-tag-js/ref"; +import { animate } from "motion"; /** * Notification create param @@ -242,8 +243,13 @@ class NotificationManager { `#${notification.id}`, ); if (!notificationElement) return; - notificationElement.classList.add("hiding"); - setTimeout(() => notificationElement.remove(), 300); + animate( + notificationElement, + { opacity: 0, transform: "translateX(100%)" }, + { duration: 0.25, ease: "easeIn" }, + ).then(() => { + notificationElement.remove(); + }); } #clearNotification(id) { @@ -289,9 +295,20 @@ class NotificationManager { this.renderNotifications(); // show toast notification - document - .querySelector(".notification-item-container") - ?.appendChild(this.createToastNotification(notification)); + const $toastEl = this.createToastNotification(notification); + const $container = document.querySelector(".notification-item-container"); + if ($container) { + $container.appendChild($toastEl); + + $toastEl.style.opacity = "0"; + $toastEl.style.transform = "translateX(100%)"; + + animate( + $toastEl, + { opacity: 1, transform: "translateX(0)" }, + { type: "spring", stiffness: 300, damping: 26 }, + ); + } } #parseIcon(icon) { diff --git a/src/main.scss b/src/main.scss index 28b919ce7..e4dfb3357 100644 --- a/src/main.scss +++ b/src/main.scss @@ -738,10 +738,10 @@ input[type="search"]::-webkit-search-results-decoration { max-width: min(400px, calc(100vw - 40px)); gap: 12px; box-shadow: 0 4px 12px var(--box-shadow-color); - animation: toastSlideIn 0.3s ease-out; border: 1px solid var(--border-color); white-space: wrap; box-sizing: border-box; + will-change: transform, opacity; } >* { @@ -770,14 +770,4 @@ input[type="search"]::-webkit-search-results-decoration { } } -@keyframes toastSlideIn { - from { - transform: translateX(120%); - opacity: 0; - } - to { - transform: translateX(0); - opacity: 1; - } -} diff --git a/src/sidebarApps/notification/style.scss b/src/sidebarApps/notification/style.scss index cdb635194..d66b71eda 100644 --- a/src/sidebarApps/notification/style.scss +++ b/src/sidebarApps/notification/style.scss @@ -51,6 +51,7 @@ padding-bottom: 5px; margin-bottom: 10px; border-radius: 0; + animation: slideIn 0.3s ease-out; } .empty-state { diff --git a/src/styles/notification.scss b/src/styles/notification.scss index a931e81d3..ef206af87 100644 --- a/src/styles/notification.scss +++ b/src/styles/notification.scss @@ -8,9 +8,8 @@ flex-direction: column; gap: 10px; align-items: flex-start; - animation: slideIn 0.3s ease-out; border: 1px solid var(--popup-border-color); - transition: all 0.2s ease; + transition: background-color 0.2s ease, border-color 0.2s ease, box-shadow 0.2s ease; overflow: hidden; &.loading { @@ -120,10 +119,7 @@ } } - &.hiding { - transform: translateX(120%); - opacity: 0; - } + &.success { .notification-icon {