diff --git a/packages/clay-modal/src/Modal.tsx b/packages/clay-modal/src/Modal.tsx index e27adb3930..8c9128e5e3 100644 --- a/packages/clay-modal/src/Modal.tsx +++ b/packages/clay-modal/src/Modal.tsx @@ -9,27 +9,25 @@ import classNames from 'classnames'; import Context, {IContext} from './Context'; import Footer from './Footer'; import Header from './Header'; -import React, {FunctionComponent, useEffect, useRef, useState} from 'react'; +import React, {FunctionComponent, useEffect, useRef} from 'react'; import {ClayPortal} from '@clayui/shared'; -import {Size} from './types'; +import {Observer, ObserverType, Size} from './types'; import {useUserInteractions} from './Hook'; -interface IProps extends React.HTMLAttributes, IContext { - children?: (onClose: () => void) => React.ReactNode; - +interface IProps + extends React.HTMLAttributes, + Omit { /** * The size of element modal. */ size?: Size; -} - -const delay = (fn: Function) => { - return setTimeout(() => { - fn(); - }, 100); -}; -const modalOpenClassName = 'modal-open'; + /** + * Observer is Modal's communication system with `useModal` + * hook, adds observer from `useModal` hook here. + */ + observer: Observer; +} const ClayModal: FunctionComponent & { Body: typeof Body; @@ -38,58 +36,32 @@ const ClayModal: FunctionComponent & { } = ({ children, className, - onClose = () => {}, + observer, size, spritemap, status, ...otherProps }: IProps) => { - const [visibleClassShow, setVisibleClassShow] = useState(false); - const modalBodyElementRef = useRef(null); const modalDialogElementRef = useRef(null); - /** - * Control the close of the modal to create the component's "unmount" - * animation and call the onClose prop with delay. - */ - const handleCloseModal = () => { - document.body.classList.remove(modalOpenClassName); - setVisibleClassShow(false); - - delay(onClose); - }; - - const context = { - onClose: handleCloseModal, - spritemap, - status, - }; - - useUserInteractions(modalDialogElementRef, handleCloseModal); - - useEffect(() => { - document.body.classList.add(modalOpenClassName); - const timer = delay(() => { - setVisibleClassShow(true); - }); + useUserInteractions(modalDialogElementRef, () => + observer.dispatch(ObserverType.Close) + ); - return () => { - clearTimeout(timer); - }; - }, []); + useEffect(() => observer.dispatch(ObserverType.Open), []); return (
@@ -102,10 +74,15 @@ const ClayModal: FunctionComponent & { tabIndex={-1} >
- - {children && typeof children === 'function' - ? children(handleCloseModal) - : children} + + observer.dispatch(ObserverType.Close), + spritemap, + status, + }} + > + {children}
diff --git a/packages/clay-modal/src/__tests__/IncrementalInteractions.tsx b/packages/clay-modal/src/__tests__/IncrementalInteractions.tsx index 075837ccfe..0d938a0762 100644 --- a/packages/clay-modal/src/__tests__/IncrementalInteractions.tsx +++ b/packages/clay-modal/src/__tests__/IncrementalInteractions.tsx @@ -6,8 +6,8 @@ */ import Button from '@clayui/button'; -import ClayModal from '..'; -import React, {useState} from 'react'; +import ClayModal, {ClayModalProvider, Context, useModal} from '..'; +import React, {useContext, useEffect, useState} from 'react'; import ReactDOM from 'react-dom'; import {cleanup, fireEvent, render} from '@testing-library/react'; @@ -24,15 +24,12 @@ const ModalWithState: React.FunctionComponent = ({ ...props }) => { const [visible, setVisible] = useState(initialVisible); + const {observer} = useModal({onClose: () => setVisible(false)}); return ( <> {visible && ( - setVisible(false)} - spritemap={spritemap} - {...props} - > + {children} )} @@ -160,9 +157,18 @@ describe('Modal -> IncrementalInteractions', () => { }); it('close the modal when click on the button of Footer component', () => { - const {getByLabelText} = render( - - {(onClose: any) => ( + const ModalState = () => { + const [visible, setVisible] = useState(true); + const {observer, onClose} = useModal({ + onClose: () => setVisible(false), + }); + + if (!visible) { + return null; + } + + return ( + @@ -170,9 +176,10 @@ describe('Modal -> IncrementalInteractions', () => { } /> - )} - - ); + + ); + }; + const {getByLabelText} = render(); jest.runAllTimers(); diff --git a/packages/clay-modal/src/__tests__/__snapshots__/index.tsx.snap b/packages/clay-modal/src/__tests__/__snapshots__/index.tsx.snap index 83592d4c93..324aa51bc1 100644 --- a/packages/clay-modal/src/__tests__/__snapshots__/index.tsx.snap +++ b/packages/clay-modal/src/__tests__/__snapshots__/index.tsx.snap @@ -1,244 +1,270 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP exports[`ClayModal renders 1`] = ` -Array [ -
, -
+ +