You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
170 lines
4.7 KiB
170 lines
4.7 KiB
"use strict"; |
|
|
|
var _interopRequire = function (obj) { return obj && obj.__esModule ? obj["default"] : obj; }; |
|
|
|
var React = _interopRequire(require("react")); |
|
|
|
var TransitionEvents = _interopRequire(require("react/lib/ReactTransitionEvents")); |
|
|
|
var CollapsableMixin = { |
|
|
|
propTypes: { |
|
defaultExpanded: React.PropTypes.bool, |
|
expanded: React.PropTypes.bool |
|
}, |
|
|
|
getInitialState: function getInitialState() { |
|
var defaultExpanded = this.props.defaultExpanded != null ? this.props.defaultExpanded : this.props.expanded != null ? this.props.expanded : false; |
|
|
|
return { |
|
expanded: defaultExpanded, |
|
collapsing: false |
|
}; |
|
}, |
|
|
|
componentWillUpdate: function componentWillUpdate(nextProps, nextState) { |
|
var willExpanded = nextProps.expanded != null ? nextProps.expanded : nextState.expanded; |
|
if (willExpanded === this.isExpanded()) { |
|
return; |
|
} |
|
|
|
// if the expanded state is being toggled, ensure node has a dimension value |
|
// this is needed for the animation to work and needs to be set before |
|
// the collapsing class is applied (after collapsing is applied the in class |
|
// is removed and the node's dimension will be wrong) |
|
|
|
var node = this.getCollapsableDOMNode(); |
|
var dimension = this.dimension(); |
|
var value = "0"; |
|
|
|
if (!willExpanded) { |
|
value = this.getCollapsableDimensionValue(); |
|
} |
|
|
|
node.style[dimension] = value + "px"; |
|
|
|
this._afterWillUpdate(); |
|
}, |
|
|
|
componentDidUpdate: function componentDidUpdate(prevProps, prevState) { |
|
// check if expanded is being toggled; if so, set collapsing |
|
this._checkToggleCollapsing(prevProps, prevState); |
|
|
|
// check if collapsing was turned on; if so, start animation |
|
this._checkStartAnimation(); |
|
}, |
|
|
|
// helps enable test stubs |
|
_afterWillUpdate: function _afterWillUpdate() {}, |
|
|
|
_checkStartAnimation: function _checkStartAnimation() { |
|
if (!this.state.collapsing) { |
|
return; |
|
} |
|
|
|
var node = this.getCollapsableDOMNode(); |
|
var dimension = this.dimension(); |
|
var value = this.getCollapsableDimensionValue(); |
|
|
|
// setting the dimension here starts the transition animation |
|
var result = undefined; |
|
if (this.isExpanded()) { |
|
result = value + "px"; |
|
} else { |
|
result = "0px"; |
|
} |
|
node.style[dimension] = result; |
|
}, |
|
|
|
_checkToggleCollapsing: function _checkToggleCollapsing(prevProps, prevState) { |
|
var wasExpanded = prevProps.expanded != null ? prevProps.expanded : prevState.expanded; |
|
var isExpanded = this.isExpanded(); |
|
if (wasExpanded !== isExpanded) { |
|
if (wasExpanded) { |
|
this._handleCollapse(); |
|
} else { |
|
this._handleExpand(); |
|
} |
|
} |
|
}, |
|
|
|
_handleExpand: function _handleExpand() { |
|
var _this = this; |
|
|
|
var node = this.getCollapsableDOMNode(); |
|
var dimension = this.dimension(); |
|
|
|
var complete = function () { |
|
_this._removeEndEventListener(node, complete); |
|
// remove dimension value - this ensures the collapsable item can grow |
|
// in dimension after initial display (such as an image loading) |
|
node.style[dimension] = ""; |
|
_this.setState({ |
|
collapsing: false |
|
}); |
|
}; |
|
|
|
this._addEndEventListener(node, complete); |
|
|
|
this.setState({ |
|
collapsing: true |
|
}); |
|
}, |
|
|
|
_handleCollapse: function _handleCollapse() { |
|
var _this = this; |
|
|
|
var node = this.getCollapsableDOMNode(); |
|
|
|
var complete = function () { |
|
_this._removeEndEventListener(node, complete); |
|
_this.setState({ |
|
collapsing: false |
|
}); |
|
}; |
|
|
|
this._addEndEventListener(node, complete); |
|
|
|
this.setState({ |
|
collapsing: true |
|
}); |
|
}, |
|
|
|
// helps enable test stubs |
|
_addEndEventListener: function _addEndEventListener(node, complete) { |
|
TransitionEvents.addEndEventListener(node, complete); |
|
}, |
|
|
|
// helps enable test stubs |
|
_removeEndEventListener: function _removeEndEventListener(node, complete) { |
|
TransitionEvents.removeEndEventListener(node, complete); |
|
}, |
|
|
|
dimension: function dimension() { |
|
return typeof this.getCollapsableDimension === "function" ? this.getCollapsableDimension() : "height"; |
|
}, |
|
|
|
isExpanded: function isExpanded() { |
|
return this.props.expanded != null ? this.props.expanded : this.state.expanded; |
|
}, |
|
|
|
getCollapsableClassSet: function getCollapsableClassSet(className) { |
|
var classes = {}; |
|
|
|
if (typeof className === "string") { |
|
className.split(" ").forEach(function (subClasses) { |
|
if (subClasses) { |
|
classes[subClasses] = true; |
|
} |
|
}); |
|
} |
|
|
|
classes.collapsing = this.state.collapsing; |
|
classes.collapse = !this.state.collapsing; |
|
classes["in"] = this.isExpanded() && !this.state.collapsing; |
|
|
|
return classes; |
|
} |
|
}; |
|
|
|
module.exports = CollapsableMixin; |