UNPKG

@shopgate/engage

Version:
38 lines • 7.78 kB
function _typeof(obj){if(typeof Symbol==="function"&&typeof Symbol.iterator==="symbol"){_typeof=function _typeof(obj){return typeof obj;};}else{_typeof=function _typeof(obj){return obj&&typeof Symbol==="function"&&obj.constructor===Symbol&&obj!==Symbol.prototype?"symbol":typeof obj;};}return _typeof(obj);}function _classCallCheck(instance,Constructor){if(!(instance instanceof Constructor)){throw new TypeError("Cannot call a class as a function");}}function _defineProperties(target,props){for(var i=0;i<props.length;i++){var descriptor=props[i];descriptor.enumerable=descriptor.enumerable||false;descriptor.configurable=true;if("value"in descriptor)descriptor.writable=true;Object.defineProperty(target,descriptor.key,descriptor);}}function _createClass(Constructor,protoProps,staticProps){if(protoProps)_defineProperties(Constructor.prototype,protoProps);if(staticProps)_defineProperties(Constructor,staticProps);return Constructor;}function _callSuper(_this,derived,args){function isNativeReflectConstruct(){if(typeof Reflect==="undefined"||!Reflect.construct)return false;if(Reflect.construct.sham)return false;if(typeof Proxy==="function")return true;try{return!Boolean.prototype.valueOf.call(Reflect.construct(Boolean,[],function(){}));}catch(e){return false;}}derived=_getPrototypeOf(derived);return _possibleConstructorReturn(_this,isNativeReflectConstruct()?Reflect.construct(derived,args||[],_getPrototypeOf(_this).constructor):derived.apply(_this,args));}function _possibleConstructorReturn(self,call){if(call&&(_typeof(call)==="object"||typeof call==="function")){return call;}return _assertThisInitialized(self);}function _assertThisInitialized(self){if(self===void 0){throw new ReferenceError("this hasn't been initialised - super() hasn't been called");}return self;}function _getPrototypeOf(o){_getPrototypeOf=Object.setPrototypeOf?Object.getPrototypeOf:function _getPrototypeOf(o){return o.__proto__||Object.getPrototypeOf(o);};return _getPrototypeOf(o);}function _inherits(subClass,superClass){if(typeof superClass!=="function"&&superClass!==null){throw new TypeError("Super expression must either be null or a function");}subClass.prototype=Object.create(superClass&&superClass.prototype,{constructor:{value:subClass,writable:true,configurable:true}});if(superClass)_setPrototypeOf(subClass,superClass);}function _setPrototypeOf(o,p){_setPrototypeOf=Object.setPrototypeOf||function _setPrototypeOf(o,p){o.__proto__=p;return o;};return _setPrototypeOf(o,p);}function _defineProperty(obj,key,value){if(key in obj){Object.defineProperty(obj,key,{value:value,enumerable:true,configurable:true,writable:true});}else{obj[key]=value;}return obj;}import React,{Component}from'react';import PropTypes from'prop-types';import debounce from'lodash/debounce';import I18n from'@shopgate/pwa-common/components/I18n';import RippleButton from'@shopgate/pwa-ui-shared/RippleButton';import{themeConfig}from'@shopgate/pwa-common/helpers/config';import styles from"./style";var variables=themeConfig.variables;/** * The height of one row. * @type {number} */export var CHIP_ROW_HEIGHT=34;/** * The minimum width that a chip should have. * @type {number} */export var CHIP_MINIMUM_WIDTH=60;/** * The ChipLayout component. */var ChipLayout=/*#__PURE__*/function(_Component){function ChipLayout(){var _this2;_classCallCheck(this,ChipLayout);for(var _len=arguments.length,args=new Array(_len),_key=0;_key<_len;_key++){args[_key]=arguments[_key];}_this2=_callSuper(this,ChipLayout,[].concat(args));/** * Debounced, eg. layout effect */_defineProperty(_this2,"processHiddenElementsDebounced",debounce(_this2.processHiddenElements,50));return _this2;}_inherits(ChipLayout,_Component);return _createClass(ChipLayout,[{key:"componentDidMount",value:/** * When the component mounts we need to initially process all children. */function componentDidMount(){this.processHiddenElementsDebounced();}/** * Eveyry time pathname or other prop changes this callback is called. * This funtion will start processing hidden elements in order to check if "more" button * should be rendered. * * It must be done on every prop change, including the pathname. * Sometimes this component is rendered invisible, then since `.processHiddenElements` uses * refs.clientHeight it would always be zero. */},{key:"componentDidUpdate",value:function componentDidUpdate(){this.processHiddenElementsDebounced();}/** * Returns the maximum height the container should have. * @returns {number} */},{key:"maxContentHeight",get:function get(){// 8 -> container padding. return CHIP_ROW_HEIGHT*this.props.maxRows+8;}/** * Returns the more button styles. * @return {string} The store button class name. */},{key:"moreButtonStyles",get:function get(){if(this.props.invertMoreButton){return styles.moreButtonInverted;}return styles.moreButton;}/** * Loops through all children to make sure the more button appears if there is too much content. */},{key:"processHiddenElements",value:function processHiddenElements(){var _this3=this;if(!this.containerRef){return;}// Find out if there are overflowing elements. var lastVisibleElement=0;var showMoreButton=this.containerRef.scrollHeight>this.containerRef.clientHeight;var containerHeight=this.containerRef.clientHeight;var chips=Array.from(this.layoutRef.children);this.moreButtonRef.style.display=showMoreButton?'block':'none';this.layoutRef.style.minHeight=showMoreButton?"".concat(this.maxContentHeight,"px"):'0px';// If the more button is not visible we don't need to process anything. if(!showMoreButton){return;}// Hide or show chips that are hidden due to overflow. chips.forEach(function(child,index){var isVisible=child.offsetTop+child.clientHeight<containerHeight;child.setAttribute('style',"display: ".concat(isVisible?'flex':'none',";"));if(isVisible){lastVisibleElement=index;}});// Hide the more button if previous assumption was incorrect. if(lastVisibleElement===chips.length-1){this.moreButtonRef.style.display='none';return;}// Hide elements so that the 'more button' has enough space. chips.slice(0,lastVisibleElement+1).reverse().every(function(element){var offsetBottom=element.offsetTop+element.clientHeight;if(_this3.moreButtonRef.offsetTop>offsetBottom){return true;}var buttonSpaceRequired=_this3.moreButtonRef.clientWidth+variables.gap.big;var elementRight=_this3.containerRef.clientWidth-(element.offsetLeft+element.clientWidth);var spaceDiff=buttonSpaceRequired-elementRight;var remainingChipWidth=element.clientWidth-spaceDiff;if(remainingChipWidth>CHIP_MINIMUM_WIDTH){element.setAttribute('style',"max-width: ".concat(remainingChipWidth,"px"));return false;}if(element.offsetTop!==chips[lastVisibleElement].offsetTop){element.setAttribute('style','display: none');return false;}element.setAttribute('style','display: none');return true;});}},{key:"render",value:/** * Renders the component. * @returns {JSX} */function render(){var _this4=this;return React.createElement("div",{ref:function ref(element){_this4.containerRef=element;},className:"".concat(styles.container(this.maxContentHeight)," engage__chip-layout")},React.createElement("div",{ref:function ref(element){_this4.layoutRef=element;},className:styles.layout},this.props.children),React.createElement("div",{ref:function ref(element){_this4.moreButtonRef=element;},className:styles.moreButtonWrapper},React.createElement(RippleButton,{fill:true,type:"plain",className:this.moreButtonStyles,onClick:this.props.handleMoreButton},React.createElement(I18n.Text,{string:this.props.moreLabel}))));}}]);}(Component);_defineProperty(ChipLayout,"defaultProps",{children:null,handleMoreButton:function handleMoreButton(){},invertMoreButton:false,maxRows:2,moreLabel:'more',pathname:''});export default ChipLayout;