diff options
Diffstat (limited to 'packages/excalidraw/components/Toast.tsx')
| -rw-r--r-- | packages/excalidraw/components/Toast.tsx | 63 |
1 files changed, 63 insertions, 0 deletions
diff --git a/packages/excalidraw/components/Toast.tsx b/packages/excalidraw/components/Toast.tsx new file mode 100644 index 0000000..d99c9f6 --- /dev/null +++ b/packages/excalidraw/components/Toast.tsx @@ -0,0 +1,63 @@ +import type { CSSProperties } from "react"; +import { useCallback, useEffect, useRef } from "react"; +import { CloseIcon } from "./icons"; +import "./Toast.scss"; +import { ToolButton } from "./ToolButton"; + +const DEFAULT_TOAST_TIMEOUT = 5000; + +export const Toast = ({ + message, + onClose, + closable = false, + // To prevent autoclose, pass duration as Infinity + duration = DEFAULT_TOAST_TIMEOUT, + style, +}: { + message: string; + onClose: () => void; + closable?: boolean; + duration?: number; + style?: CSSProperties; +}) => { + const timerRef = useRef<number>(0); + const shouldAutoClose = duration !== Infinity; + const scheduleTimeout = useCallback(() => { + if (!shouldAutoClose) { + return; + } + timerRef.current = window.setTimeout(() => onClose(), duration); + }, [onClose, duration, shouldAutoClose]); + + useEffect(() => { + if (!shouldAutoClose) { + return; + } + scheduleTimeout(); + return () => clearTimeout(timerRef.current); + }, [scheduleTimeout, message, duration, shouldAutoClose]); + + const onMouseEnter = shouldAutoClose + ? () => clearTimeout(timerRef?.current) + : undefined; + const onMouseLeave = shouldAutoClose ? scheduleTimeout : undefined; + return ( + <div + className="Toast" + onMouseEnter={onMouseEnter} + onMouseLeave={onMouseLeave} + style={style} + > + <p className="Toast__message">{message}</p> + {closable && ( + <ToolButton + icon={CloseIcon} + aria-label="close" + type="icon" + onClick={onClose} + className="close" + /> + )} + </div> + ); +}; |
