mirror of https://github.com/Squidex/squidex.git
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
169 lines
5.3 KiB
169 lines
5.3 KiB
/*
|
|
* Squidex Headless CMS
|
|
*
|
|
* @license
|
|
* Copyright (c) Squidex UG (haftungsbeschränkt). All rights reserved.
|
|
*/
|
|
|
|
export type RelativePosition =
|
|
'bottom-center' |
|
|
'bottom-left' |
|
|
'bottom-right' |
|
|
'left-bottom' |
|
|
'left-center' |
|
|
'left-top' |
|
|
'right-bottom' |
|
|
'right-center' |
|
|
'right-top' |
|
|
'top-center' |
|
|
'top-left' |
|
|
'top-right';
|
|
|
|
const POSITION_BOTTOM_CENTER = 'bottom-center';
|
|
const POSITION_BOTTOM_LEFT = 'bottom-left';
|
|
const POSITION_BOTTOM_RIGHT = 'bottom-right';
|
|
const POSITION_LEFT_BOTTOM = 'left-bottom';
|
|
const POSITION_LEFT_CENTER = 'left-center';
|
|
const POSITION_LEFT_TOP = 'left-top';
|
|
const POSITION_RIGHT_BOTTOM = 'right-bottom';
|
|
const POSITION_RIGHT_CENTER = 'right-center';
|
|
const POSITION_RIGHT_TOP = 'right-top';
|
|
const POSITION_TOP_CENTER = 'top-center';
|
|
const POSITION_TOP_LEFT = 'top-left';
|
|
const POSITION_TOP_RIGHT = 'top-right';
|
|
|
|
export type PositionResult = {
|
|
x: number;
|
|
y: number;
|
|
xMax: number;
|
|
yMax: number;
|
|
};
|
|
|
|
export function positionModal(targetRect: DOMRect, modalRect: DOMRect, relativePosition: RelativePosition, offset: number, fix: boolean, clientWidth: number, clientHeight: number): PositionResult {
|
|
let y = 0;
|
|
let x = 0;
|
|
|
|
// Available space in x/y direction.
|
|
let xMax = 0;
|
|
let yMax = 0;
|
|
|
|
switch (relativePosition) {
|
|
case POSITION_LEFT_TOP:
|
|
case POSITION_RIGHT_TOP: {
|
|
y = targetRect.top;
|
|
break;
|
|
}
|
|
case POSITION_LEFT_BOTTOM:
|
|
case POSITION_RIGHT_BOTTOM: {
|
|
y = targetRect.bottom - modalRect.height;
|
|
break;
|
|
}
|
|
case POSITION_BOTTOM_CENTER:
|
|
case POSITION_BOTTOM_LEFT:
|
|
case POSITION_BOTTOM_RIGHT: {
|
|
y = targetRect.bottom + offset;
|
|
|
|
yMax = clientHeight - y;
|
|
// Unset yMax if we have enough space.
|
|
if (modalRect.height <= yMax) {
|
|
yMax = 0;
|
|
} else if (fix) {
|
|
// Find a position at the other side of the rect (top).
|
|
const candidate = targetRect.top - modalRect.height - offset;
|
|
|
|
if (candidate > 0) {
|
|
y = candidate;
|
|
// Reset space to zero (full space), becuase we fix only if we have the space.
|
|
yMax = 0;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case POSITION_TOP_CENTER:
|
|
case POSITION_TOP_LEFT:
|
|
case POSITION_TOP_RIGHT: {
|
|
y = targetRect.top - modalRect.height - offset;
|
|
|
|
yMax = targetRect.top - offset;
|
|
// Unset yMax if we have enough space.
|
|
if (modalRect.height <= yMax) {
|
|
yMax = 0;
|
|
} else if (fix) {
|
|
// Find a position at the other side of the rect (bottom).
|
|
const candidate = targetRect.bottom + offset;
|
|
|
|
if (candidate + modalRect.height < clientHeight) {
|
|
y = candidate;
|
|
// Reset space to zero (full space), becuase we fix only if we have the space.
|
|
yMax = 0;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case POSITION_LEFT_CENTER:
|
|
case POSITION_RIGHT_CENTER:
|
|
y = targetRect.top + targetRect.height * 0.5 - modalRect.height * 0.5;
|
|
break;
|
|
}
|
|
|
|
switch (relativePosition) {
|
|
case POSITION_TOP_LEFT:
|
|
case POSITION_BOTTOM_LEFT: {
|
|
x = targetRect.left;
|
|
break;
|
|
}
|
|
case POSITION_TOP_RIGHT:
|
|
case POSITION_BOTTOM_RIGHT: {
|
|
x = targetRect.right - modalRect.width;
|
|
break;
|
|
}
|
|
case POSITION_RIGHT_CENTER:
|
|
case POSITION_RIGHT_TOP:
|
|
case POSITION_RIGHT_BOTTOM: {
|
|
x = targetRect.right + offset;
|
|
|
|
xMax = clientWidth - x;
|
|
// Unset xMax if we have enough space.
|
|
if (modalRect.width <= xMax) {
|
|
xMax = 0;
|
|
} else if (fix) {
|
|
// Find a position at the other side of the rect (left).
|
|
const candidate = targetRect.left - modalRect.width - offset;
|
|
|
|
if (candidate > 0) {
|
|
x = candidate;
|
|
// Reset space to zero (full space), becuase we fix only if we have the space.
|
|
xMax = 0;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case POSITION_LEFT_CENTER:
|
|
case POSITION_LEFT_TOP:
|
|
case POSITION_LEFT_BOTTOM: {
|
|
x = targetRect.left - modalRect.width - offset;
|
|
|
|
xMax = targetRect.left - offset;
|
|
// Unset xMax if we have enough space.
|
|
if (modalRect.width <= xMax) {
|
|
xMax = 0;
|
|
} else if (fix) {
|
|
// Find a position at the other side of the rect (right).
|
|
const candidate = targetRect.right + offset;
|
|
|
|
if (candidate + modalRect.width < clientWidth) {
|
|
x = candidate;
|
|
// Reset space to zero (full space), becuase we fix only if we have the space.
|
|
xMax = 0;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case POSITION_TOP_CENTER:
|
|
case POSITION_BOTTOM_CENTER:
|
|
x = targetRect.left + targetRect.width * 0.5 - modalRect.width * 0.5;
|
|
break;
|
|
}
|
|
|
|
return { x, y, xMax, yMax };
|
|
}
|
|
|