UNPKG

chayns-components

Version:

A set of beautiful React components for developing chayns® applications.

244 lines (240 loc) 7.93 kB
"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); exports.__esModule = true; exports.default = void 0; var _clsx = _interopRequireDefault(require("clsx")); var _propTypes = _interopRequireDefault(require("prop-types")); var _react = _interopRequireDefault(require("react")); var _ExpandableContent = _interopRequireDefault(require("../../react-chayns-expandable_content/component/ExpandableContent")); var _ImageAccordionHead = _interopRequireDefault(require("./ImageAccordionHead")); /** * @component */ function listToMatrix(list, count) { const matrix = []; let i = 0; let k = 0; for (i = 0, k = -1; i < list.length; i += 1) { if (i % count === 0) { k += 1; matrix[k] = []; } if (matrix[k] && list[i]) { matrix[k].push(list[i]); } } return matrix; } /** * Groups several `ImageAccordion` components together, so only one of them can * be open at a time. */ class ImageAccordionGroup extends _react.default.Component { constructor(_props) { super(_props); this.getPx = style => { if (!style) { return 0; } const trimmed = style.replace(/ /g, ''); const number = trimmed.match(/[+-]?([0-9]*[.])?[0-9]+/); if (!number) { return 0; } return parseFloat(number[0]); }; this.handleAccordionClick = (key, sameRow, props, event) => { const { onHeadOpen } = this.props; let trigger = true; const node = event.target; for (let i = 0; i < 15; i += 1) { if (node.classList) { if (node.classList.contains('accordion--no--trigger') || node.classList.contains('context-menu-overlay') || node.classList.contains('context-menu__item__text') || node.classList.contains('context-menu__item')) { trigger = false; return trigger; } } } if (onHeadOpen) { onHeadOpen(props); } if (trigger) { const { currentState } = this.state; const { onOpen } = props; if (currentState === key) { this.accordionCloseListener(); } else { this.accordionOpenListener(key, sameRow, onOpen); } } return null; }; this.state = { width: 100 }; this.myRef = /*#__PURE__*/_react.default.createRef(); ImageAccordionGroup.index += 1; this.index = ImageAccordionGroup.index; } componentDidMount() { let style = getComputedStyle(this.myRef.current); this.width = this.getPx(style.width); this.setState({ width: this.width }); window.addEventListener('resize', () => { if (this.myRef.current) { style = getComputedStyle(this.myRef.current); this.width = this.getPx(style.width); this.setState({ width: this.width }); } }); } accordionCloseListener() { this.setState(state => ({ currentState: undefined, prevOpen: state.currentState })); } accordionOpenListener(key, sameRow, onOpen) { const { dataGroup, children } = this.props; if (dataGroup) { const openGroup = ImageAccordionGroup.dataGroups[dataGroup]; if (openGroup && openGroup !== this) { openGroup.accordionCloseListener(); } ImageAccordionGroup.dataGroups[dataGroup] = this; } let findChild = -1; if (children) { findChild = children.findIndex(g => g && g.key === key); } this.setState(state => ({ currentState: findChild !== -1 && children[findChild].props.children ? key : null, prevOpen: !sameRow && state.currentState })); if (onOpen) onOpen(); } render() { const { children, className, reference } = this.props; const { currentState, prevOpen, width } = this.state; const itemsPerRow = parseInt(width / 100, 10); const percent = 100 / itemsPerRow; const columnCount = Math.trunc(100 / percent); const childrenWithProps = _react.default.Children.map(children, child => { if (child) { return /*#__PURE__*/_react.default.cloneElement(child, { originalKey: child.key, open: child.key === currentState, prevOpen: child.key === prevOpen }); } return null; }) || []; const imageAccordionMatrix = listToMatrix(childrenWithProps, columnCount); let wrapperHeight = '150px'; if (width < 200) wrapperHeight = '185px';else if (width < 300) wrapperHeight = '165px'; return ( /*#__PURE__*/ // ImageAccordionGroup _react.default.createElement("div", { ref: this.myRef, className: (0, _clsx.default)('cc__image-accordion', className) }, imageAccordionMatrix.map(matrixRow => /*#__PURE__*/ // ImageAccordion Heads per row _react.default.createElement("div", { className: 'image-accordion-container' + (matrixRow.some(row => row.props.open) ? " open" : ""), key: matrixRow[0].key }, matrixRow.map(item => /*#__PURE__*/_react.default.createElement("div", { className: 'image-accordion' + (currentState === item.props.originalKey ? " open" : ""), onClick: e => { this.handleAccordionClick(item.props.originalKey, matrixRow.some(row => row.props.originalKey === currentState), item.props, e); }, onKeyPress: () => {}, ref: ref => { this.accordion = ref; if (reference) reference(ref); }, style: { width: `${percent}%` }, key: item.props.originalKey }, /*#__PURE__*/_react.default.createElement(_ImageAccordionHead.default, { item: item, wrapperHeight: wrapperHeight, width: width, itemsPerRow: itemsPerRow }))), /*#__PURE__*/_react.default.createElement("div", { className: "image-accordion-body" }, /*#__PURE__*/_react.default.createElement("div", { className: 'arrow' + (matrixRow.findIndex(c => !c.props.children && (c.props.originalKey === currentState || c.props.originalKey === prevOpen)) !== -1 ? " no-arrow" : ""), style: { marginLeft: (matrixRow.findIndex(c => c.props.originalKey === currentState || c.props.originalKey === prevOpen) + 0.5) * (width * (percent / 100)) - 12, opacity: (matrixRow.find(c => c.props.originalKey === currentState || c.props.originalKey === prevOpen) || { props: { item: {} } }).props.disabled ? 0.55 : 1 } }), /*#__PURE__*/_react.default.createElement(_ExpandableContent.default, { open: matrixRow.find(c => c.props.children && (c.props.originalKey === currentState || c.props.originalKey === prevOpen)) !== -1 }, matrixRow))))) ); } } exports.default = ImageAccordionGroup; ImageAccordionGroup.dataGroups = {}; ImageAccordionGroup.index = -1; ImageAccordionGroup.propTypes = { /** * A list of `ImageAccordion` components, that are contained in this group. */ children: _propTypes.default.node, /** * An id that identifies this group. Accordions in groups that share the * same `dataGroup` close each other. */ dataGroup: _propTypes.default.string, /** * A classname string that will be applied to the container element. */ className: _propTypes.default.string, /** * A function that receives a reference to the root containers DOM node. */ reference: _propTypes.default.func, /** * A callback that is invoked when one of the `ImageAccordion` components in * this group opens. */ onHeadOpen: _propTypes.default.func }; ImageAccordionGroup.defaultProps = { children: [], dataGroup: null, className: '', reference: null, onHeadOpen: null }; ImageAccordionGroup.displayName = 'ImageAccordionGroup'; //# sourceMappingURL=ImageAccordionGroup.js.map