jiti-meet/react/features/base/popover/functions.web.ts

157 lines
4.4 KiB
TypeScript

const LEFT_RIGHT_OFFSET = 25;
const TOP_BOTTOM_OFFSET = 20;
const getLeftAlignedStyle = (bounds: DOMRect) => {
return {
position: 'fixed',
right: `${window.innerWidth - bounds.x + LEFT_RIGHT_OFFSET}px`
};
};
const getRightAlignedStyle = (bounds: DOMRect) => {
return {
position: 'fixed',
left: `${bounds.x + bounds.width + LEFT_RIGHT_OFFSET}px`
};
};
const getTopAlignedStyle = (bounds: DOMRect) => {
return {
position: 'fixed',
bottom: `${window.innerHeight - bounds.y + TOP_BOTTOM_OFFSET}px`
};
};
const getBottomAlignedStyle = (bounds: DOMRect) => {
return {
position: 'fixed',
top: `${bounds.y + bounds.height + TOP_BOTTOM_OFFSET}px`
};
};
const getLeftRightStartAlign = (bounds: DOMRect, size: DOMRectReadOnly) => {
return {
top: `${Math.min(bounds.y + 15, window.innerHeight - size.height - 20)}px`
};
};
const getLeftRightMidAlign = (bounds: DOMRect, size: DOMRectReadOnly) => {
return {
bottom: `${window.innerHeight - bounds.y - bounds.height - (size.height / 2)}px`
};
};
const getLeftRightEndAlign = (bounds: DOMRect, size: DOMRectReadOnly) => {
return {
bottom: `${Math.min(window.innerHeight - bounds.y - bounds.height, window.innerHeight - size.height)}px`
};
};
const getTopBotStartAlign = (bounds: DOMRect) => {
return {
right: `${window.innerWidth - bounds.x + 10}px`
};
};
const getTopBotMidAlign = (bounds: DOMRect, size: DOMRectReadOnly) => {
return {
right: `${window.innerWidth - bounds.x - (size.width / 2)}px`
};
};
const getTopBotEndAlign = (bounds: DOMRect) => {
return {
left: `${bounds.x + bounds.width + 10}px`
};
};
/**
* Gets the trigger element's and the context menu's bounds/size info and
* computes the style to apply to the context menu to positioning it correctly
* in regards to the given position info.
*
* @param {DOMRect} triggerBounds -The bounds info of the trigger html element.
* @param {DOMRectReadOnly} dialogSize - The size info of the context menu.
* @param {string} position - The position of the context menu in regards to the trigger element.
*
* @returns {Object} = The style to apply to context menu for positioning it correctly.
*/
export const getContextMenuStyle = (triggerBounds: DOMRect,
dialogSize: DOMRectReadOnly,
position: string) => {
const parsed = position.split('-');
switch (parsed[0]) {
case 'top': {
let alignmentStyle = {};
if (parsed[1]) {
alignmentStyle = parsed[1] === 'start'
? getTopBotStartAlign(triggerBounds)
: getTopBotEndAlign(triggerBounds);
} else {
alignmentStyle = getTopBotMidAlign(triggerBounds, dialogSize);
}
return {
...getTopAlignedStyle(triggerBounds),
...alignmentStyle
};
}
case 'bottom': {
let alignmentStyle = {};
if (parsed[1]) {
alignmentStyle = parsed[1] === 'start'
? getTopBotStartAlign(triggerBounds)
: getTopBotEndAlign(triggerBounds);
} else {
alignmentStyle = getTopBotMidAlign(triggerBounds, dialogSize);
}
return {
...getBottomAlignedStyle(triggerBounds),
...alignmentStyle
};
}
case 'left': {
let alignmentStyle = {};
if (parsed[1]) {
alignmentStyle = parsed[1] === 'start'
? getLeftRightStartAlign(triggerBounds, dialogSize)
: getLeftRightEndAlign(triggerBounds, dialogSize);
} else {
alignmentStyle = getLeftRightMidAlign(triggerBounds, dialogSize);
}
return {
...getLeftAlignedStyle(triggerBounds),
...alignmentStyle
};
}
case 'right': {
let alignmentStyle = {};
if (parsed[1]) {
alignmentStyle = parsed[1] === 'start'
? getLeftRightStartAlign(triggerBounds, dialogSize)
: getLeftRightEndAlign(triggerBounds, dialogSize);
} else {
alignmentStyle = getLeftRightMidAlign(triggerBounds, dialogSize);
}
return {
...getRightAlignedStyle(triggerBounds),
...alignmentStyle
};
}
default: {
return {
...getLeftAlignedStyle(triggerBounds),
...getLeftRightEndAlign(triggerBounds, dialogSize)
};
}
}
};