import React, { ReactNode, useContext, useMemo } from "react"; import toast from "react-hot-toast"; import classNames from "classnames"; import { Box, BoxProps } from "../Box"; import { Flex } from "../Flex"; import { CloseButton } from "../CloseButton"; import { Icon, ICON_TYPE, StatusIcon } from "../Icon"; import { bem } from "../../utilities/bem"; import { STATUS_VARIANT } from "../../types"; import { StatusContext } from "../../contexts/status"; import { Link, LinkProps } from "../Link"; import { Heading } from "../Heading"; const cn = "Toast"; const defaultDuration = 5000; // @Deprecated type ToastPosition = "top-right"; export interface ToastSharedProps { title: string; content: ReactNode; variant?: STATUS_VARIANT; duration?: number; disableProgress?: boolean; className?: string; } export interface ToastProps extends ToastSharedProps { onClose: () => void; id?: string; style?: React.CSSProperties; } export interface ToastMessageProps { children: ReactNode; withIcon?: boolean; className?: string; } export interface ShowToastProps extends ToastSharedProps { position?: ToastPosition; } export const ToastLinkList = ({ children, className, ...rest }: BoxProps) => ( {children} ); export const ToastLink = ({ children, className, ...rest }: LinkProps) => ( {children} ); export const ToastMessage = ({ children, withIcon, className, }: ToastMessageProps) => { const variant = useContext(StatusContext); return ( {withIcon ? ( <> {children} ) : ( {children} )} ); }; export const Toast = ({ title, onClose, content, duration = defaultDuration, variant = STATUS_VARIANT.DEFAULT, disableProgress = false, className, style, id, ...rest }: ToastProps) => { const componentId = "toast"; const statusValue = useMemo(() => variant, [variant]); const durationCustomProperty = useMemo(() => { return { "--ads-toast-duration": `${duration}ms`, } as React.CSSProperties; }, [duration]); return ( {title && ( {title} )} {content && ( {content} )} ); }; export const showToast = ({ position = "top-right", duration = defaultDuration, variant = STATUS_VARIANT.DEFAULT, disableProgress = false, title, content, className, ...rest }: ShowToastProps) => { const options = { position, duration, }; return toast.custom( (t) => ( toast.dismiss(t.id), content, variant, disableProgress, className: classNames( t.visible ? "animate-toast-enter" : "animate-toast-leave", className, ), id: t.id, duration, ...rest, }} /> ), options, ); }; Toast.Link = ToastLink; Toast.LinkList = ToastLinkList; Toast.Message = ToastMessage;