@shakthillc/components
Version:
React generic components for shakthi products
367 lines (314 loc) • 12.5 kB
JavaScript
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
};