instantjob-recruiter-client
Version:
a set of tools for creating an instantjob recruiter react client
120 lines (101 loc) • 2.44 kB
JSX
import React, {Component} from 'react'
import styled from 'styled-components'
import {position} from 'polished'
import Button from 'components/utils/button'
import auto_bind from 'common/auto_bind'
import {color, acceleration, desceleration} from 'common/styles'
const modals = []
let after_update = () => {}
export function add_modal(modal) {
modals.push(modal)
after_update()
}
const dismissers = []
export function dismiss_front_modal() {
const dismiss = dismissers.pop()
dismiss()
}
function dismiss_front_modal_immediately() {
modals.pop()
after_update()
}
export default class Modals extends Component {
constructor(props) {
super(props)
auto_bind(this)
}
componentDidMount() {
after_update = this.after_update
}
componentWillUpdate() {
after_update = this.after_update
}
after_update() {
this.forceUpdate()
}
render_modal(modal, id) {
return <Modal key={id} component={modal} />
}
render() {
if (modals.length) {
return (
<Frame>
{modals.map(this.render_modal)}
</Frame>
)
}
return null
}
}
class Modal extends Component {
constructor(props) {
super(props)
this.state = {
mounted: false,
}
auto_bind(this)
}
componentDidMount() {
dismissers.push(this.dismiss)
setTimeout(() => this.setState({mounted: true}), 10)
}
dismiss() {
setTimeout(dismiss_front_modal_immediately, 400)
this.setState({mounted: false})
}
render() {
const {mounted} = this.state
const {component: Content} = this.props
return (
<Container mounted={mounted}>
<Header>
<Button onClick={dismiss_front_modal} back>
Retour
</Button>
</Header>
<ContentContainer>
<Content />
</ContentContainer>
</Container>
)
}
}
const Frame = styled.div`
${position('absolute', '0', '0', '0', '0')}
`
const Container = styled.div`
${position('absolute', '0', '0', '0', '0')}
background-color: ${color('black', 'translucent')};
overflow: scroll;
transform: translate(0, ${({mounted}) => mounted ? '0' : '100%'});
transition: transform 400ms ${({mounted}) => mounted ? desceleration : acceleration};
box-shadow: 0 0 3px ${color('black', 'normal', 0.25)};
& > * {
margin: 0 40px 40px 40px;
}
`
const Header = styled.div`
margin-top: 40px;
`
const ContentContainer = styled.div`
`