UNPKG

react-accordion-with-header

Version:
180 lines (139 loc) 6.63 kB
'use strict'; exports.__esModule = true; exports.default = undefined; var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; var _react = require('react'); var _react2 = _interopRequireDefault(_react); var _propTypes = require('prop-types'); var _propTypes2 = _interopRequireDefault(_propTypes); var _classnames = require('classnames'); var _classnames2 = _interopRequireDefault(_classnames); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } var defaultProps = { speed: 250 }; var defaultStyle = { overflow: 'hidden', padding: 0 }; var AccordionPanel = function (_PureComponent) { _inherits(AccordionPanel, _PureComponent); function AccordionPanel() { var _temp, _this, _ret; _classCallCheck(this, AccordionPanel); for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) { args[_key] = arguments[_key]; } return _ret = (_temp = (_this = _possibleConstructorReturn(this, _PureComponent.call.apply(_PureComponent, [this].concat(args))), _this), _this.state = { panelHeight: 0 }, _this.preloadImages = function () { var images = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : []; var imagesLoaded = 0; var imgLoaded = function imgLoaded(data) { imagesLoaded++; if (imagesLoaded === images.length) _this.calcHeight(); }; images.forEach(function (element) { var img = new Image(); img.src = element.src; img.onload = img.onerror = imgLoaded; }); }, _this.calcHeight = function () { if (_this.componentRef) { var _panelHeight = _this.componentRef.current.clientHeight; _this.setState({ panelHeight: _panelHeight }); return; } var panelHeight = _react.Children.map(_this.props.children, function (child, i) { return _this.refs['item-' + child.props.key]; }).reduce(function (previousValue, child) { return previousValue + child.clientHeight; }, _this.state.panelHeight); _this.setState({ panelHeight: panelHeight }); }, _this.renderChildren = function () { if (!_this.props.template && !_this.props.children) { throw new Error('AccordionPanel must have at least one child!'); } /*************************************************************** create a ref so we calculate its height on componentDidMount() this way we know how high to expand the panel ***************************************************************/ var wrapComponent = function wrapComponent(components) { return _react.Children.map(components, function (child, index) { var WrappedComponent = _react2.default.forwardRef(function (props, ref) { _this.componentRef = ref; return _react2.default.createElement( 'div', { ref: ref }, child ); }); var ref = _react2.default.createRef(); return _react2.default.createElement(WrappedComponent, { ref: ref }); }); }; if (_this.props.template) { // for template prop that contains a class component console.warn('The template prop will be deprecated in the future. \n Prefer passing in your component directly as children: https://reactjs.org/docs/composition-vs-inheritance.html'); return wrapComponent((0, _react.cloneElement)(_this.props.template)); } if (typeof _this.props.children.type === 'function') { // for children that are class components return wrapComponent(_this.props.children); } return _react.Children.map(_this.props.children, function (child) { return (0, _react.cloneElement)(child, { ref: 'item-' + child.props.key }); }); }, _temp), _possibleConstructorReturn(_this, _ret); } AccordionPanel.prototype.componentDidMount = function componentDidMount() { var bodyNode = this.accordionPanelRef; if (!bodyNode) return; // tests only? var images = bodyNode.querySelectorAll('img'); if (images.length > 0) { this.preloadImages(images); } else { this.calcHeight(); } }; // Wait for images to load before calculating height of element AccordionPanel.prototype.render = function render() { var _this2 = this; var _props = this.props, className = _props.className, isExpanded = _props.isExpanded, style = _props.style, speed = _props.speed; var styles = { transition: 'all ' + (speed || defaultProps.speed) + 'ms ease-in-out', maxHeight: isExpanded ? this.state.panelHeight : 0, opacity: isExpanded ? 1 : 0 }; return _react2.default.createElement( 'div', { ref: function ref(inst) { return _this2.accordionPanelRef = inst; }, className: (0, _classnames2.default)(className, { 'is-expanded': isExpanded }), style: _extends({}, style, defaultStyle, styles) }, this.renderChildren() ); }; return AccordionPanel; }(_react.PureComponent); exports.default = AccordionPanel; AccordionPanel.propTypes = process.env.NODE_ENV !== "production" ? { className: _propTypes2.default.string, style: _propTypes2.default.object, speed: _propTypes2.default.number, isExpanded: _propTypes2.default.bool } : {}; AccordionPanel.defaultProps = defaultProps; module.exports = exports['default'];