11import React from 'react' ;
22import Modal , { ModalProps } from '@/components/elements/Modal' ;
33import ModalContext from '@/context/ModalContext' ;
4+ import isEqual from 'react-fast-compare' ;
45
56export interface AsModalProps {
67 visible : boolean ;
@@ -12,26 +13,34 @@ type ExtendedModalProps = Omit<ModalProps, 'appear' | 'visible' | 'onDismissed'>
1213interface State {
1314 render : boolean ;
1415 visible : boolean ;
15- showSpinnerOverlay : boolean ;
16+ modalProps : ExtendedModalProps | undefined ;
1617}
1718
18- function asModal ( modalProps ?: ExtendedModalProps ) {
19- // eslint-disable-next-line @typescript-eslint/ban-types
20- return function < T extends object > ( Component : React . ComponentType < T > ) {
21- return class extends React . PureComponent < T & AsModalProps , State > {
19+ type ExtendedComponentType < T > = ( C : React . ComponentType < T > ) => React . ComponentType < T & AsModalProps > ;
20+
21+ // eslint-disable-next-line @typescript-eslint/ban-types
22+ function asModal < P extends object > ( modalProps ?: ExtendedModalProps | ( ( props : P ) => ExtendedModalProps ) ) : ExtendedComponentType < P > {
23+ return function ( Component ) {
24+ return class extends React . PureComponent < P & AsModalProps , State > {
2225 static displayName = `asModal(${ Component . displayName } )` ;
2326
24- constructor ( props : T & AsModalProps ) {
27+ constructor ( props : P & AsModalProps ) {
2528 super ( props ) ;
2629
2730 this . state = {
2831 render : props . visible ,
2932 visible : props . visible ,
30- showSpinnerOverlay : modalProps ?. showSpinnerOverlay || false ,
33+ modalProps : typeof modalProps === 'function' ? modalProps ( this . props ) : modalProps ,
3134 } ;
3235 }
3336
34- componentDidUpdate ( prevProps : Readonly < T & AsModalProps > ) {
37+ componentDidUpdate ( prevProps : Readonly < P & AsModalProps > ) {
38+ const mapped = typeof modalProps === 'function' ? modalProps ( this . props ) : modalProps ;
39+ if ( ! isEqual ( this . state . modalProps , mapped ) ) {
40+ // noinspection JSPotentiallyInvalidUsageOfThis
41+ this . setState ( { modalProps : mapped } ) ;
42+ }
43+
3544 if ( prevProps . visible && ! this . props . visible ) {
3645 // noinspection JSPotentiallyInvalidUsageOfThis
3746 this . setState ( { visible : false } ) ;
@@ -43,7 +52,12 @@ function asModal (modalProps?: ExtendedModalProps) {
4352
4453 dismiss = ( ) => this . setState ( { visible : false } ) ;
4554
46- toggleSpinner = ( value ?: boolean ) => this . setState ( { showSpinnerOverlay : value || false } ) ;
55+ toggleSpinner = ( value ?: boolean ) => this . setState ( s => ( {
56+ modalProps : {
57+ ...s . modalProps ,
58+ showSpinnerOverlay : value || false ,
59+ } ,
60+ } ) ) ;
4761
4862 render ( ) {
4963 return (
@@ -58,13 +72,12 @@ function asModal (modalProps?: ExtendedModalProps) {
5872 < Modal
5973 appear
6074 visible = { this . state . visible }
61- showSpinnerOverlay = { this . state . showSpinnerOverlay }
6275 onDismissed = { ( ) => this . setState ( { render : false } , ( ) => {
6376 if ( typeof this . props . onModalDismissed === 'function' ) {
6477 this . props . onModalDismissed ( ) ;
6578 }
6679 } ) }
67- { ...modalProps }
80+ { ...this . state . modalProps }
6881 >
6982 < Component { ...this . props } />
7083 </ Modal >
0 commit comments