UNPKG

react-accordion-with-header

Version:
182 lines (153 loc) 6.89 kB
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; }; 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; } import React, { Component, Children, cloneElement } from "react"; import PropTypes from "prop-types"; import classNames from "classnames"; var defaultProps = { className: "react-accordion-with-header", multipleOkay: false, firstOpen: false, style: { boxShadow: "0 0 0 1px rgba(63,63,68,.05), 0 1px 3px 0 rgba(63,63,68,.15)", borderRadius: 3 } }; var AccordionWithHeader = function (_Component) { _inherits(AccordionWithHeader, _Component); function AccordionWithHeader() { var _temp, _this, _ret; _classCallCheck(this, AccordionWithHeader); for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) { args[_key] = arguments[_key]; } return _ret = (_temp = (_this = _possibleConstructorReturn(this, _Component.call.apply(_Component, [this].concat(args))), _this), _this.state = _extends({ panels: [], active: [] }, _this.props), _this.onClickHeader = function (panelIndex) { var active = void 0; if (_this.state.active.includes(panelIndex)) { active = _this.state.active.filter(function (item) { return item !== panelIndex; }); } else { active = !_this.props.multipleOkay ? [] : _this.state.active; active.push(_this.state.panels[panelIndex]); active.sort(); } _this.setState(function (prevState) { return { active: active, multipleOkay: prevState.multipleOkay !== _this.props.multipleOkay ? _this.props.multipleOkay : prevState.multipleOkay }; }, function () { if (_this.props.actionCallback) { var _this$props; // pass array of panels and accordion state back to actionCallback props function var panelData = _this.state.panels.map(function (panel) { return { panel: panel, open: active.includes(panel) }; }); (_this$props = _this.props).actionCallback.apply(_this$props, [panelData].concat(_this.state)); } }); }, _this.checkExpanded = function (indexKey, activePanelOrPanelsProps) { if (Array.isArray(activePanelOrPanelsProps)) { //multipleOkay is true return activePanelOrPanelsProps.some(function (panel) { return panel === indexKey; }); } else { return indexKey === activePanelOrPanelsProps; } }, _temp), _possibleConstructorReturn(_this, _ret); } AccordionWithHeader.prototype.componentDidMount = function componentDidMount() { var panels = void 0; var _props = this.props, children = _props.children, active = _props.active, firstOpen = _props.firstOpen; if (!children) { throw new Error("AccordionWithHeader must have children!"); } panels = Children.map(children, function (child) { return +child.key; }); // define the number of AccordionNode "panels" to control this.setState({ panels: panels }); // allow firstOpen prop, but prefer an "active" array if (firstOpen) { this.setState({ active: [0] }); } // if this.props.active is defined, validate it is an array // and that it is a valid instance of the panels array if (typeof active !== "undefined") { var validateActive = function validateActive() { if (typeof active === "number" || !Array.isArray(active)) { throw new Error("this.props.active must be an array"); } active.forEach(function (active) { if (!panels.includes(active)) { throw new Error("Items in this.props.active array are not included in panel array!\n Check that one or more array indexes are properly passed in."); } }); }; validateActive(); this.setState(function (prevState) { return { active: Array.from(new Set([].concat(prevState.active, active))) }; }); } }; AccordionWithHeader.prototype.componentDidUpdate = function componentDidUpdate(prevProps) { // Only needs to render if children have been dynamically aded/removed if (prevProps.children.length != this.props.children.length) { var children = this.props.children; var panels = Children.map(children, function (child) { return +child.key; }); this.setState({ panels: panels }); } }; AccordionWithHeader.prototype.render = function render() { var _this2 = this; var _props2 = this.props, className = _props2.className, style = _props2.style, children = _props2.children, active = _props2.active; var internalControl = !active; var panelsToCheck = internalControl ? this.state.active : active; return React.createElement( "div", { className: classNames(className), style: _extends({}, style) }, Children.map(children, function (item, index) { // lets render the <AccordionNode /> and its kids return cloneElement(item, { indexKey: index, // needed for child ref if template prop is used key: index, onClickHeader: function onClickHeader() { return _this2.onClickHeader(index); }, isExpanded: _this2.checkExpanded(index, panelsToCheck) }); }) ); }; return AccordionWithHeader; }(Component); export { AccordionWithHeader as default }; AccordionWithHeader.propTypes = process.env.NODE_ENV !== "production" ? { className: PropTypes.string, style: PropTypes.object, firstOpen: PropTypes.bool, multipleOkay: PropTypes.bool, active: PropTypes.array, actionCallback: PropTypes.func } : {}; AccordionWithHeader.defaultProps = defaultProps;