Skip to content

Commit

Permalink
feat: add removedByUser for onClose callback
Browse files Browse the repository at this point in the history
- solve: #1000, #716
- breaking: children props not passed down to `onClose` and `onOpen` callbacks
  • Loading branch information
fkhadra committed Nov 27, 2024
1 parent 2c9138a commit 525ff66
Show file tree
Hide file tree
Showing 5 changed files with 18 additions and 15 deletions.
4 changes: 2 additions & 2 deletions src/components/CloseButton.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { Default } from '../utils';
import { Theme, TypeOptions } from '../types';

export interface CloseButtonProps {
closeToast: (e: React.MouseEvent<HTMLElement>) => void;
closeToast: (removedByUser: boolean) => void;
type: TypeOptions;
ariaLabel?: string;
theme: Theme;
Expand All @@ -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}
>
Expand Down
16 changes: 8 additions & 8 deletions src/core/containerObserver.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { ReactElement, cloneElement, isValidElement } from 'react';
import { cloneElement, isValidElement, ReactElement } from 'react';
import {
Id,
NotValidatedToastProps,
Expand Down Expand Up @@ -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);
});
};

Expand All @@ -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 = <TData = unknown>(content: ToastContent<TData>, 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);
};

Expand All @@ -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);

Expand Down
4 changes: 2 additions & 2 deletions src/hooks/useToast.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand All @@ -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);
};
}

Expand Down
8 changes: 5 additions & 3 deletions src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -174,12 +174,12 @@ export interface ToastOptions<Data = unknown> extends CommonOptions {
/**
* Called when toast is mounted.
*/
onOpen?: <T = {}>(props: T) => void;
onOpen?: () => void;

/**
* Called when toast is unmounted.
*/
onClose?: <T = {}>(props: T) => void;
onClose?: (removedByUser: true | undefined) => void;

/**
* An optional inline style to apply.
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -311,6 +311,7 @@ export interface Toast {
content: ToastContent;
props: ToastProps;
toggle?: (v: boolean) => void;
removedByUser?: true | undefined;
}

export type ToastItemStatus = 'added' | 'removed' | 'updated';
Expand All @@ -325,6 +326,7 @@ export interface ToastItem<Data = {}> {
data: Data;
icon?: ToastIcon;
status: ToastItemStatus;
removedByUser?: true;
}

export type OnChangeCallback = (toast: ToastItem) => void;
Expand Down
1 change: 1 addition & 0 deletions src/utils/mapper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down

0 comments on commit 525ff66

Please sign in to comment.