Last active
December 27, 2017 16:29
-
-
Save thomasmaclean/9032227db3911fc563cea2c564e3b609 to your computer and use it in GitHub Desktop.
Redux Alert system
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import React, { Component } from 'react'; | |
import CookieWarning from './CookieWarning'; | |
import PushDown from './PushDown'; | |
export default class Alerts extends Component { | |
render() { | |
require('src/sass/components/push-down-notifications.scss'); | |
return ( | |
<PushDown> | |
<CookieWarning><button /></CookieWarning> | |
</PushDown> | |
); | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import React, { Component, PropTypes } from 'react'; | |
const enhanceWithClickOutside = require('react-click-outside'); | |
class AlertWrapper extends Component { | |
static propTypes = { | |
children: PropTypes.node, | |
className: PropTypes.string, | |
onClickOutside: PropTypes.func | |
}; | |
handleClickOutside() { | |
this.props.onClickOutside(); | |
} | |
render() { | |
return (<div className={this.props.className}>{this.props.children}</div>); | |
} | |
} | |
export default enhanceWithClickOutside(AlertWrapper); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import React, { Component, PropTypes } from 'react'; | |
import AlertWrapper from './AlertWrapper'; | |
import classnames from 'classnames'; | |
import { connect } from 'react-redux'; | |
import { closeAlert } from './redux-alert'; | |
class PushDown extends Component { | |
static propTypes = { | |
children: PropTypes.node, | |
active: PropTypes.string, | |
registry: PropTypes.object, | |
closeAlert: PropTypes.func | |
}; | |
componentDidMount() { | |
this.body = document.querySelector('body'); | |
this.nav = document.querySelector('.nav'); | |
this.showHide(); | |
} | |
componentDidUpdate() { | |
this.showHide(); | |
} | |
alertClass = 'push-down__content-wrapper'; | |
showHide() { | |
const { active, registry } = this.props; | |
const alertWrapper = document.querySelector(`.${this.alertClass}`); | |
if (!!active) { | |
const alertInfo = registry[active]; | |
const alert = document.querySelector(`.${this.alertClass} .alert`); | |
const contentHeight = `${alertInfo.height || alert.offsetHeight}px`; | |
window.setTimeout(() => { alertWrapper.style.overflow = 'visible'; }, 250); | |
alertWrapper.style.height = contentHeight; | |
this.refs.container.style.height = contentHeight; | |
this.refs.overlay.style.transform = `translateY(${contentHeight}px)`; | |
this.body.style.overflow = 'hidden'; | |
this.body.style.width = 'auto'; | |
this.nav.style.top = contentHeight; | |
} else { | |
alertWrapper.style.height = 0; | |
alertWrapper.style.removeProperty('overflow'); | |
this.refs.container.style.height = 0; | |
this.refs.overlay.style.transform = `translateY(0px)`; | |
this.body.style.removeProperty('width'); | |
this.body.style.removeProperty('overflow'); | |
this.nav.style.removeProperty('top'); | |
} | |
} | |
render() { | |
const { active, children } = this.props; | |
const pushDownWrapperClass = classnames('push-down__container', { alert__active: !!active }); | |
return ( | |
<div className={pushDownWrapperClass} ref="container"> | |
<div className="push-down__overlay" ref="overlay"></div> | |
<div className="push-down__close alert-close" onClick={this.props.closeAlert}></div> | |
<AlertWrapper onClickOutside={this.props.closeAlert} className={this.alertClass}> | |
{children} | |
</AlertWrapper> | |
</div> | |
); | |
} | |
} | |
export default connect(state => ({ | |
active: state.alert.active, | |
registry: state.alert.registry | |
}), { closeAlert })(PushDown) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const ALERT_REGISTER = 'alert/register'; | |
const ALERT_OPEN = 'alert/open'; | |
const ALERT_CLOSE = 'alert/close'; | |
const initialState = { | |
registry: {}, | |
active: '', | |
queue: [] | |
}; | |
export default function reducer(state = initialState, action = {}) { | |
switch (action.type) { | |
case ALERT_REGISTER: | |
return { | |
...state, | |
registry: { | |
...state.registry, | |
...action.alertInfo | |
} | |
}; | |
case ALERT_OPEN: | |
return (state.active && state.alert !== action.alert && action.alert) ? { | |
...state, | |
queue: [...state.queue, action.alert] | |
} : { | |
...state, | |
active: action.alert | |
}; | |
case ALERT_CLOSE: | |
return (state.queue) ? { | |
...state, | |
queue: state.queue.slice(1), | |
active: state.queue[0] || '' | |
} : { | |
active: '' | |
}; | |
default: | |
return state; | |
} | |
} | |
export function registerAlert(name, info = {}) { | |
const alertInfo = {}; | |
alertInfo[name] = info; | |
return { | |
type: ALERT_REGISTER, | |
alertInfo | |
}; | |
} | |
export function openAlert(name) { | |
return { | |
type: ALERT_OPEN, | |
alert: name | |
}; | |
} | |
export function closeAlert() { | |
return { | |
type: ALERT_CLOSE | |
}; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment