UNPKG

@zohodesk/components

Version:

In this Package, we Provide Some Basic Components to Build Web App

197 lines (171 loc) 6.71 kB
/* eslint-disable */ // QUestions to be discussed //1) mutation.type === 'characterData' needed ??? // 2) debounce Mutation observer and resize observer import React from 'react'; import PropTypes from 'prop-types'; import ResizeObserver from "./ResizeObserver"; import { getElementSpace, debounce } from "../utils/Common"; export default class ResizeComponent extends React.Component { constructor(props) { super(props); this.noSpaceForChildren = false; this.childrenCurrentList = []; this.widthCheck = debounce(this.widthCheck.bind(this), 10); // this.widthCheck = this.widthCheck.bind(this); this.onResize = this.onResize.bind(this); this.onResizeMutation = this.onResizeMutation.bind(this); this.tabsObserver = new ResizeObserver(this.onResize); this.tabObserver = new MutationObserver(this.onResizeMutation); this.reset = this.reset.bind(this); this.constructChildren = this.constructChildren.bind(this); this.querySelector = this.querySelector.bind(this); } querySelector() { if (this.props.wrapperDivRef && this.props.wrapperDivRef.current) { return this.props.wrapperDivRef.current.querySelectorAll('[data-responsive="true"]'); } else { return []; } } onResizeMutation(mutations) { // console.log(mutations); let { childrenList } = this.props; for (const mutation of mutations) { if (mutation.type === 'childList') { if (mutation.addedNodes.length) { let newAdded = false; mutation.addedNodes.forEach(mut => { // Here we can listen for icon nodes. Confirm with bk if (mut.attributes && mut.attributes['data-responsive'] && (childrenList.length !== this.querySelector().length || this.childrenCurrentList.length !== this.querySelector().length)) { newAdded = true; } }); if (newAdded) { //console.log('A child node has been added ', mutation); this.onResize(); } } else if (mutation.removedNodes.length) {// ?? removed nodes ku check pannanum ah ?? // console.log('A child node has been removed ', mutation); } } else if (mutation.type === 'attributes') {//console.log('The ' + mutation.attributeName + ' attribute was modified.', mutation); } else if (mutation.type === 'characterData') {// To Call While Changing InnerText, Remove Below line If Required. But It might affect Performance. // this.onResize(); } } // mutations.forEach(mutation => { // if (mutation.target === foo && // mutation.attributeName === 'style' && // oldWidth !== foo.style.width) { // foo.textContent = 'Width changed from ' + // oldWidth + ' to ' + foo.style.width; // oldWidth = foo.style.width; // } // }); } componentDidMount() { if (this.props.wrapperDivRef && this.props.wrapperDivRef.current) { this.tabsObserver.observe(this.props.wrapperDivRef.current); this.tabObserver.observe(this.props.wrapperDivRef.current, { characterData: true, attributes: true, childList: true, subtree: true, attributeFilter: ['data-responsive'] }); } } componentWillUnmount() { this.reset(); } reset() { this.childrenCurrentList = []; this.tabsObserver.disconnect(); this.tabObserver && this.tabObserver.disconnect(); } componentDidUpdate(prevProps) { if (this.childrenCurrentList.length === 0) { this.childrenCurrentList = this.querySelector(); this.widthCheck(); } if (this.props.resizeId !== prevProps.resizeId) { // Completely reset the observers and set new observer if id is changed this.reset(); if (this.props.wrapperDivRef && this.props.wrapperDivRef.current) { this.tabsObserver.observe(this.props.wrapperDivRef.current); this.tabObserver.observe(this.props.wrapperDivRef.current, { characterData: true, attributes: true, childList: true, subtree: true, attributeFilter: ['data-responsive'] }); } } } onResize() { // if (this.childrenCurrentList.length !== 0) { this.childrenCurrentList = []; this.constructChildren(0, false); //} } // shouldComponentUpdate() { // return this.childrenCurrentList.length === 0 // } widthCheck() { let wrapperDivRef = this.props.wrapperDivRef.current; let moreDivRef = this.props.moreDivRef.current; if (wrapperDivRef && this.childrenCurrentList.length > 0) { const childrenWidthList = this.childrenCurrentList; // this.childrenCurrentList = childrenWidthList; const moreWidth = getElementSpace(moreDivRef).neededSpace; //console.log(moreWidth,'moreWidth'); let totalWidth = getElementSpace(wrapperDivRef).availableInsideSpace - moreWidth; let _childrenTotalWidth = 0; let dataCount = 0; this.noSpaceForChildren = false; if (totalWidth <= moreWidth) { this.noSpaceForChildren = true; } else { for (let i = 0; i < childrenWidthList.length; i++) { let currentWidth = getElementSpace(childrenWidthList[i]).neededSpace; _childrenTotalWidth += currentWidth; // console.log(_childrenTotalWidth, currentWidth, totalWidth) if (i === childrenWidthList.length - 1 && moreWidth >= currentWidth) { totalWidth += moreWidth; } if (totalWidth <= _childrenTotalWidth) { dataCount = i; break; } } } this.constructChildren(dataCount, true); } else { this.constructChildren(0, false); } } constructChildren() { let dataCount = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 0; let responsive = arguments.length > 1 ? arguments[1] : undefined; const { childrenList, getData } = this.props; // If the data count is zero we assume that we can render all the items - data count will be zero only when we want to calculate the whole list width dataCount = dataCount || childrenList && childrenList.length; getData({ responsiveHook: responsive, validListCount: this.noSpaceForChildren ? 0 : dataCount }); } render() { return /*#__PURE__*/React.createElement(React.Fragment, null, this.props.children); } } ResizeComponent.propTypes = { children: PropTypes.node, getData: PropTypes.func, resizeId: PropTypes.number, childrenList: PropTypes.array, wrapperDivRef: PropTypes.any, moreDivRef: PropTypes.any }; ResizeComponent.defaultProps = { getData: () => {}, resizeId: null };