Add react-modal, replace confirm usage with it

This commit is contained in:
Ken-Håvard Lieng 2019-01-05 07:08:34 +01:00
parent 63cf65100d
commit 0085cea5a1
17 changed files with 443 additions and 152 deletions

View file

@ -1,9 +1,10 @@
import React, { Suspense, lazy } from 'react';
import React, { Suspense, lazy, useState } from 'react';
import Route from 'containers/Route';
import AppInfo from 'components/AppInfo';
import TabList from 'components/TabList';
import cn from 'classnames';
const Modals = lazy(() => import('components/modals'));
const Chat = lazy(() => import('containers/Chat'));
const Connect = lazy(() => import('containers/Connect'));
const Settings = lazy(() => import('containers/Settings'));
@ -18,8 +19,14 @@ const App = ({
select,
push,
hideMenu,
newVersionAvailable
newVersionAvailable,
hasOpenModals
}) => {
const [renderModals, setRenderModals] = useState(false);
if (!renderModals && hasOpenModals) {
setRenderModals(true);
}
const mainClass = cn('main-container', {
'off-canvas': showTabList
});
@ -54,10 +61,8 @@ const App = ({
push={push}
/>
<div className={mainClass}>
<Suspense
maxDuration={1000}
fallback={<div className="suspense-fallback">...</div>}
>
<Suspense fallback={<div className="suspense-fallback">...</div>}>
{renderModals && <Modals />}
<Route name="chat">
<Chat />
</Route>

View file

@ -0,0 +1,27 @@
import React, { useCallback } from 'react';
import withModal from 'components/modals/withModal';
import Button from 'components/ui/Button';
const Confirm = ({
payload: { question, confirmation, onConfirm },
onClose
}) => {
const handleConfirm = useCallback(() => {
onClose(false);
onConfirm();
}, []);
return (
<>
<p>{question}</p>
<Button onClick={handleConfirm}>{confirmation || 'OK'}</Button>
<Button category="normal" onClick={onClose}>
Cancel
</Button>
</>
);
};
export default withModal({
name: 'confirm'
})(Confirm);

View file

@ -0,0 +1,10 @@
import React, { memo } from 'react';
import Confirm from 'components/modals/Confirm';
const Modals = () => (
<>
<Confirm />
</>
);
export default memo(Modals, () => true);

View file

@ -0,0 +1,64 @@
import React, { useCallback } from 'react';
import Modal from 'react-modal';
import { createSelector } from 'reselect';
import { getModals, closeModal } from 'state/modals';
import connect from 'utils/connect';
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 = createSelector(
getModals,
modals => modals[name] || { payload: {} }
);
const mapDispatch = dispatch => ({
onRequestClose: () => dispatch(closeModal(name))
});
return connect(
mapState,
mapDispatch
)(ReduxModal);
};
}

View file

@ -26,10 +26,7 @@ const ChatTitle = ({
let serverError = null;
if (!tab.name && status.error) {
serverError = (
<span className="chat-topic error">
Error:
{status.error}
</span>
<span className="chat-topic error">Error: {status.error}</span>
);
}

View file

@ -1,7 +1,7 @@
import React from 'react';
const Button = ({ children, ...props }) => (
<button type="button" {...props}>
const Button = ({ children, category, ...props }) => (
<button className={`button-${category}`} type="button" {...props}>
{children}
</button>
);