@@ -72,6 +72,10 @@ export interface CModalProps extends HTMLAttributes<HTMLDivElement> {
7272 * Remove animation to create modal that simply appear rather than fade in to view.
7373 */
7474 transition ?: boolean
75+ /*
76+ * By default the component is unmounted after close animation, if you want to keep the component mounted set this property to false
77+ */
78+ unmountOnClose ?: boolean
7579 /**
7680 * Toggle the visibility of modal component.
7781 */
@@ -102,11 +106,13 @@ export const CModal = forwardRef<HTMLDivElement, CModalProps>(
102106 scrollable,
103107 size,
104108 transition = true ,
109+ unmountOnClose = true ,
105110 visible,
106111 } ,
107112 ref ,
108113 ) => {
109114 const modalRef = useRef < HTMLDivElement > ( null )
115+ const modalContentRef = useRef < HTMLDivElement > ( null )
110116 const forkedRef = useForkedRef ( ref , modalRef )
111117
112118 const [ _visible , setVisible ] = useState ( visible )
@@ -121,6 +127,16 @@ export const CModal = forwardRef<HTMLDivElement, CModalProps>(
121127 setVisible,
122128 }
123129
130+ useEffect ( ( ) => {
131+ modalRef . current && modalRef . current . addEventListener ( 'click' , handleClickOutside )
132+ modalRef . current && modalRef . current . addEventListener ( 'keyup' , handleKeyDown )
133+
134+ return ( ) => {
135+ modalRef . current && modalRef . current . removeEventListener ( 'click' , handleClickOutside )
136+ modalRef . current && modalRef . current . removeEventListener ( 'keyup' , handleKeyDown )
137+ }
138+ } , [ _visible ] )
139+
124140 const handleDismiss = ( ) => {
125141 if ( backdrop === 'static' ) {
126142 return setStaticBackdrop ( true )
@@ -167,6 +183,15 @@ export const CModal = forwardRef<HTMLDivElement, CModalProps>(
167183 return ( ) => document . body . classList . remove ( 'modal-open' )
168184 } , [ _visible ] )
169185
186+ const handleClickOutside = ( event : Event ) => {
187+ if (
188+ modalContentRef . current &&
189+ ! modalContentRef . current . contains ( event . target as HTMLElement )
190+ ) {
191+ handleDismiss ( )
192+ }
193+ }
194+
170195 const handleKeyDown = useCallback (
171196 ( event ) => {
172197 if ( event . key === 'Escape' && keyboard ) {
@@ -190,9 +215,8 @@ export const CModal = forwardRef<HTMLDivElement, CModalProps>(
190215 fullscreen = { fullscreen }
191216 scrollable = { scrollable }
192217 size = { size }
193- onClick = { ( event ) => event . stopPropagation ( ) }
194218 >
195- < CModalContent > { children } </ CModalContent >
219+ < CModalContent ref = { modalContentRef } > { children } </ CModalContent >
196220 </ CModalDialog >
197221 </ div >
198222 </ CModalContext . Provider >
@@ -201,23 +225,21 @@ export const CModal = forwardRef<HTMLDivElement, CModalProps>(
201225
202226 return (
203227 < >
204- < div onClick = { handleDismiss } onKeyDown = { handleKeyDown } >
205- < Transition
206- in = { _visible }
207- mountOnEnter
208- onEnter = { onShow }
209- onExit = { onClose }
210- unmountOnExit
211- timeout = { ! transition ? 0 : duration }
212- >
213- { ( state ) => {
214- const transitionClass = getTransitionClass ( state )
215- return typeof window !== 'undefined' && portal
216- ? createPortal ( modal ( forkedRef , transitionClass ) , document . body )
217- : modal ( forkedRef , transitionClass )
218- } }
219- </ Transition >
220- </ div >
228+ < Transition
229+ in = { _visible }
230+ mountOnEnter
231+ onEnter = { onShow }
232+ onExit = { onClose }
233+ unmountOnExit = { unmountOnClose }
234+ timeout = { ! transition ? 0 : duration }
235+ >
236+ { ( state ) => {
237+ const transitionClass = getTransitionClass ( state )
238+ return typeof window !== 'undefined' && portal
239+ ? createPortal ( modal ( forkedRef , transitionClass ) , document . body )
240+ : modal ( forkedRef , transitionClass )
241+ } }
242+ </ Transition >
221243 { typeof window !== 'undefined' && portal
222244 ? backdrop && createPortal ( < CBackdrop visible = { _visible } /> , document . body )
223245 : backdrop && < CBackdrop visible = { _visible } /> }
@@ -244,6 +266,7 @@ CModal.propTypes = {
244266 scrollable : PropTypes . bool ,
245267 size : PropTypes . oneOf ( [ 'sm' , 'lg' , 'xl' ] ) ,
246268 transition : PropTypes . bool ,
269+ unmountOnClose : PropTypes . bool ,
247270 visible : PropTypes . bool ,
248271}
249272
0 commit comments