import { keyframes } from "@emotion/react" import styled from "@emotion/styled" import * as Portal from "@radix-ui/react-portal" import Error from "mdi-react/AlertCircleIcon" import Warning from "mdi-react/AlertIcon" import CheckCircle from "mdi-react/CheckCircleIcon" import Info from "mdi-react/InformationIcon" import { FC, useEffect, useState } from "react" import { Theme } from "../common/theme/Theme" import { useTheme } from "../main/hooks/useTheme" import { ToastSeverity } from "../main/hooks/useToast" export interface ToastProps { message: string severity: ToastSeverity onExited: () => void } const contentShow = keyframes` from { opacity: 0; transform: translate(0, 0.5rem) scale(0.96); } to { opacity: 1; transform: translate(0, 0) scale(1); } ` const contentHide = keyframes` from { opacity: 1; transform: translate(0, 0) scale(1); } to { opacity: 0; transform: translate(0, 0.5rem) scale(0.96); } ` const Root = styled(Portal.Root)` position: fixed; bottom: 2rem; left: 0; right: 0; display: flex; ` const Content = styled.div` margin: 0 auto; background: ${({ theme }) => theme.secondaryBackgroundColor}; padding: 1rem; border-radius: 0.5rem; font-size: 0.8rem; box-shadow: 0 0.5rem 3rem ${({ theme }) => theme.shadowColor}; display: flex; align-items: center; animation: ${({ show }: { show: boolean }) => show ? contentShow : contentHide} 500ms cubic-bezier(0.16, 1, 0.3, 1) forwards; ` const SeverityIcon: FC<{ severity: ToastSeverity }> = ({ severity }) => { const theme = useTheme() const fill = colorForSeverity(severity, theme) switch (severity) { case "error": return case "info": return case "success": return case "warning": return } } const exitDuration = 5000 export const Toast: FC = ({ message, severity, onExited }) => { const [show, setShow] = useState(true) useEffect(() => { const timeout = setTimeout(() => setShow(false), exitDuration - 500) const timeout2 = setTimeout(onExited, exitDuration) return () => { clearTimeout(timeout) clearTimeout(timeout2) } }) return (
{message} ) } const colorForSeverity = (severity: ToastSeverity, theme: Theme) => { switch (severity) { case "error": return theme.redColor case "info": return theme.textColor case "success": return theme.greenColor case "warning": return theme.yellowColor } }