75 lines
1.9 KiB
JavaScript
75 lines
1.9 KiB
JavaScript
import React, { useCallback } from 'react';
|
|
import Modal from 'react-modal';
|
|
import { createStructuredSelector } from 'reselect';
|
|
import get from 'lodash/get';
|
|
import { getModals, closeModal } from 'state/modals';
|
|
import connect from 'utils/connect';
|
|
import { bindActionCreators } from 'redux';
|
|
|
|
Modal.setAppElement('#root');
|
|
|
|
export default function withModal({ name, ...modalProps }) {
|
|
modalProps = {
|
|
className: {
|
|
base: `modal modal-${name}`,
|
|
afterOpen: 'modal-opening',
|
|
beforeClose: 'modal-closing'
|
|
},
|
|
overlayClassName: {
|
|
base: 'modal-overlay',
|
|
afterOpen: 'modal-overlay-opening',
|
|
beforeClose: 'modal-overlay-closing'
|
|
},
|
|
closeTimeoutMS: 200,
|
|
...modalProps
|
|
};
|
|
|
|
return WrappedComponent => {
|
|
const ReduxModal = ({ onRequestClose, ...props }) => {
|
|
const handleRequestClose = useCallback(
|
|
(dismissed = true) => {
|
|
onRequestClose();
|
|
|
|
if (dismissed && props.payload.onDismiss) {
|
|
props.payload.onDismiss();
|
|
}
|
|
},
|
|
[props.payload.onDismiss]
|
|
);
|
|
|
|
return (
|
|
<Modal
|
|
contentLabel={name}
|
|
onRequestClose={handleRequestClose}
|
|
{...modalProps}
|
|
{...props}
|
|
>
|
|
<WrappedComponent onClose={handleRequestClose} {...props} />
|
|
</Modal>
|
|
);
|
|
};
|
|
|
|
const mapState = createStructuredSelector({
|
|
isOpen: state => get(getModals(state), [name, 'isOpen'], false),
|
|
payload: state => get(getModals(state), [name, 'payload'], {}),
|
|
...modalProps.state
|
|
});
|
|
|
|
const mapDispatch = dispatch => {
|
|
const actions = { onRequestClose: () => dispatch(closeModal(name)) };
|
|
if (modalProps.actions) {
|
|
return {
|
|
...actions,
|
|
...bindActionCreators(modalProps.actions, dispatch)
|
|
};
|
|
}
|
|
return actions;
|
|
};
|
|
|
|
return connect(
|
|
mapState,
|
|
mapDispatch
|
|
)(ReduxModal);
|
|
};
|
|
}
|