diff --git a/README.md b/README.md index 6b3dc134..e1fb934d 100644 --- a/README.md +++ b/README.md @@ -64,7 +64,7 @@ ReactDOM.render( | maskTransitionName | String | | mask animation css class name | | | title | String\|React.Element | | Title of the dialog | | | footer | React.Element | | footer of the dialog | | -| closable | Boolean \| ({ closeIcon?: React.ReactNode; disabled?: boolean } & React.AriaAttributes | true | whether show close button | | +| closable | Boolean \| ({ closeIcon?: React.ReactNode; disabled?: boolean, afterClose:function } & React.AriaAttributes) | true | whether show close button | | | mask | Boolean | true | whether show mask | | | maskClosable | Boolean | true | whether click mask to close | | | keyboard | Boolean | true | whether support press esc to close | | diff --git a/src/DialogWrap.tsx b/src/DialogWrap.tsx index 58db3a5c..36c20bf8 100644 --- a/src/DialogWrap.tsx +++ b/src/DialogWrap.tsx @@ -20,6 +20,7 @@ const DialogWrap: React.FC = (props) => { forceRender, destroyOnHidden = false, afterClose, + closable, panelRef, } = props; const [animatedVisible, setAnimatedVisible] = React.useState(visible); @@ -49,6 +50,9 @@ const DialogWrap: React.FC = (props) => { {...props} destroyOnHidden={destroyOnHidden} afterClose={() => { + const closableObj = closable && typeof closable === 'object' ? closable : {}; + const { afterClose: closableAfterClose } = closableObj || {}; + closableAfterClose?.(); afterClose?.(); setAnimatedVisible(false); }} diff --git a/src/IDialogPropTypes.tsx b/src/IDialogPropTypes.tsx index 8a5b305c..6a9c47d1 100644 --- a/src/IDialogPropTypes.tsx +++ b/src/IDialogPropTypes.tsx @@ -7,6 +7,12 @@ export type ModalClassNames = Partial>; export type ModalStyles = Partial>; +export type ClosableType = { + closeIcon?: React.ReactNode; + disabled?: boolean; + afterClose?: () => any; +}; + export type IDialogPropTypes = { className?: string; keyboard?: boolean; @@ -17,7 +23,7 @@ export type IDialogPropTypes = { afterClose?: () => any; afterOpenChange?: (open: boolean) => void; onClose?: (e: SyntheticEvent) => any; - closable?: boolean | ({ closeIcon?: React.ReactNode; disabled?: boolean } & React.AriaAttributes); + closable?: boolean | (ClosableType & React.AriaAttributes); maskClosable?: boolean; visible?: boolean; destroyOnHidden?: boolean; diff --git a/tests/index.spec.tsx b/tests/index.spec.tsx index e6c075ea..1f233f41 100644 --- a/tests/index.spec.tsx +++ b/tests/index.spec.tsx @@ -552,6 +552,25 @@ describe('dialog', () => { expect(afterClose).toHaveBeenCalledTimes(0); }); + + it('should prioritize closable.afterClose when both exist', () => { + const afterClose = jest.fn(); + const legacyAfterClose = jest.fn(); + + const { rerender } = render( + , + ); + act(() => { + jest.runAllTimers(); + }); + + rerender(); + act(() => { + jest.runAllTimers(); + }); + expect(afterClose).toHaveBeenCalledTimes(1); + expect(legacyAfterClose).toHaveBeenCalledTimes(1); + }); }); describe('afterOpenChange', () => {