Browse Source
and make use of it in the SideBar component, to open the send and receive modals.master
meriadec
7 years ago
10 changed files with 244 additions and 9 deletions
@ -0,0 +1,13 @@ |
|||
// @flow
|
|||
|
|||
import React, { PureComponent } from 'react' |
|||
|
|||
import Modal from 'components/base/Modal' |
|||
|
|||
class ReceiveModal extends PureComponent { |
|||
render() { |
|||
return <Modal name="receive">receive modal</Modal> |
|||
} |
|||
} |
|||
|
|||
export default ReceiveModal |
@ -0,0 +1,13 @@ |
|||
// @flow
|
|||
|
|||
import React, { PureComponent } from 'react' |
|||
|
|||
import Modal from 'components/base/Modal' |
|||
|
|||
class SendModal extends PureComponent { |
|||
render() { |
|||
return <Modal name="send">send modal</Modal> |
|||
} |
|||
} |
|||
|
|||
export default SendModal |
@ -0,0 +1,98 @@ |
|||
// @flow
|
|||
/* eslint-disable jsx-a11y/click-events-have-key-events */ |
|||
/* eslint-disable jsx-a11y/no-static-element-interactions */ |
|||
|
|||
import React, { PureComponent } from 'react' |
|||
import { connect } from 'react-redux' |
|||
import Mortal from 'react-mortal' |
|||
import styled from 'styled-components' |
|||
|
|||
import { closeModal, isModalOpened } from 'reducers/modals' |
|||
|
|||
type Props = { |
|||
isOpened: boolean, |
|||
onClose: Function, |
|||
children: any, |
|||
} |
|||
|
|||
const springConfig = { |
|||
stiffness: 350, |
|||
} |
|||
|
|||
const mapStateToProps = (state, { name, isOpened }) => ({ |
|||
isOpened: isOpened || (name && isModalOpened(state, name)), |
|||
}) |
|||
|
|||
const mapDispatchToProps = (dispatch, { name }) => ({ |
|||
onClose: name ? () => dispatch(closeModal(name)) : undefined, |
|||
}) |
|||
|
|||
const Container = styled.div.attrs({ |
|||
style: p => ({ |
|||
pointerEvents: p.isVisible ? 'auto' : 'none', |
|||
}), |
|||
})` |
|||
position: fixed; |
|||
z-index: 1; |
|||
top: 0; |
|||
left: 0; |
|||
right: 0; |
|||
bottom: 0; |
|||
overflow: hidden; |
|||
display: flex; |
|||
align-items: flex-start; |
|||
justify-content: center; |
|||
` |
|||
|
|||
const Backdrop = styled.div.attrs({ |
|||
style: p => ({ |
|||
opacity: p.op, |
|||
}), |
|||
})` |
|||
position: fixed; |
|||
top: 0; |
|||
left: 0; |
|||
right: 0; |
|||
bottom: 0; |
|||
background: rgba(0, 0, 0, 0.4); |
|||
` |
|||
|
|||
const Body = styled.div.attrs({ |
|||
style: p => ({ |
|||
opacity: p.op, |
|||
transform: `translate3d(0, ${p.offset}px, 0)`, |
|||
}), |
|||
})` |
|||
padding: 20px; |
|||
margin-top: 100px; |
|||
background: white; |
|||
width: 400px; |
|||
z-index: 2; |
|||
` |
|||
|
|||
class Modal extends PureComponent<Props> { |
|||
render() { |
|||
const { isOpened, onClose, children } = this.props |
|||
return ( |
|||
<Mortal |
|||
isOpened={isOpened} |
|||
onClose={onClose} |
|||
motionStyle={(spring, isVisible) => ({ |
|||
opacity: spring(isVisible ? 1 : 0, springConfig), |
|||
y: spring(isVisible ? 0 : 20, springConfig), |
|||
})} |
|||
> |
|||
{(m, isVisible) => ( |
|||
<Container isVisible={isVisible}> |
|||
<Backdrop op={m.opacity} onClick={onClose} /> |
|||
<Body op={m.opacity} offset={m.y}> |
|||
{children} |
|||
</Body> |
|||
</Container> |
|||
)} |
|||
</Mortal> |
|||
) |
|||
} |
|||
} |
|||
|
|||
export default connect(mapStateToProps, mapDispatchToProps)(Modal) |
@ -0,0 +1,50 @@ |
|||
// @flow
|
|||
|
|||
import { handleActions, createAction } from 'redux-actions' |
|||
|
|||
const state = {} |
|||
|
|||
type OpenPayload = { |
|||
name: string, |
|||
data?: Object | null, |
|||
} |
|||
|
|||
type ClosePayload = { |
|||
name: string, |
|||
} |
|||
|
|||
const handlers = { |
|||
MODAL_OPEN: (state, { payload }: { payload: OpenPayload }) => { |
|||
const { name, data } = payload |
|||
return { |
|||
...state, |
|||
[name]: { |
|||
isOpened: true, |
|||
data, |
|||
}, |
|||
} |
|||
}, |
|||
MODAL_CLOSE: (state, { payload }: { payload: ClosePayload }) => { |
|||
const { name } = payload |
|||
return { |
|||
...state, |
|||
[name]: { |
|||
isOpened: false, |
|||
data: null, |
|||
}, |
|||
} |
|||
}, |
|||
} |
|||
|
|||
// Actions
|
|||
|
|||
export const openModal = createAction('MODAL_OPEN', (name, data = {}) => ({ name, data })) |
|||
export const closeModal = createAction('MODAL_CLOSE', name => ({ name })) |
|||
|
|||
// Selectors
|
|||
|
|||
export const isModalOpened = (state, name) => state.modals[name] && state.modals[name].isOpened |
|||
|
|||
// Exporting reducer
|
|||
|
|||
export default handleActions(handlers, state) |
Loading…
Reference in new issue