From 57836e20a3b5f7999469a307f0600c2e38403eb0 Mon Sep 17 00:00:00 2001 From: ysshir Date: Mon, 7 Aug 2023 14:09:03 +0900 Subject: [PATCH] feat(Toast): add transition callbacks (#6674) * add transition callbacks to Toast * typo modal -> toast * add Toast Callback example * add Toast Callback test * modify Toast Callback test * remove Toast Callback example --------- Co-authored-by: Yohei Shiraishi --- src/Toast.tsx | 55 ++++++++++++++++++++++++++++++++++++++++++---- test/ToastSpec.tsx | 40 ++++++++++++++++++++++++++++++++- 2 files changed, 90 insertions(+), 5 deletions(-) diff --git a/src/Toast.tsx b/src/Toast.tsx index afe561a509..a65ce57597 100644 --- a/src/Toast.tsx +++ b/src/Toast.tsx @@ -4,7 +4,7 @@ import PropTypes from 'prop-types'; import classNames from 'classnames'; import useTimeout from '@restart/hooks/useTimeout'; -import { TransitionComponent } from '@restart/ui/types'; +import { TransitionCallbacks, TransitionComponent } from '@restart/ui/types'; import ToastFade from './ToastFade'; import ToastHeader from './ToastHeader'; import ToastBody from './ToastBody'; @@ -14,12 +14,14 @@ import { BsPrefixProps, BsPrefixRefForwardingComponent } from './helpers'; import { Variant } from './types'; export interface ToastProps - extends BsPrefixProps, + extends TransitionCallbacks, + BsPrefixProps, React.HTMLAttributes { animation?: boolean; autohide?: boolean; delay?: number; onClose?: (e?: React.MouseEvent | React.KeyboardEvent) => void; + show?: boolean; transition?: TransitionComponent; bg?: Variant; @@ -52,7 +54,37 @@ const propTypes = { onClose: PropTypes.func, /** - * When `true` The modal will show itself. + * Callback fired before the toast transitions in + */ + onEnter: PropTypes.func, + + /** + * Callback fired as the toast begins to transition in + */ + onEntering: PropTypes.func, + + /** + * Callback fired after the toast finishes transitioning in + */ + onEntered: PropTypes.func, + + /** + * Transition onExit callback when animation is not `false` + */ + onExit: PropTypes.func, + + /** + * Transition onExiting callback when animation is not `false` + */ + onExiting: PropTypes.func, + + /** + * Transition onExited callback when animation is not `false` + */ + onExited: PropTypes.func, + + /** + * When `true` The toast will show itself. */ show: PropTypes.bool, @@ -81,6 +113,12 @@ const Toast: BsPrefixRefForwardingComponent<'div', ToastProps> = delay = 5000, autohide = false, onClose, + onEntered, + onExit, + onExiting, + onEnter, + onEntering, + onExited, bg, ...props }, @@ -140,7 +178,16 @@ const Toast: BsPrefixRefForwardingComponent<'div', ToastProps> = return ( {hasAnimation && Transition ? ( - + {toast} ) : ( diff --git a/test/ToastSpec.tsx b/test/ToastSpec.tsx index 61184436ce..9b77847a50 100644 --- a/test/ToastSpec.tsx +++ b/test/ToastSpec.tsx @@ -1,6 +1,7 @@ +import * as React from 'react'; import { fireEvent, render } from '@testing-library/react'; import sinon from 'sinon'; - +import { expect } from 'chai'; import Toast from '../src/Toast'; const getToast = ({ @@ -201,4 +202,41 @@ describe('', () => { container.firstElementChild!.tagName.toLowerCase().should.equal('div'); container.firstElementChild!.classList.contains('my-toast'); }); + + it('Should pass transition callbacks to Transition', (done) => { + const increment = sinon.spy(); + + const Elem = () => { + const [show, setShow] = React.useState(false); + React.useEffect(() => { + setShow(true); + }, []); + + return ( + { + increment(); + setShow(false); + }} + onExit={increment} + onExiting={increment} + onExited={() => { + increment(); + expect(increment.callCount).to.equal(6); + done(); + }} + > + + Body + + ); + }; + + render(); + + clock.tick(250); + }); });