From 440a7564a386e3ae9b2a02a36bde40da69d9e6b4 Mon Sep 17 00:00:00 2001 From: Luke Date: Mon, 2 Jan 2023 21:50:49 +0100 Subject: [PATCH] refactor(web/notifications): improve notification transitions --- .../notifications/NotificationWrapper.tsx | 144 ++++++++++++++---- 1 file changed, 114 insertions(+), 30 deletions(-) diff --git a/web/src/features/notifications/NotificationWrapper.tsx b/web/src/features/notifications/NotificationWrapper.tsx index e39a43e..db2c7d5 100644 --- a/web/src/features/notifications/NotificationWrapper.tsx +++ b/web/src/features/notifications/NotificationWrapper.tsx @@ -3,7 +3,7 @@ import { IconProp } from '@fortawesome/fontawesome-svg-core'; import { toast, Toaster, ToastPosition } from 'react-hot-toast'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import ReactMarkdown from 'react-markdown'; -import { Avatar, createStyles, Group, Stack, Box, Text } from '@mantine/core'; +import { Avatar, createStyles, Group, Stack, Box, Text, keyframes } from '@mantine/core'; import React from 'react'; export interface NotificationProps { @@ -49,6 +49,73 @@ const useStyles = createStyles((theme) => ({ }, })); +// I hate this +const enterAnimationTop = keyframes({ + from: { + opacity: 0, + transform: 'translateY(-30px)', + }, + to: { + opacity: 1, + transform: 'translateY(0px)', + }, +}); + +const enterAnimationBottom = keyframes({ + from: { + opacity: 0, + transform: 'translateY(30px)', + }, + to: { + opacity: 1, + transform: 'translateY(0px)', + }, +}); + +const exitAnimationTop = keyframes({ + from: { + opacity: 1, + transform: 'translateY(0px)', + }, + to: { + opacity: 0, + transform: 'translateY(-100%)', + }, +}); + +const exitAnimationRight = keyframes({ + from: { + opacity: 1, + transform: 'translateX(0px)', + }, + to: { + opacity: 0, + transform: 'translateX(100%)', + }, +}); + +const exitAnimationLeft = keyframes({ + from: { + opacity: 1, + transform: 'translateX(0px)', + }, + to: { + opacity: 0, + transform: 'translateX(-100%)', + }, +}); + +const exitAnimationBottom = keyframes({ + from: { + opacity: 1, + transform: 'translateY(0px)', + }, + to: { + opacity: 0, + transform: 'translateY(100%)', + }, +}); + const Notifications: React.FC = () => { const { classes } = useStyles(); @@ -68,39 +135,56 @@ const Notifications: React.FC = () => { data.icon = data.type === 'error' ? 'xmark' : data.type === 'success' ? 'check' : 'info'; } - toast( - - - {data.icon && ( - <> - {!data.iconColor ? ( - - - - ) : ( - - )} - - )} - - {data.title && {data.title}} - {data.description && {data.description}} - - - , + toast.custom( + (t) => ( + + + {data.icon && ( + <> + {!data.iconColor ? ( + + + + ) : ( + + )} + + )} + + {data.title && {data.title}} + {data.description && {data.description}} + + + + ), { id: data.id?.toString(), duration: data.duration || 3000, position: position || 'top-right', - style: { - padding: 0, - boxShadow: 'none', - backgroundColor: 'transparent', - }, } ); });