UNPKG

apeman-react-mixins

Version:
156 lines (131 loc) 3.17 kB
/** * Mixin to handle stack */ import React, {PropTypes as types} from 'react' 'use strict' 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)