diff --git a/src/components/CloseButton.tsx b/src/components/CloseButton.tsx index d3564add..a5b09502 100644 --- a/src/components/CloseButton.tsx +++ b/src/components/CloseButton.tsx @@ -3,7 +3,7 @@ import { Default } from '../utils'; import { Theme, TypeOptions } from '../types'; export interface CloseButtonProps { - closeToast: (e: React.MouseEvent) => void; + closeToast: (removedByUser: boolean) => void; type: TypeOptions; ariaLabel?: string; theme: Theme; @@ -16,7 +16,7 @@ export function CloseButton({ closeToast, theme, ariaLabel = 'close' }: CloseBut type="button" onClick={e => { e.stopPropagation(); - closeToast(e); + closeToast(true); }} aria-label={ariaLabel} > diff --git a/src/core/containerObserver.ts b/src/core/containerObserver.ts index e8f03b68..47abd292 100644 --- a/src/core/containerObserver.ts +++ b/src/core/containerObserver.ts @@ -1,4 +1,4 @@ -import { ReactElement, cloneElement, isValidElement } from 'react'; +import { cloneElement, isValidElement, ReactElement } from 'react'; import { Id, NotValidatedToastProps, @@ -59,7 +59,7 @@ export function createContainerObserver( const toggle = (v: boolean, id?: Id) => { toasts.forEach(t => { - if (id == null || id === t.props.toastId) isFn(t.toggle) && t.toggle(v); + if (id == null || id === t.props.toastId) t.toggle?.(v); }); }; @@ -74,24 +74,25 @@ export function createContainerObserver( }; const addActiveToast = (toast: ActiveToast) => { - const { toastId, onOpen, updateId, children } = toast.props; + const { toastId, updateId } = toast.props; const isNew = updateId == null; if (toast.staleId) toasts.delete(toast.staleId); toasts.set(toastId, toast); - activeToasts = [...activeToasts, toast.props.toastId].filter(v => v !== toast.staleId); + activeToasts = [...activeToasts, toastId].filter(v => v !== toast.staleId); notify(); dispatchChanges(toToastItem(toast, isNew ? 'added' : 'updated')); - if (isNew && isFn(onOpen)) onOpen(isValidElement(children) && children.props); + if (isNew) toast.props.onOpen?.(); }; const buildToast = (content: ToastContent, options: NotValidatedToastProps) => { if (shouldIgnoreToast(options)) return; const { toastId, updateId, data, staleId, delay } = options; - const closeToast = () => { + const closeToast = (removedByUser?: true) => { + toasts.get(toastId)!.removedByUser = removedByUser; removeToast(toastId); }; @@ -115,9 +116,8 @@ export function createContainerObserver( autoClose: options.isLoading ? false : getAutoCloseDelay(options.autoClose, props.autoClose), deleteToast() { const toastToRemove = toasts.get(toastId)!; - const { onClose, children } = toastToRemove.props; - if (isFn(onClose)) onClose(isValidElement(children) && children.props); + toastToRemove.props.onClose?.(toastToRemove.removedByUser); dispatchChanges(toToastItem(toastToRemove, 'removed')); toasts.delete(toastId); diff --git a/src/hooks/useToast.ts b/src/hooks/useToast.ts index 1dec8012..85c5d1a4 100644 --- a/src/hooks/useToast.ts +++ b/src/hooks/useToast.ts @@ -141,7 +141,7 @@ export function useToast(props: ToastProps) { drag.canDrag = false; if (Math.abs(drag.delta) > drag.removalDistance) { setPreventExitTransition(true); - props.closeToast(); + props.closeToast(true); props.collapseAll(); return; } @@ -168,7 +168,7 @@ export function useToast(props: ToastProps) { if (closeOnClick) { eventHandlers.onClick = (e: React.MouseEvent) => { onClick && onClick(e); - drag.canCloseOnClick && closeToast(); + drag.canCloseOnClick && closeToast(true); }; } diff --git a/src/types.ts b/src/types.ts index d73c38b1..436ae59c 100644 --- a/src/types.ts +++ b/src/types.ts @@ -174,12 +174,12 @@ export interface ToastOptions extends CommonOptions { /** * Called when toast is mounted. */ - onOpen?: (props: T) => void; + onOpen?: () => void; /** * Called when toast is unmounted. */ - onClose?: (props: T) => void; + onClose?: (removedByUser: true | undefined) => void; /** * An optional inline style to apply. @@ -282,7 +282,7 @@ export interface ToastProps extends ToastOptions { toastId: Id; key: Id; transition: ToastTransition; - closeToast: () => void; + closeToast: (removedByUser?: boolean) => void; position: ToastPosition; children?: ToastContent; draggablePercent: number; @@ -311,6 +311,7 @@ export interface Toast { content: ToastContent; props: ToastProps; toggle?: (v: boolean) => void; + removedByUser?: true | undefined; } export type ToastItemStatus = 'added' | 'removed' | 'updated'; @@ -325,6 +326,7 @@ export interface ToastItem { data: Data; icon?: ToastIcon; status: ToastItemStatus; + removedByUser?: true; } export type OnChangeCallback = (toast: ToastItem) => void; diff --git a/src/utils/mapper.ts b/src/utils/mapper.ts index 2d09fb8d..6181735a 100644 --- a/src/utils/mapper.ts +++ b/src/utils/mapper.ts @@ -11,6 +11,7 @@ export function toToastItem(toast: Toast, status: ToastItemStatus): ToastItem { data: toast.props.data || {}, isLoading: toast.props.isLoading, icon: toast.props.icon, + removedByUser: toast.removedByUser, status } : // monkey patch for now