apeman-react-mixins
Version:
React mixin set of apeman.
156 lines (131 loc) • 3.17 kB
JSX
/**
* Mixin to handle stack
*/
import React, {PropTypes as types} from 'react'
const INSETS_STATE_KEY = '_apStackInsets'
/** @lends ApStackMixin */
const ApStackMixin = {
// --------------------
// Custom
// --------------------
$apStackMixed: true,
/**
* Get insets of the stack.
* @returns {object}
*/
getStackInsets () {
const s = this
return s.state[ INSETS_STATE_KEY ] || {}
},
/**
* Set insets of the stack.
* @param {object} nextInsets - Insets to set.
*/
setStackInsets (nextInsets) {
const s = this
let insets = s.getStackInsets()
s.setState({
[INSETS_STATE_KEY]: Object.assign(insets, nextInsets)
})
},
/**
* Bind stacker events.
* @param {Stacker} stacker - A stacker instance.
*/
bindStacker (stacker) {
const s = this
s._addStackerListener(stacker, 'push', s.stackedViewDidPush)
s._addStackerListener(stacker, 'pop', s.stackedViewDidPop)
},
/**
* Unbind stacker events.
* @param {Stacker} stacker - A stacker instance.
*/
unbindStacker (stacker) {
const s = this
s._removeStackerListener(stacker, 'push', s.stackedViewDidPush)
s._removeStackerListener(stacker, 'pop', s.stackedViewDidPop)
},
/**
* Get width of scrollable content in the top view.
* @returns {number|null}
*/
getStackedScrollWidth () {
const s = this
let { stacker } = s.props
let topView = stacker && stacker.topView()
if (!topView) {
return null
}
let wrapElm = document && document.getElementById(`view-wrap-${topView.id}`)
if (!wrapElm) {
return null
}
let bodyElm = wrapElm.querySelector('.ap-view-body')
if (!bodyElm) {
return null
}
return bodyElm.scrollWidth || null
},
// --------------------
// Specs
// --------------------
statics: {},
propTypes: {
stacker: types.object.isRequired,
stackInsets: types.object
},
getInitialState () {
return {
[INSETS_STATE_KEY]: {}
}
},
// --------------------
// Lifecycle
// --------------------
componentWillMount () {
const s = this
let { props } = s
s.bindStacker(props.stacker)
},
componentDidMount () {
const s = this
let { props } = s
if (props.stackInsets) {
s.setStackInsets(props.stackInsets)
}
},
componentWillReceiveProps (nextProps) {
const s = this
let { props } = s
if (nextProps.stackInsets) {
s.setStackInsets(nextProps.stackInsets)
}
if (nextProps.stacker) {
s.unbindStacker(props.stacker)
s.bindStacker(nextProps.stacker)
}
},
componentWillUnmount () {
const s = this
let { props } = s
s.unbindStacker(props.stacker)
},
// ------------------
// Private
// ------------------
_addStackerListener (stacker, event, listner) {
const s = this
if (listner && stacker) {
stacker.addListener(event, listner)
}
},
_removeStackerListener (stacker, event, listner) {
const s = this
if (listner && stacker) {
stacker.removeListener(event, listner)
}
}
}
export default Object.freeze(ApStackMixin)