Skip to content

Instantly share code, notes, and snippets.

@lexfrl
Last active September 12, 2016 13:48
Show Gist options
  • Save lexfrl/dca5f662a7360a17dfc47e4423a31c32 to your computer and use it in GitHub Desktop.
Save lexfrl/dca5f662a7360a17dfc47e4423a31c32 to your computer and use it in GitHub Desktop.
React Overlay Impl (useful for Modals and Popovers)
import React, { PropTypes } from 'react'
import { OverlayMountPoint, OverlayView, OverlayToggle } from './overlay'
function somewhereOnTheTopOffTheAppTree() {
return (
<div>
<OverlayMountPoint /> // SnapshotsEditDialog will be rendered here
</div>
)
}
function exampleComponent(props) {
return (
<div>
<OverlayView name="EditSnapshots" renderFn={({hide}) =>
<Modal>
<SnapshotsEditDialog service={ props.service } hideModal={ hide } />
</Modal>} />} />
<OverlayToggle renderFn={({show}) =>
<Icon type="edit" onClick={() => show('EditSnapshots')} />} />
</div>
)
}
import React, { PropTypes } from 'react'
import { connect } from 'react-redux'
import { bindActionCreators } from 'redux'
import { ACTIONS } from './reducer'
export const OverlayMountPoint = connect(
({overlay}) => overlay,
dispatch => bindActionCreators(ACTIONS, dispatch)
)(({ renderFn, // from props
views, displaying, show, hide}) => { // from redux
return renderFn ? renderFn({views, displaying, show, hide})
: (views[displaying] ? views[displaying]({show, hide, displaying, views}) : <noscript />)
})
export const OverlayView = connect(
({overlay}) => overlay,
dispatch => bindActionCreators(ACTIONS, dispatch)
)((React.createClass({
componentWillMount() {
this.props.register(this.props.name, this.props.renderFn)
},
componentWillReceiveProps(newProps) {
if (newProps.renderFn !== this.props.renderFn) {
this.props.register(this.props.name, newProps.renderFn)
}
},
render() {
return <noscript />
}
})))
export const OverlayToggle = connect(
({overlay}) => overlay,
dispatch => bindActionCreators(ACTIONS, dispatch)
)(({ renderFn, // from props
displaying, show, hide, // from redux
}) => {
return renderFn({ show, hide, displaying })
})
import { handleActions } from 'redux-actions'
import { createAction } from 'redux-actions'
export const ACTIONS = {
register: createAction('OVERLAY_VIEW_REGISTER', (name, renderFn) => ({ name, renderFn })),
toggle: createAction('OVERLAY_VIEW_TOGGLE'),
show: createAction('OVERLAY_VIEW_SHOW'),
hide: createAction('OVERLAY_VIEW_HIDE'),
}
export default handleActions({
'OVERLAY_VIEW_REGISTER': ({views, ...state}, { payload: { name, renderFn } }) => {
views = {...views, [name]: renderFn }
return {...state, views}
},
'OVERLAY_VIEW_SHOW': ({displaying, ...state}, { payload: name}) => {
return {...state, displaying: name }
},
'OVERLAY_VIEW_HIDE': ({displaying, ...state}, { payload: name }) => {
return {...state, displaying: null }
},
}, {
displaying: null,
views: {},
})
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment