From e45e742850716ba9889a01acf23fa0be4130fc62 Mon Sep 17 00:00:00 2001
From: Alex Bueno <44420072+aweell@users.noreply.github.com>
Date: Tue, 19 Nov 2024 16:55:06 +0100
Subject: [PATCH] Fix toast issues
---
.../components/toast-wrapper.jsx | 37 +++++++----
.../advent-calendar-2024/components/toast.jsx | 63 ++++++++++++-------
.../components/toast.module.css | 23 +++++++
3 files changed, 87 insertions(+), 36 deletions(-)
create mode 100644 src/pages/advent-calendar-2024/components/toast.module.css
diff --git a/src/pages/advent-calendar-2024/components/toast-wrapper.jsx b/src/pages/advent-calendar-2024/components/toast-wrapper.jsx
index 7e5935bd6a..f9c502e355 100644
--- a/src/pages/advent-calendar-2024/components/toast-wrapper.jsx
+++ b/src/pages/advent-calendar-2024/components/toast-wrapper.jsx
@@ -1,7 +1,10 @@
import { useState, useEffect } from "react";
import Toast from "./toast"; // Assuming your Toast component is already implemented
+import { Stack } from "@telefonica/mistica";
const ToastWrapper = ({ toasts, removeToast }) => {
+ const totalToasts = toasts.length;
+
return (
{
right: "16px",
}}
>
-
- {toasts.map((toast, index) => (
- removeToast(toast.id)} // Dismiss the toast by `id`
- />
- ))}
-
+
+ {toasts.map((toast, index) => {
+ const scaleValue = 1 - index * 0.2;
+ console.log(`scale(${scaleValue})`); // Log the scale value
+
+ return (
+ removeToast(toast.id)} // Dismiss the toast by `id`
+ style={{
+ right: "16px",
+ zIndex: 1000 + index,
+ }}
+ delay={(totalToasts - index - 1) * 1000} // Last toast will have the longest delay
+ />
+ );
+ })}
+
);
};
diff --git a/src/pages/advent-calendar-2024/components/toast.jsx b/src/pages/advent-calendar-2024/components/toast.jsx
index 0c1353ba87..69b2d96722 100644
--- a/src/pages/advent-calendar-2024/components/toast.jsx
+++ b/src/pages/advent-calendar-2024/components/toast.jsx
@@ -1,4 +1,4 @@
-import { useEffect, useState, useRef } from "react";
+import { useState, useEffect, useRef } from "react";
import {
Stack,
Text3,
@@ -9,16 +9,19 @@ import {
IconButton,
IconCloseRegular,
} from "@telefonica/mistica";
+import styles from "./toast.module.css";
const Toast = ({
title,
description,
icon: Icon,
duration = 3000,
- style,
+ delay = 0,
onClose,
+ style,
}) => {
- const [visible, setVisible] = useState(true);
+ const [visible, setVisible] = useState(true); // Initial visibility is true
+ const [fadeOut, setFadeOut] = useState(false); // Controls fade-out animation
const [isHovered, setIsHovered] = useState(false);
const timeoutRef = useRef(null);
@@ -32,44 +35,53 @@ const Toast = ({
const startHideTimeout = () => {
clearHideTimeout();
timeoutRef.current = setTimeout(() => {
- setVisible(false); // This will trigger unmount if necessary
- onClose?.(); // Pass the ID to remove the toast
+ setFadeOut(true); // Trigger fade-out before setting visible to false
+ onClose?.(); // Trigger onClose callback to remove toast
}, duration);
};
+ // Handle visibility change when hovered or not
useEffect(() => {
- if (!isHovered) {
- startHideTimeout(); // Start timeout when not hovered
- } else {
- clearHideTimeout(); // Clear timeout when hovered
- }
+ const handleTimeout = () => {
+ if (!isHovered) {
+ setTimeout(startHideTimeout, delay); // Delay before auto-dismissing
+ } else {
+ clearHideTimeout(); // Clear timeout when hovered
+ }
+ };
+
+ handleTimeout();
return () => clearHideTimeout(); // Cleanup timeout on unmount
- }, [isHovered, duration]);
+ }, [isHovered, delay, duration]);
- // Always render dismiss button, regardless of toast visibility
- const handleDismiss = () => {
- setVisible(false);
- clearHideTimeout();
- onClose?.(); // Ensure it triggers onClose from parent
- };
+ useEffect(() => {
+ if (fadeOut) {
+ // Wait for the exit animation to complete before removing the toast
+ timeoutRef.current = setTimeout(() => {
+ setVisible(false); // Remove from the DOM after animation
+ }, 500); // Match the duration of your fade-out transition
+ }
+
+ return () => clearTimeout(timeoutRef.current); // Cleanup the fade-out timeout
+ }, [fadeOut]);
- if (!visible) return null; // Hide toast when not visible
+ if (!visible) return null; // If not visible, do not render the toast
return (
setIsHovered(true)}
- onMouseLeave={() => setIsHovered(false)}
+ onMouseEnter={() => setIsHovered(true)} // Trigger hover state
+ onMouseLeave={() => setIsHovered(false)} // Reset hover state
>
- {/* Dismiss button should always be on top */}
{
+ setFadeOut(true); // Trigger fade-out animation on close
+ clearHideTimeout(); // Clear the timeout when manually closed
+ onClose?.(); // Trigger onClose callback to remove toast
+ }}
/>
diff --git a/src/pages/advent-calendar-2024/components/toast.module.css b/src/pages/advent-calendar-2024/components/toast.module.css
new file mode 100644
index 0000000000..1e0746c125
--- /dev/null
+++ b/src/pages/advent-calendar-2024/components/toast.module.css
@@ -0,0 +1,23 @@
+/* toast.module.css */
+
+/* Keyframes for the toast entry animation */
+@keyframes slideIn {
+ 0% {
+ opacity: 0;
+ transform: translateY(400px); /* Start below */
+ }
+ 100% {
+ opacity: 1; /* Fade in */
+ transform: translateY(0); /* Move to final position */
+ }
+}
+
+
+
+/* Base toast styles */
+.toast {
+ opacity: 0;
+ transform: translateY(400px); /* Initial off-screen position */
+ animation: slideIn 0.5s ease-out forwards; /* Entry animation */
+}
+