mirror of https://github.com/rancher/dashboard.git
173 lines
4.5 KiB
JavaScript
173 lines
4.5 KiB
JavaScript
// @TODO replace this with popper.js...
|
|
|
|
export const LEFT = 'left';
|
|
export const RIGHT = 'right';
|
|
export const TOP = 'top';
|
|
export const CENTER = 'center'; // These are both the same externally so you can use either,
|
|
export const MIDDLE = 'center'; // but have different meaning inside this file (center->left/right, middle->top/bottom)
|
|
export const BOTTOM = 'bottom';
|
|
export const AUTO = 'auto';
|
|
|
|
export function boundingRect(elem) {
|
|
const pos = elem.getBoundingClientRect();
|
|
const width = elem.offsetWidth;
|
|
const height = elem.offsetHeight;
|
|
|
|
return {
|
|
top: pos.top,
|
|
right: pos.left + width,
|
|
bottom: pos.top + height,
|
|
left: pos.left,
|
|
width,
|
|
height,
|
|
};
|
|
}
|
|
|
|
export function fakeRectFor(event) {
|
|
return {
|
|
top: event.clientY,
|
|
left: event.clientX,
|
|
bottom: event.clientY,
|
|
right: event.clientX,
|
|
width: 0,
|
|
height: 0,
|
|
};
|
|
}
|
|
|
|
export function screenRect() {
|
|
const width = window.innerWidth;
|
|
const height = window.innerHeight;
|
|
const top = window.pageYOffset;
|
|
const left = window.pageXOffset;
|
|
|
|
return {
|
|
top,
|
|
right: left + width,
|
|
bottom: top + height,
|
|
left,
|
|
width,
|
|
height,
|
|
};
|
|
}
|
|
|
|
export function fitOnScreen(contentElem, triggerElemOrEvent, opt, useDefaults) {
|
|
let {
|
|
positionX = AUTO, // Preferred horizontal position
|
|
positionY = AUTO, // Preferred vertical position
|
|
} = opt || {};
|
|
|
|
const {
|
|
fudgeX = 0,
|
|
fudgeY = 0,
|
|
overlapX = true, // Position on "top" of the trigger horizontally
|
|
overlapY = false, // Position on "top" of the trigger vertically
|
|
} = opt || {};
|
|
|
|
const screen = screenRect();
|
|
let trigger;
|
|
|
|
if ( triggerElemOrEvent instanceof Event ) {
|
|
trigger = fakeRectFor(triggerElemOrEvent);
|
|
} else {
|
|
trigger = boundingRect(triggerElemOrEvent);
|
|
}
|
|
|
|
let content = {};
|
|
|
|
if (contentElem) {
|
|
content = boundingRect(contentElem);
|
|
}
|
|
|
|
if (useDefaults) {
|
|
content = {
|
|
top: 0,
|
|
right: 147,
|
|
bottom: 163,
|
|
left: 0,
|
|
width: 147,
|
|
height: 80
|
|
};
|
|
}
|
|
|
|
// console.log('screen', screen);
|
|
// console.log('trigger', trigger);
|
|
// console.log('content', content);
|
|
|
|
const style = { position: 'absolute' };
|
|
|
|
const originFor = {
|
|
left: (overlapX ? trigger.left : trigger.right ),
|
|
center: (trigger.left + trigger.right ) / 2,
|
|
right: (overlapX ? trigger.right : trigger.left ),
|
|
top: (overlapY ? trigger.bottom : trigger.top ),
|
|
middle: (trigger.top + trigger.bottom ) / 2,
|
|
bottom: (overlapY ? trigger.top : trigger.bottom ),
|
|
};
|
|
|
|
// console.log('origin', originFor);
|
|
|
|
const gapIf = {
|
|
left: screen.right - content.width - originFor.left,
|
|
center: Math.min(screen.right - (content.width / 2) - originFor.center, originFor.center - (content.width / 2) - screen.left),
|
|
right: originFor.right - content.width - screen.left,
|
|
top: originFor.bottom - content.height - screen.top,
|
|
middle: Math.min(originFor.middle - (content.height / 2) - screen.top, screen.bottom - (content.height / 2) - originFor.middle),
|
|
bottom: screen.bottom - content.height - originFor.top,
|
|
};
|
|
|
|
// console.log('gapIf', gapIf);
|
|
|
|
if ( positionX === CENTER && gapIf.center < 0) {
|
|
positionX = AUTO;
|
|
}
|
|
|
|
if ( positionX === AUTO ) {
|
|
positionX = gapIf.left < 0 || gapIf.right * 1.5 > gapIf.left ? RIGHT : LEFT;
|
|
} else if ( positionY === LEFT && gapIf.left < 0 ) {
|
|
positionX = RIGHT;
|
|
} else if ( positionY === RIGHT && gapIf.right < 0 ) {
|
|
positionX = LEFT;
|
|
}
|
|
|
|
switch ( positionX ) {
|
|
case LEFT:
|
|
style.left = `${ originFor.left - fudgeX }px`;
|
|
break;
|
|
case CENTER:
|
|
style.left = `${ ((originFor.left + originFor.right) / 2) - (content.width / 2) - fudgeX }px`;
|
|
break;
|
|
case RIGHT:
|
|
style.left = `${ originFor.right + fudgeX - content.width }px`;
|
|
// style.right = `${ screen.width - originFor.right - fudgeX }px`;
|
|
break;
|
|
}
|
|
|
|
if ( positionY === MIDDLE && gapIf.middle < 0) {
|
|
positionY = AUTO;
|
|
}
|
|
|
|
if ( positionY === AUTO ) {
|
|
positionY = gapIf.top < 0 || gapIf.bottom * 1.5 > gapIf.top ? BOTTOM : TOP;
|
|
} else if ( positionY === TOP && gapIf.top < 0 ) {
|
|
positionY = BOTTOM;
|
|
} else if ( positionY === BOTTOM && gapIf.bottom < 0 ) {
|
|
positionY = TOP;
|
|
}
|
|
|
|
switch ( positionY ) {
|
|
case TOP:
|
|
style.top = `${ originFor.top + fudgeY - content.height }px`;
|
|
break;
|
|
case CENTER:
|
|
style.top = `${ ((originFor.top + originFor.bottom) / 2) + fudgeY - content.height }px`;
|
|
break;
|
|
case BOTTOM:
|
|
style.top = `${ originFor.bottom - fudgeY }px`;
|
|
break;
|
|
}
|
|
|
|
// console.log(positionX, positionY, style);
|
|
|
|
return style;
|
|
}
|