diff --git a/src/components/Toast.scss b/src/components/Toast.scss index 63d949a6..d236edd1 100644 --- a/src/components/Toast.scss +++ b/src/components/Toast.scss @@ -2,6 +2,9 @@ .excalidraw { .Toast { + $closeButtonSize: 1.2rem; + $closeButtonPadding: 0.4rem; + animation: fade-in 0.5s; background-color: var(--button-gray-1); border-radius: 4px; @@ -15,11 +18,24 @@ text-align: center; width: 300px; z-index: 999999; - } - .Toast__message { - color: var(--popup-text-color); - white-space: pre-wrap; + .Toast__message { + padding: 0 $closeButtonSize + ($closeButtonPadding); + color: var(--popup-text-color); + white-space: pre-wrap; + } + + .close { + position: absolute; + top: 0; + right: 0; + padding: $closeButtonPadding; + + .ToolIcon__icon { + width: $closeButtonSize; + height: $closeButtonSize; + } + } } @keyframes fade-in { diff --git a/src/components/Toast.tsx b/src/components/Toast.tsx index 22b62750..e6fd3648 100644 --- a/src/components/Toast.tsx +++ b/src/components/Toast.tsx @@ -1,34 +1,59 @@ import { useCallback, useEffect, useRef } from "react"; -import { TOAST_TIMEOUT } from "../constants"; +import { close } from "./icons"; import "./Toast.scss"; +import { ToolButton } from "./ToolButton"; + +const DEFAULT_TOAST_TIMEOUT = 5000; export const Toast = ({ message, clearToast, + closable = false, + // To prevent autoclose, pass duration as Infinity + duration = DEFAULT_TOAST_TIMEOUT, }: { message: string; clearToast: () => void; + closable?: boolean; + duration?: number; }) => { const timerRef = useRef(0); - - const scheduleTimeout = useCallback( - () => - (timerRef.current = window.setTimeout(() => clearToast(), TOAST_TIMEOUT)), - [clearToast], - ); + const shouldAutoClose = duration !== Infinity; + const scheduleTimeout = useCallback(() => { + if (!shouldAutoClose) { + return; + } + timerRef.current = window.setTimeout(() => clearToast(), duration); + }, [clearToast, duration, shouldAutoClose]); useEffect(() => { + if (!shouldAutoClose) { + return; + } scheduleTimeout(); return () => clearTimeout(timerRef.current); - }, [scheduleTimeout, message]); + }, [scheduleTimeout, message, duration, shouldAutoClose]); + const onMouseEnter = shouldAutoClose + ? () => clearTimeout(timerRef?.current) + : undefined; + const onMouseLeave = shouldAutoClose ? scheduleTimeout : undefined; return (
clearTimeout(timerRef?.current)} - onMouseLeave={scheduleTimeout} + onMouseEnter={onMouseEnter} + onMouseLeave={onMouseLeave} >

{message}

+ {closable && ( + + )}
); }; diff --git a/src/constants.ts b/src/constants.ts index 9bbacd8f..b1638f39 100644 --- a/src/constants.ts +++ b/src/constants.ts @@ -116,7 +116,6 @@ export const IMAGE_RENDER_TIMEOUT = 500; export const TAP_TWICE_TIMEOUT = 300; export const TOUCH_CTX_MENU_TIMEOUT = 500; export const TITLE_TIMEOUT = 10000; -export const TOAST_TIMEOUT = 5000; export const VERSION_TIMEOUT = 30000; export const SCROLL_TIMEOUT = 100; export const ZOOM_STEP = 0.1;