1- import React , { cloneElement , ForwardedRef , forwardRef , useImperativeHandle } from 'react' ;
2- import ReactDOM from 'react-dom' ;
1+ import { cloneElement , ForwardedRef , forwardRef , useImperativeHandle , useRef , useState , useEffect , useCallback } from 'react' ;
32import { DEFAULT_SIZE , SIZE_MAP } from '../../../constants/layout.settings' ;
43import { classNames } from '../../../utils/dom.utils' ;
54import { FlyoutProps } from './Flyout.types' ;
@@ -17,46 +16,46 @@ export const Flyout = forwardRef(function Flyout(
1716 onStateChange,
1817 qa
1918 } : FlyoutProps ,
20- forwardRef : ForwardedRef < null >
19+ forwardRef : ForwardedRef < HTMLDivElement | null >
2120) {
22- const [ isOpen , setIsOpen ] = React . useState ( ! ! open ) ;
21+ const [ isOpen , setIsOpen ] = useState ( ! ! open ) ;
2322 const showFlyout = open === false || open === true ? open : isOpen ;
2423
25- const flyoutRef = React . useRef ( null ) ;
24+ const flyoutRef = useRef < HTMLDivElement | null > ( null ) ;
2625 useImperativeHandle ( forwardRef , ( ) => flyoutRef . current ) ;
2726
28- const _handleOutsideClick = React . useCallback (
27+ const _handleOutsideClick = useCallback (
2928 ( e : MouseEvent ) => {
30- const area = ReactDOM . findDOMNode ( flyoutRef . current ) ;
31- if ( e . target === area ?. lastChild ) {
29+ const area = flyoutRef . current ;
30+ if ( ! area ) return ;
31+
32+ if ( e . target === area . lastChild ) {
3233 e . preventDefault ( ) ;
3334 }
34- if ( area && ! area . contains ( e . target as HTMLInputElement ) ) {
35+
36+ if ( ! area . contains ( e . target as Node ) ) {
3537 setIsOpen ( false ) ;
36- onStateChange && onStateChange ( false ) ;
38+ onStateChange ?. ( false ) ;
3739 }
3840 } ,
3941 [ onStateChange ]
4042 ) ;
4143
42- const initEventHandlers = React . useCallback ( ( ) => {
44+ useEffect ( ( ) => {
4345 if ( showFlyout ) {
4446 document . addEventListener ( 'mousedown' , _handleOutsideClick , false ) ;
45- } else {
46- document . removeEventListener ( 'mousedown' , _handleOutsideClick , false ) ;
47+ return ( ) => {
48+ document . removeEventListener ( 'mousedown' , _handleOutsideClick , false ) ;
49+ } ;
4750 }
48- } , [ _handleOutsideClick , showFlyout ] ) ;
51+ } , [ showFlyout , _handleOutsideClick ] ) ;
4952
5053 const _toggleIsOpen = ( ) => {
51- setIsOpen ( ! showFlyout ) ;
52- initEventHandlers ( ) ;
53- onStateChange && onStateChange ( ! showFlyout ) ;
54+ const newState = ! showFlyout ;
55+ setIsOpen ( newState ) ;
56+ onStateChange ?. ( newState ) ;
5457 } ;
5558
56- React . useEffect ( ( ) => {
57- initEventHandlers ( ) ;
58- } , [ initEventHandlers ] ) ;
59-
6059 const flyoutClasses = classNames ( {
6160 'm-flyout' : true ,
6261 [ className ] : ! ! className ,
0 commit comments