Add react-modal, replace confirm usage with it
This commit is contained in:
parent
63cf65100d
commit
0085cea5a1
File diff suppressed because one or more lines are too long
|
@ -57,6 +57,18 @@ button:active {
|
||||||
background: #6bb758;
|
background: #6bb758;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.button-normal {
|
||||||
|
background: #222;
|
||||||
|
}
|
||||||
|
|
||||||
|
.button-normal:hover {
|
||||||
|
background: #111;
|
||||||
|
}
|
||||||
|
|
||||||
|
.button-normal:active {
|
||||||
|
background: #222;
|
||||||
|
}
|
||||||
|
|
||||||
label {
|
label {
|
||||||
-webkit-tap-highlight-color: rgba(0, 0, 0, 0);
|
-webkit-tap-highlight-color: rgba(0, 0, 0, 0);
|
||||||
}
|
}
|
||||||
|
@ -855,6 +867,62 @@ input.message-input-nick.invalid {
|
||||||
color: #ddd;
|
color: #ddd;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.modal-overlay {
|
||||||
|
position: fixed;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
bottom: 0;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
background: rgba(0, 0, 0, 0.33);
|
||||||
|
opacity: 0;
|
||||||
|
transition: opacity 0.2s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.modal-overlay-opening {
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.modal-overlay-closing {
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.modal {
|
||||||
|
max-width: 600px;
|
||||||
|
padding: 15px;
|
||||||
|
background: #f0f0f0;
|
||||||
|
border: 1px solid #ddd;
|
||||||
|
outline: none;
|
||||||
|
margin: 15px;
|
||||||
|
text-align: center;
|
||||||
|
font-family: 'Montserrat', sans-serif;
|
||||||
|
transform: translateY(-20px);
|
||||||
|
transition: transform 0.2s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.modal-opening {
|
||||||
|
transform: translateY(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
.modal-closing {
|
||||||
|
transform: translateY(-20px);
|
||||||
|
}
|
||||||
|
|
||||||
|
.modal p {
|
||||||
|
margin-bottom: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.modal button {
|
||||||
|
width: 120px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.modal button {
|
||||||
|
margin: 0 5px;
|
||||||
|
margin-top: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
@media (max-width: 600px) {
|
@media (max-width: 600px) {
|
||||||
.tablist {
|
.tablist {
|
||||||
width: 200px;
|
width: 200px;
|
||||||
|
|
|
@ -1,9 +1,10 @@
|
||||||
import React, { Suspense, lazy } from 'react';
|
import React, { Suspense, lazy, useState } from 'react';
|
||||||
import Route from 'containers/Route';
|
import Route from 'containers/Route';
|
||||||
import AppInfo from 'components/AppInfo';
|
import AppInfo from 'components/AppInfo';
|
||||||
import TabList from 'components/TabList';
|
import TabList from 'components/TabList';
|
||||||
import cn from 'classnames';
|
import cn from 'classnames';
|
||||||
|
|
||||||
|
const Modals = lazy(() => import('components/modals'));
|
||||||
const Chat = lazy(() => import('containers/Chat'));
|
const Chat = lazy(() => import('containers/Chat'));
|
||||||
const Connect = lazy(() => import('containers/Connect'));
|
const Connect = lazy(() => import('containers/Connect'));
|
||||||
const Settings = lazy(() => import('containers/Settings'));
|
const Settings = lazy(() => import('containers/Settings'));
|
||||||
|
@ -18,8 +19,14 @@ const App = ({
|
||||||
select,
|
select,
|
||||||
push,
|
push,
|
||||||
hideMenu,
|
hideMenu,
|
||||||
newVersionAvailable
|
newVersionAvailable,
|
||||||
|
hasOpenModals
|
||||||
}) => {
|
}) => {
|
||||||
|
const [renderModals, setRenderModals] = useState(false);
|
||||||
|
if (!renderModals && hasOpenModals) {
|
||||||
|
setRenderModals(true);
|
||||||
|
}
|
||||||
|
|
||||||
const mainClass = cn('main-container', {
|
const mainClass = cn('main-container', {
|
||||||
'off-canvas': showTabList
|
'off-canvas': showTabList
|
||||||
});
|
});
|
||||||
|
@ -54,10 +61,8 @@ const App = ({
|
||||||
push={push}
|
push={push}
|
||||||
/>
|
/>
|
||||||
<div className={mainClass}>
|
<div className={mainClass}>
|
||||||
<Suspense
|
<Suspense fallback={<div className="suspense-fallback">...</div>}>
|
||||||
maxDuration={1000}
|
{renderModals && <Modals />}
|
||||||
fallback={<div className="suspense-fallback">...</div>}
|
|
||||||
>
|
|
||||||
<Route name="chat">
|
<Route name="chat">
|
||||||
<Chat />
|
<Chat />
|
||||||
</Route>
|
</Route>
|
||||||
|
|
|
@ -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);
|
|
@ -0,0 +1,10 @@
|
||||||
|
import React, { memo } from 'react';
|
||||||
|
import Confirm from 'components/modals/Confirm';
|
||||||
|
|
||||||
|
const Modals = () => (
|
||||||
|
<>
|
||||||
|
<Confirm />
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
|
||||||
|
export default memo(Modals, () => true);
|
|
@ -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);
|
||||||
|
};
|
||||||
|
}
|
|
@ -26,10 +26,7 @@ const ChatTitle = ({
|
||||||
let serverError = null;
|
let serverError = null;
|
||||||
if (!tab.name && status.error) {
|
if (!tab.name && status.error) {
|
||||||
serverError = (
|
serverError = (
|
||||||
<span className="chat-topic error">
|
<span className="chat-topic error">Error: {status.error}</span>
|
||||||
Error:
|
|
||||||
{status.error}
|
|
||||||
</span>
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
|
||||||
const Button = ({ children, ...props }) => (
|
const Button = ({ children, category, ...props }) => (
|
||||||
<button type="button" {...props}>
|
<button className={`button-${category}`} type="button" {...props}>
|
||||||
{children}
|
{children}
|
||||||
</button>
|
</button>
|
||||||
);
|
);
|
||||||
|
|
|
@ -2,6 +2,7 @@ import { createStructuredSelector } from 'reselect';
|
||||||
import App from 'components/App';
|
import App from 'components/App';
|
||||||
import { getConnected } from 'state/app';
|
import { getConnected } from 'state/app';
|
||||||
import { getSortedChannels } from 'state/channels';
|
import { getSortedChannels } from 'state/channels';
|
||||||
|
import { getHasOpenModals } from 'state/modals';
|
||||||
import { getPrivateChats } from 'state/privateChats';
|
import { getPrivateChats } from 'state/privateChats';
|
||||||
import { getServers } from 'state/servers';
|
import { getServers } from 'state/servers';
|
||||||
import { getSelectedTab, select } from 'state/tab';
|
import { getSelectedTab, select } from 'state/tab';
|
||||||
|
@ -16,7 +17,8 @@ const mapState = createStructuredSelector({
|
||||||
servers: getServers,
|
servers: getServers,
|
||||||
showTabList: getShowTabList,
|
showTabList: getShowTabList,
|
||||||
tab: getSelectedTab,
|
tab: getSelectedTab,
|
||||||
newVersionAvailable: state => state.app.newVersionAvailable
|
newVersionAvailable: state => state.app.newVersionAvailable,
|
||||||
|
hasOpenModals: getHasOpenModals
|
||||||
});
|
});
|
||||||
|
|
||||||
const mapDispatch = { push, select, hideMenu };
|
const mapDispatch = { push, select, hideMenu };
|
||||||
|
|
|
@ -7,6 +7,7 @@ import {
|
||||||
addMessage,
|
addMessage,
|
||||||
addMessages
|
addMessages
|
||||||
} from 'state/messages';
|
} from 'state/messages';
|
||||||
|
import { openModal } from 'state/modals';
|
||||||
import { reconnect } from 'state/servers';
|
import { reconnect } from 'state/servers';
|
||||||
import { select } from 'state/tab';
|
import { select } from 'state/tab';
|
||||||
import { find, normalizeChannel } from 'utils';
|
import { find, normalizeChannel } from 'utils';
|
||||||
|
@ -123,15 +124,17 @@ export default function handleSocket({
|
||||||
},
|
},
|
||||||
|
|
||||||
connection_update({ server, errorType }) {
|
connection_update({ server, errorType }) {
|
||||||
if (
|
if (errorType === 'verify') {
|
||||||
errorType === 'verify' &&
|
|
||||||
window.confirm(
|
|
||||||
'The server is using a self-signed certificate, continue anyway?'
|
|
||||||
)
|
|
||||||
) {
|
|
||||||
dispatch(
|
dispatch(
|
||||||
reconnect(server, {
|
openModal('confirm', {
|
||||||
skipVerify: true
|
question:
|
||||||
|
'The server is using a self-signed certificate, continue anyway?',
|
||||||
|
onConfirm: () =>
|
||||||
|
dispatch(
|
||||||
|
reconnect(server, {
|
||||||
|
skipVerify: true
|
||||||
|
})
|
||||||
|
)
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,6 +19,9 @@ export const FETCH_MESSAGES = 'FETCH_MESSAGES';
|
||||||
export const RAW = 'RAW';
|
export const RAW = 'RAW';
|
||||||
export const UPDATE_MESSAGE_HEIGHT = 'UPDATE_MESSAGE_HEIGHT';
|
export const UPDATE_MESSAGE_HEIGHT = 'UPDATE_MESSAGE_HEIGHT';
|
||||||
|
|
||||||
|
export const OPEN_MODAL = 'OPEN_MODAL';
|
||||||
|
export const CLOSE_MODAL = 'CLOSE_MODAL';
|
||||||
|
|
||||||
export const CLOSE_PRIVATE_CHAT = 'CLOSE_PRIVATE_CHAT';
|
export const CLOSE_PRIVATE_CHAT = 'CLOSE_PRIVATE_CHAT';
|
||||||
export const OPEN_PRIVATE_CHAT = 'OPEN_PRIVATE_CHAT';
|
export const OPEN_PRIVATE_CHAT = 'OPEN_PRIVATE_CHAT';
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
import assign from 'lodash/assign';
|
|
||||||
import createReducer from 'utils/createReducer';
|
import createReducer from 'utils/createReducer';
|
||||||
import * as actions from './actions';
|
import * as actions from './actions';
|
||||||
|
|
||||||
|
@ -31,7 +30,7 @@ const initialState = {
|
||||||
export default createReducer(initialState, {
|
export default createReducer(initialState, {
|
||||||
[actions.APP_SET](state, { key, value }) {
|
[actions.APP_SET](state, { key, value }) {
|
||||||
if (typeof key === 'object') {
|
if (typeof key === 'object') {
|
||||||
assign(state, key);
|
Object.assign(state, key);
|
||||||
} else {
|
} else {
|
||||||
state[key] = value;
|
state[key] = value;
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,6 +3,7 @@ import app from './app';
|
||||||
import channels from './channels';
|
import channels from './channels';
|
||||||
import input from './input';
|
import input from './input';
|
||||||
import messages from './messages';
|
import messages from './messages';
|
||||||
|
import modals from './modals';
|
||||||
import privateChats from './privateChats';
|
import privateChats from './privateChats';
|
||||||
import search from './search';
|
import search from './search';
|
||||||
import servers from './servers';
|
import servers from './servers';
|
||||||
|
@ -20,6 +21,7 @@ export default function createReducer(router) {
|
||||||
channels,
|
channels,
|
||||||
input,
|
input,
|
||||||
messages,
|
messages,
|
||||||
|
modals,
|
||||||
privateChats,
|
privateChats,
|
||||||
search,
|
search,
|
||||||
servers,
|
servers,
|
||||||
|
|
|
@ -0,0 +1,50 @@
|
||||||
|
import { createSelector } from 'reselect';
|
||||||
|
import createReducer from 'utils/createReducer';
|
||||||
|
import * as actions from './actions';
|
||||||
|
|
||||||
|
export const getModals = state => state.modals;
|
||||||
|
|
||||||
|
export const getHasOpenModals = createSelector(
|
||||||
|
getModals,
|
||||||
|
modals => {
|
||||||
|
const keys = Object.keys(modals);
|
||||||
|
|
||||||
|
for (let i = 0; i < keys.length; i++) {
|
||||||
|
if (modals[keys[i]].isOpen) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
export default createReducer(
|
||||||
|
{},
|
||||||
|
{
|
||||||
|
[actions.OPEN_MODAL](state, { name, payload = {} }) {
|
||||||
|
state[name] = {
|
||||||
|
isOpen: true,
|
||||||
|
payload
|
||||||
|
};
|
||||||
|
},
|
||||||
|
|
||||||
|
[actions.CLOSE_MODAL](state, { name }) {
|
||||||
|
state[name].isOpen = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
export function openModal(name, payload) {
|
||||||
|
return {
|
||||||
|
type: actions.OPEN_MODAL,
|
||||||
|
name,
|
||||||
|
payload
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export function closeModal(name) {
|
||||||
|
return {
|
||||||
|
type: actions.CLOSE_MODAL,
|
||||||
|
name
|
||||||
|
};
|
||||||
|
}
|
|
@ -1,4 +1,3 @@
|
||||||
import assign from 'lodash/assign';
|
|
||||||
import createReducer from 'utils/createReducer';
|
import createReducer from 'utils/createReducer';
|
||||||
import * as actions from './actions';
|
import * as actions from './actions';
|
||||||
|
|
||||||
|
@ -41,7 +40,7 @@ export default createReducer(
|
||||||
|
|
||||||
[actions.SETTINGS_SET](state, { key, value, settings }) {
|
[actions.SETTINGS_SET](state, { key, value, settings }) {
|
||||||
if (settings) {
|
if (settings) {
|
||||||
assign(state, settings);
|
Object.assign(state, settings);
|
||||||
} else {
|
} else {
|
||||||
state[key] = value;
|
state[key] = value;
|
||||||
}
|
}
|
||||||
|
|
|
@ -71,6 +71,7 @@
|
||||||
"react": "^16.7.0-alpha.0",
|
"react": "^16.7.0-alpha.0",
|
||||||
"react-dom": "^16.7.0-alpha.0",
|
"react-dom": "^16.7.0-alpha.0",
|
||||||
"react-hot-loader": "^4.6.3",
|
"react-hot-loader": "^4.6.3",
|
||||||
|
"react-modal": "^3.8.1",
|
||||||
"react-redux": "^6.0.0-beta.2",
|
"react-redux": "^6.0.0-beta.2",
|
||||||
"react-virtualized-auto-sizer": "^1.0.2",
|
"react-virtualized-auto-sizer": "^1.0.2",
|
||||||
"react-window": "^1.5.0",
|
"react-window": "^1.5.0",
|
||||||
|
|
|
@ -3664,6 +3664,11 @@ execa@^0.7.0:
|
||||||
signal-exit "^3.0.0"
|
signal-exit "^3.0.0"
|
||||||
strip-eof "^1.0.0"
|
strip-eof "^1.0.0"
|
||||||
|
|
||||||
|
exenv@^1.2.0:
|
||||||
|
version "1.2.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/exenv/-/exenv-1.2.2.tgz#2ae78e85d9894158670b03d47bec1f03bd91bb9d"
|
||||||
|
integrity sha1-KueOhdmJQVhnCwPUe+wfA72Ru50=
|
||||||
|
|
||||||
exit@^0.1.2:
|
exit@^0.1.2:
|
||||||
version "0.1.2"
|
version "0.1.2"
|
||||||
resolved "https://registry.yarnpkg.com/exit/-/exit-0.1.2.tgz#0632638f8d877cc82107d30a0fff1a17cba1cd0c"
|
resolved "https://registry.yarnpkg.com/exit/-/exit-0.1.2.tgz#0632638f8d877cc82107d30a0fff1a17cba1cd0c"
|
||||||
|
@ -8053,7 +8058,7 @@ prompts@^0.1.9:
|
||||||
kleur "^2.0.1"
|
kleur "^2.0.1"
|
||||||
sisteransi "^0.1.1"
|
sisteransi "^0.1.1"
|
||||||
|
|
||||||
prop-types@^15.6.1, prop-types@^15.6.2:
|
prop-types@^15.5.10, prop-types@^15.6.1, prop-types@^15.6.2:
|
||||||
version "15.6.2"
|
version "15.6.2"
|
||||||
resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.6.2.tgz#05d5ca77b4453e985d60fc7ff8c859094a497102"
|
resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.6.2.tgz#05d5ca77b4453e985d60fc7ff8c859094a497102"
|
||||||
integrity sha512-3pboPvLiWD7dkI3qf3KbUe6hKFKa52w+AE0VCqECtf+QHAKgOL37tTaNCnuX1nAAQ4ZhyP+kYVKf8rLmJ/feDQ==
|
integrity sha512-3pboPvLiWD7dkI3qf3KbUe6hKFKa52w+AE0VCqECtf+QHAKgOL37tTaNCnuX1nAAQ4ZhyP+kYVKf8rLmJ/feDQ==
|
||||||
|
@ -8268,11 +8273,21 @@ react-is@^16.7.0-alpha.2:
|
||||||
resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.7.0-alpha.2.tgz#0dd7f95d45ad5318b7f7bcb99dcb84da9385cb57"
|
resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.7.0-alpha.2.tgz#0dd7f95d45ad5318b7f7bcb99dcb84da9385cb57"
|
||||||
integrity sha512-1Q3qN8nMWUfFcRz/bBC1f9zSL3il9OcSxMd9CNnpJbeFf4VCX0qYxL3TuwT4f+tFk1TkidwIL11yYgk4HjldYg==
|
integrity sha512-1Q3qN8nMWUfFcRz/bBC1f9zSL3il9OcSxMd9CNnpJbeFf4VCX0qYxL3TuwT4f+tFk1TkidwIL11yYgk4HjldYg==
|
||||||
|
|
||||||
react-lifecycles-compat@^3.0.4:
|
react-lifecycles-compat@^3.0.0, react-lifecycles-compat@^3.0.4:
|
||||||
version "3.0.4"
|
version "3.0.4"
|
||||||
resolved "https://registry.yarnpkg.com/react-lifecycles-compat/-/react-lifecycles-compat-3.0.4.tgz#4f1a273afdfc8f3488a8c516bfda78f872352362"
|
resolved "https://registry.yarnpkg.com/react-lifecycles-compat/-/react-lifecycles-compat-3.0.4.tgz#4f1a273afdfc8f3488a8c516bfda78f872352362"
|
||||||
integrity sha512-fBASbA6LnOU9dOU2eW7aQ8xmYBSXUIWr+UmF9b1efZBazGNO+rcXT/icdKnYm2pTwcRylVUYwW7H1PHfLekVzA==
|
integrity sha512-fBASbA6LnOU9dOU2eW7aQ8xmYBSXUIWr+UmF9b1efZBazGNO+rcXT/icdKnYm2pTwcRylVUYwW7H1PHfLekVzA==
|
||||||
|
|
||||||
|
react-modal@^3.8.1:
|
||||||
|
version "3.8.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/react-modal/-/react-modal-3.8.1.tgz#7300f94a6f92a2e17994de0be6ccb61734464c9e"
|
||||||
|
integrity sha512-aLKeZM9pgXpIKVwopRHMuvqKWiBajkqisDA8UzocdCF6S4fyKVfLWmZR5G1Q0ODBxxxxf2XIwiCP8G/11GJAuw==
|
||||||
|
dependencies:
|
||||||
|
exenv "^1.2.0"
|
||||||
|
prop-types "^15.5.10"
|
||||||
|
react-lifecycles-compat "^3.0.0"
|
||||||
|
warning "^3.0.0"
|
||||||
|
|
||||||
react-redux@^6.0.0-beta.2:
|
react-redux@^6.0.0-beta.2:
|
||||||
version "6.0.0"
|
version "6.0.0"
|
||||||
resolved "https://registry.yarnpkg.com/react-redux/-/react-redux-6.0.0.tgz#09e86eeed5febb98e9442458ad2970c8f1a173ef"
|
resolved "https://registry.yarnpkg.com/react-redux/-/react-redux-6.0.0.tgz#09e86eeed5febb98e9442458ad2970c8f1a173ef"
|
||||||
|
|
Loading…
Reference in New Issue