UNPKG

@shakthillc/components

Version:

React generic components for shakthi products

367 lines (314 loc) 12.5 kB
let viewPort = { frameRelativeRects: (el, customFrame) => { if (!el) { return; } let rectTemp = el.getBoundingClientRect(); let rect = { height: rectTemp.height || el.clientHeight, width: rectTemp.width || el.clientWidth, top: rectTemp.top, bottom: rectTemp.bottom, left: rectTemp.left, right: rectTemp.right, x: rectTemp.x, y: rectTemp.y }; let documentEle = document.documentElement; let customFrameRect = { top: 0, left: 0, right: documentEle.clientWidth, bottom: documentEle.clientHeight, height: documentEle.clientHeight, width: documentEle.clientWidth, x: 0, y: 0 }; if (customFrame) { customFrameRect = customFrame.getBoundingClientRect(); } let newRect = { top: rect.top - customFrameRect.top, left: rect.left - customFrameRect.left, height: rect.height, width: rect.width }; newRect.bottom = newRect.top + newRect.height; newRect.right = newRect.left + newRect.width; newRect.x = newRect.left; newRect.y = newRect.top; let rectGap = { top: newRect.top, left: newRect.left, bottom: customFrameRect.height - newRect.bottom, right: customFrameRect.width - newRect.right }; rectGap.center = { top: rectGap.top + newRect.height / 2, left: rectGap.left + newRect.width / 2, bottom: rectGap.bottom + newRect.height / 2, right: rectGap.right + newRect.width / 2 }; let adjustments = {}; if (newRect.top < 0) { adjustments.top = Math.abs(newRect.top); } if (newRect.left < 0) { adjustments.left = Math.abs(newRect.left); } if (newRect.bottom > customFrameRect.height) { adjustments.bottom = newRect.bottom - customFrameRect.height; } if (newRect.right > customFrameRect.width) { adjustments.right = newRect.right - customFrameRect.width; } return { frameRect: customFrameRect, rect: newRect, rectGap, adjustments }; }, isInViewPort: (el, customFrame) => { if (!el) { return; } let elRects = viewPort.frameRelativeRects(el, customFrame); let { rect } = elRects; let { frameRect } = elRects; return ( rect.top >= 0 && rect.left >= 0 && rect.bottom <= frameRect.height && rect.right <= frameRect.width ); }, possibilities: (el, relativeBox, customFrame) => { if (!el) { return; } let elRects = viewPort.frameRelativeRects(el, customFrame); let { rect, adjustments } = elRects; //arrow height||width let { height, width } = rect; rect.height = height + 10; rect.width = width + 10; let relativeBoxRects = viewPort.frameRelativeRects( relativeBox, customFrame ); let { rectGap: relativeBoxGap, rect: relativeBoxRect } = relativeBoxRects; // adjustments.left // ? (adjustments.left += (relativeBoxRects.rect.width * 2) / 3) // : null; // adjustments.right // ? (adjustments.right += (relativeBoxRects.rect.width * 2) / 3) // : null; // adjustments.top // ? (adjustments.top += (relativeBoxRects.rect.width * 2) / 3) // : null; // adjustments.bottom // ? (adjustments.bottom += (relativeBoxRects.rect.width * 2) / 3) // : null; let views = {}; //rect => PopOverContainer, relativeBoxGap => PopOverTarget let getPositions = () => { //Horizontal ~ ----- X axis //Vertical ~ ||||||| Y axis let bottomOverFlow = rect.height > relativeBoxGap.bottom; let topOverFlow = rect.height > relativeBoxGap.top; let rightOverFlow = rect.width > relativeBoxGap.right; let leftOverFlow = rect.width > relativeBoxGap.left; let horizontalCenterOverFlow = rect.width / 2 > relativeBoxGap.center.right || rect.width / 2 > relativeBoxGap.center.left; let verticalCenterOverFlow = rect.height / 2 > relativeBoxGap.center.top || rect.height / 2 > relativeBoxGap.center.bottom; let horizontalLeftToRightOverFlow = rect.width > relativeBoxRect.width + relativeBoxGap.right; let horizontalCenterToRightOverFlow = rect.width > relativeBoxGap.center.right; let horizontalRightToLeft = rect.width > relativeBoxRect.width + relativeBoxGap.left; let horizontalCenterToLeft = rect.width > relativeBoxGap.center.left; let verticalTopToBottomOverFlow = rect.height > relativeBoxRect.height + relativeBoxGap.bottom; let verticalCenterToBottomOverFlow = rect.height > relativeBoxGap.center.bottom; let verticalBottomToTopOverFlow = rect.height > relativeBoxRect.height + relativeBoxGap.top; let verticalCenterToTopOverFlow = rect.width > relativeBoxGap.center.top; let views = { bottomCenter: !(bottomOverFlow || horizontalCenterOverFlow), bottomLeftToRight: !(bottomOverFlow || horizontalLeftToRightOverFlow), bottomCenterToRight: !( bottomOverFlow || horizontalCenterToRightOverFlow ), bottomRight: !(bottomOverFlow || rightOverFlow), bottomRightToLeft: !(bottomOverFlow || horizontalRightToLeft), bottomCenterToLeft: !(bottomOverFlow || horizontalCenterToLeft), bottomLeft: !(bottomOverFlow || leftOverFlow), topCenter: !(topOverFlow || horizontalCenterOverFlow), topLeftToRight: !(topOverFlow || horizontalLeftToRightOverFlow), topCenterToRight: !(topOverFlow || horizontalCenterToRightOverFlow), topRight: !(topOverFlow || rightOverFlow), topRightToLeft: !(topOverFlow || horizontalRightToLeft), topCenterToLeft: !(topOverFlow || horizontalCenterToLeft), topLeft: !(topOverFlow || leftOverFlow), rightCenter: !(rightOverFlow || verticalCenterOverFlow), rightTopToBottom: !(rightOverFlow || verticalTopToBottomOverFlow), rightCenterToBottom: !(rightOverFlow || verticalCenterToBottomOverFlow), rightBottom: !(rightOverFlow || bottomOverFlow), rightBottomToTop: !(rightOverFlow || verticalBottomToTopOverFlow), rightCenterToTop: !(rightOverFlow || verticalCenterToTopOverFlow), rightTop: !(rightOverFlow || topOverFlow), leftCenter: !(leftOverFlow || verticalCenterOverFlow), leftTopToBottom: !(leftOverFlow || verticalTopToBottomOverFlow), leftCenterToBottom: !(leftOverFlow || verticalCenterToBottomOverFlow), leftBottom: !(leftOverFlow || bottomOverFlow), leftBottomToTop: !(leftOverFlow || verticalBottomToTopOverFlow), leftCenterToTop: !(leftOverFlow || verticalCenterToTopOverFlow), leftTop: !(leftOverFlow || topOverFlow) }; return views; }; //bottomCenter let bottomOverFlow = rect.height > relativeBoxGap.bottom; let bottomRightOverFlow = rect.width / 2 > relativeBoxGap.center.right; let bottomLeftOverFlow = rect.width / 2 > relativeBoxGap.center.left; //bottomRight let bottomRightOnlyOverFlow = rect.width > relativeBoxGap.center.right; views.bottomRight = !(bottomOverFlow || bottomRightOnlyOverFlow); //bottomLeft let bottomLeftOnlyOverFlow = rect.width > relativeBoxGap.center.left; views.bottomLeft = !(bottomOverFlow || bottomLeftOnlyOverFlow); views.bottomCenter = !( bottomOverFlow || bottomRightOverFlow || bottomLeftOverFlow ); //topCenter let topOverFlow = rect.height > relativeBoxGap.top; let topRightOverFlow = rect.width / 2 > relativeBoxGap.center.right; let topLeftOverFlow = rect.width / 2 > relativeBoxGap.center.left; //topRight let topRightOnlyOverFlow = rect.width > relativeBoxGap.center.right; views.topRight = !(topOverFlow || topRightOnlyOverFlow); //topLeft let topLeftOnlyOverFlow = rect.width > relativeBoxGap.center.left; views.topLeft = !(topOverFlow || topLeftOnlyOverFlow); views.topCenter = !(topOverFlow || topRightOverFlow || topLeftOverFlow); //leftCenter let leftOverFlow = rect.width > relativeBoxGap.left; let leftTopOverFlow = rect.height / 2 > relativeBoxGap.center.top; let leftBottomOverFlow = rect.height / 2 > relativeBoxGap.center.bottom; //leftTop let leftTopOnlyOverFlow = rect.height > relativeBoxGap.center.top; views.leftTop = !(leftOverFlow || leftTopOnlyOverFlow); //leftBottom let leftBottomOnlyOverFlow = rect.height > relativeBoxGap.center.bottom; views.leftBottom = !(leftOverFlow || leftBottomOnlyOverFlow); views.leftCenter = !(leftOverFlow || leftTopOverFlow || leftBottomOverFlow); //rightCenter let rightOverFlow = rect.width > relativeBoxGap.right; let rightTopOverFlow = rect.height / 2 > relativeBoxGap.center.top; let rightBottomOverFlow = rect.height / 2 > relativeBoxGap.center.bottom; //rightTop let rightTopOnlyOverFlow = rect.height > relativeBoxGap.center.top; views.rightTop = !(rightOverFlow || rightTopOnlyOverFlow); //rightBottom let rightBottomOnlyOverFlow = rect.height > relativeBoxGap.center.bottom; views.rightBottom = !(rightOverFlow || rightBottomOnlyOverFlow); views.rightCenter = !( rightOverFlow || rightTopOverFlow || rightBottomOverFlow ); return { views, adjustments }; }, getArrowAdjustments: (el, relativeBox, customFrame) => { if (!el) { return; } let elRects = viewPort.frameRelativeRects(el, customFrame); let { rectGap } = elRects; let relativeBoxRects = viewPort.frameRelativeRects( relativeBox, customFrame ); let relativeBoxGap = relativeBoxRects.rectGap; return { left: relativeBoxGap.center.left - rectGap.left, right: relativeBoxGap.center.right - rectGap.right, top: relativeBoxGap.center.top - rectGap.top, bottom: relativeBoxGap.center.bottom - rectGap.bottom }; }, betterView: (popup, relativeBox, defaultView, customFrame) => { let viewPortPossibilities = viewPort.possibilities( popup, relativeBox, customFrame ); if (!viewPortPossibilities) { return; } let { views, adjustments } = viewPortPossibilities; let viewKeys = Object.keys(views); let isViewFound = false; let fisrtView = ""; for (let i = 0; i < viewKeys.length; i++) { let viewKey = viewKeys[i]; if (views[viewKey]) { isViewFound = true; fisrtView = viewKey; break; } } if (!isViewFound) { return { view: null, adjustments }; } else if (!defaultView) { return { view: fisrtView, adjustments }; } if (views[defaultView]) { return { view: defaultView, adjustments }; } let defaultPosition = defaultView.replace( /Center|Bottom|Top|Left|Right$/, "" ); let viewTypes = { top: ["Center", "Right", "Left"], left: ["Center", "Top", "Bottom"] }; viewTypes.bottom = viewTypes.top; viewTypes.right = viewTypes.left; let defaultPositions = viewTypes[defaultPosition]; for (let i = 0, len = defaultPositions.length; i < len; i++) { let viewKey = defaultPosition + defaultPositions[i]; if (views[viewKey]) { return { view: viewKey, adjustments }; } } let oppositePositionsOrder = { bottom: ["top", "right", "left"], top: ["bottom", "right", "left"], left: ["bottom", "right", "top"], right: ["bottom", "top", "left"] }; let oppositeViews = oppositePositionsOrder[defaultPosition]; for (let i = 0, len = oppositeViews.length; i < len; i++) { let oppositeView = oppositeViews[i]; let positions = viewTypes[oppositeView]; for (let j = 0, lenx = positions.length; j < lenx; j++) { let viewKey = oppositeView + positions[j]; if (views[viewKey]) { return { view: viewKey, adjustments }; } } } return { view: null, adjustments }; } }; export default { betterView: viewPort.betterView, frameRelativeRects: viewPort.frameRelativeRects, getArrowAdjustments: viewPort.getArrowAdjustments };