react-bootstrap
Version:
Bootstrap 3 components build with React
228 lines (178 loc) • 7.11 kB
JavaScript
'use strict';
var _inherits = require('babel-runtime/helpers/inherits')['default'];
var _classCallCheck = require('babel-runtime/helpers/class-call-check')['default'];
var _extends = require('babel-runtime/helpers/extends')['default'];
var _interopRequireDefault = require('babel-runtime/helpers/interop-require-default')['default'];
exports.__esModule = true;
var _react = require('react');
var _react2 = _interopRequireDefault(_react);
var _Transition = require('./Transition');
var _Transition2 = _interopRequireDefault(_Transition);
var _utilsDomUtils = require('./utils/domUtils');
var _utilsDomUtils2 = _interopRequireDefault(_utilsDomUtils);
var _utilsCreateChainedFunction = require('./utils/createChainedFunction');
var _utilsCreateChainedFunction2 = _interopRequireDefault(_utilsCreateChainedFunction);
var capitalize = function capitalize(str) {
return str[0].toUpperCase() + str.substr(1);
};
// reading a dimension prop will cause the browser to recalculate,
// which will let our animations work
var triggerBrowserReflow = function triggerBrowserReflow(node) {
return node.offsetHeight;
};
var MARGINS = {
height: ['marginTop', 'marginBottom'],
width: ['marginLeft', 'marginRight']
};
function getDimensionValue(dimension, elem) {
var value = elem['offset' + capitalize(dimension)];
var computedStyles = _utilsDomUtils2['default'].getComputedStyles(elem);
var margins = MARGINS[dimension];
return value + parseInt(computedStyles[margins[0]], 10) + parseInt(computedStyles[margins[1]], 10);
}
var Collapse = (function (_React$Component) {
_inherits(Collapse, _React$Component);
function Collapse(props, context) {
_classCallCheck(this, Collapse);
_React$Component.call(this, props, context);
this.onEnterListener = this.handleEnter.bind(this);
this.onEnteringListener = this.handleEntering.bind(this);
this.onEnteredListener = this.handleEntered.bind(this);
this.onExitListener = this.handleExit.bind(this);
this.onExitingListener = this.handleExiting.bind(this);
}
// Explicitly copied from Transition for doc generation.
// TODO: Remove duplication once #977 is resolved.
Collapse.prototype.render = function render() {
var enter = _utilsCreateChainedFunction2['default'](this.onEnterListener, this.props.onEnter);
var entering = _utilsCreateChainedFunction2['default'](this.onEnteringListener, this.props.onEntering);
var entered = _utilsCreateChainedFunction2['default'](this.onEnteredListener, this.props.onEntered);
var exit = _utilsCreateChainedFunction2['default'](this.onExitListener, this.props.onExit);
var exiting = _utilsCreateChainedFunction2['default'](this.onExitingListener, this.props.onExiting);
return _react2['default'].createElement(
_Transition2['default'],
_extends({
ref: 'transition'
}, this.props, {
'aria-expanded': this.props['in'],
className: this._dimension() === 'width' ? 'width' : '',
exitedClassName: 'collapse',
exitingClassName: 'collapsing',
enteredClassName: 'collapse in',
enteringClassName: 'collapsing',
onEnter: enter,
onEntering: entering,
onEntered: entered,
onExit: exit,
onExiting: exiting,
onExited: this.props.onExited
}),
this.props.children
);
};
/* -- Expanding -- */
Collapse.prototype.handleEnter = function handleEnter(elem) {
var dimension = this._dimension();
elem.style[dimension] = '0';
};
Collapse.prototype.handleEntering = function handleEntering(elem) {
var dimension = this._dimension();
elem.style[dimension] = this._getScrollDimensionValue(elem, dimension);
};
Collapse.prototype.handleEntered = function handleEntered(elem) {
var dimension = this._dimension();
elem.style[dimension] = null;
};
/* -- Collapsing -- */
Collapse.prototype.handleExit = function handleExit(elem) {
var dimension = this._dimension();
elem.style[dimension] = this.props.getDimensionValue(dimension, elem) + 'px';
};
Collapse.prototype.handleExiting = function handleExiting(elem) {
var dimension = this._dimension();
triggerBrowserReflow(elem);
elem.style[dimension] = '0';
};
Collapse.prototype._dimension = function _dimension() {
return typeof this.props.dimension === 'function' ? this.props.dimension() : this.props.dimension;
};
//for testing
Collapse.prototype._getTransitionInstance = function _getTransitionInstance() {
return this.refs.transition;
};
Collapse.prototype._getScrollDimensionValue = function _getScrollDimensionValue(elem, dimension) {
return elem['scroll' + capitalize(dimension)] + 'px';
};
return Collapse;
})(_react2['default'].Component);
Collapse.propTypes = {
/**
* Show the component; triggers the expand or collapse animation
*/
'in': _react2['default'].PropTypes.bool,
/**
* Unmount the component (remove it from the DOM) when it is collapsed
*/
unmountOnExit: _react2['default'].PropTypes.bool,
/**
* Run the expand animation when the component mounts, if it is initially
* shown
*/
transitionAppear: _react2['default'].PropTypes.bool,
/**
* Duration of the collapse animation in milliseconds, to ensure that
* finishing callbacks are fired even if the original browser transition end
* events are canceled
*/
duration: _react2['default'].PropTypes.number,
/**
* Callback fired before the component expands
*/
onEnter: _react2['default'].PropTypes.func,
/**
* Callback fired after the component starts to expand
*/
onEntering: _react2['default'].PropTypes.func,
/**
* Callback fired after the component has expanded
*/
onEntered: _react2['default'].PropTypes.func,
/**
* Callback fired before the component collapses
*/
onExit: _react2['default'].PropTypes.func,
/**
* Callback fired after the component starts to collapse
*/
onExiting: _react2['default'].PropTypes.func,
/**
* Callback fired after the component has collapsed
*/
onExited: _react2['default'].PropTypes.func,
/**
* The dimension used when collapsing, or a function that returns the
* dimension
*
* _Note: Bootstrap only partially supports 'width'!
* You will need to supply your own CSS animation for the `.width` CSS class._
*/
dimension: _react2['default'].PropTypes.oneOfType([_react2['default'].PropTypes.oneOf(['height', 'width']), _react2['default'].PropTypes.func]),
/**
* Function that returns the height or width of the animating DOM node
*
* Allows for providing some custom logic for how much the Collapse component
* should animate in its specified dimension. Called with the current
* dimension prop value and the DOM node.
*/
getDimensionValue: _react2['default'].PropTypes.func
};
Collapse.defaultProps = {
'in': false,
duration: 300,
unmountOnExit: false,
transitionAppear: false,
dimension: 'height',
getDimensionValue: getDimensionValue
};
exports['default'] = Collapse;
module.exports = exports['default'];