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
10 years ago
|
"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;
|