Skip to content

Commit

Permalink
feat(Toaster): added onClose callback (#1902)
Browse files Browse the repository at this point in the history
  • Loading branch information
kkirik authored Oct 19, 2024
1 parent 7eb5e1e commit 3069194
Show file tree
Hide file tree
Showing 4 changed files with 33 additions and 4 deletions.
1 change: 1 addition & 0 deletions src/components/Toaster/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,7 @@ Accepts the argument `toastOptions` with ongoing notification details:
| isClosable | `boolean` | | `true` | A configuration that manages the visibility of the X icon, which allows the user to close the notification |
| actions | `ToastAction[]` | | `undefined` | An array of [actions](./types.ts#L9) that display after `content` |
| renderIcon | `(toastProps: ToastProps) => ReactNode` | | `undefined` | Used to customize the toast icon. Type-based behavior is used by default |
| onClose | `() => void` | | `undefined` | Callback which calls when close button is clicked |

Every `action` is an object with following parameters:

Expand Down
15 changes: 11 additions & 4 deletions src/components/Toaster/Toast/Toast.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -94,12 +94,19 @@ export const Toast = React.forwardRef<HTMLDivElement, ToastUnitedProps>(function
autoHiding: timeoutProp = DEFAULT_TIMEOUT,
isClosable = true,
mobile = false,
onClose,
removeCallback,
} = props;

const onClose = React.useCallback(() => removeCallback(name), [removeCallback, name]);
const handleClose = React.useCallback(() => {
removeCallback(name);

if (onClose) {
onClose();
}
}, [removeCallback, onClose, name]);
const timeout = typeof timeoutProp === 'number' ? timeoutProp : undefined;
const closeOnTimeoutProps = useCloseOnTimeout<HTMLDivElement>({onClose, timeout});
const closeOnTimeoutProps = useCloseOnTimeout<HTMLDivElement>({onClose: handleClose, timeout});

const mods = {
mobile,
Expand All @@ -120,7 +127,7 @@ export const Toast = React.forwardRef<HTMLDivElement, ToastUnitedProps>(function
size="s"
view="flat"
className={b('btn-close')}
onClick={onClose}
onClick={handleClose}
extraProps={{'aria-label': i18n('label_close-button')}}
>
<Icon data={Xmark} />
Expand All @@ -129,7 +136,7 @@ export const Toast = React.forwardRef<HTMLDivElement, ToastUnitedProps>(function
{hasContent && (
<div className={b('content', {'without-title': !hasTitle})}>{content}</div>
)}
{renderActions({actions, onClose})}
{renderActions({actions, onClose: handleClose})}
</div>
</div>
);
Expand Down
19 changes: 19 additions & 0 deletions src/components/Toaster/__tests__/ToasterProvider.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -409,4 +409,23 @@ describe('modal remains open after toaster close', () => {
expect(toast).not.toBeInTheDocument();
expect(modal).toBeInTheDocument();
});

it('Toaster calls onClose callback when close icon is clicked', async () => {
const {providerAPI} = setup();

const mockOnCloseFn = jest.fn();

act(() => {
providerAPI.add({...toastProps, isClosable: true, onClose: mockOnCloseFn});
});

const toast = getToast();

const closeToastButton = await within(toast).findByRole('button');

fireEvent.click(closeToastButton);
tick(toast, 0);

expect(mockOnCloseFn).toHaveBeenCalled();
});
});
2 changes: 2 additions & 0 deletions src/components/Toaster/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ export type ToastProps = {
isClosable?: boolean;
actions?: ToastAction[];

onClose?: () => void;

/** Function. Use for toast icon customization. By default type-based behavior is used */
renderIcon?: (toastProps: ToastProps) => React.ReactNode;
};
Expand Down

0 comments on commit 3069194

Please sign in to comment.