@gooddata/react-components
Version:
GoodData.UI - A powerful JavaScript library for building analytical applications
142 lines • 7.12 kB
JavaScript
"use strict";
var __assign = (this && this.__assign) || function () {
__assign = Object.assign || function(t) {
for (var s, i = 1, n = arguments.length; i < n; i++) {
s = arguments[i];
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
t[p] = s[p];
}
return t;
};
return __assign.apply(this, arguments);
};
Object.defineProperty(exports, "__esModule", { value: true });
function getViewportDimensionsAndCoords() {
var width = window.innerWidth;
var height = window.innerHeight;
var left = window.pageXOffset;
var top = window.pageYOffset;
var right = left + width;
var bottom = top + height;
return { width: width, height: height, left: left, top: top, right: right, bottom: bottom };
}
exports.getViewportDimensionsAndCoords = getViewportDimensionsAndCoords;
function getElementDimensionsAndCoords(element) {
var rect = element.getBoundingClientRect();
var window = getViewportDimensionsAndCoords();
var width = rect.width;
var height = rect.height;
var left = rect.left + window.left;
var top = rect.top + window.top;
var right = left + width;
var bottom = top + height;
return { width: width, height: height, left: left, top: top, right: right, bottom: bottom };
}
exports.getElementDimensionsAndCoords = getElementDimensionsAndCoords;
function getElementDimensions(element) {
var rect = element.getBoundingClientRect();
var width = rect.width;
var height = rect.height;
return { width: width, height: height };
}
exports.getElementDimensions = getElementDimensions;
var reverseDirectionMap = {
left: "right",
right: "left",
top: "bottom",
bottom: "top",
};
var dimensionMap = {
left: "width",
right: "width",
top: "height",
bottom: "height",
};
function calculateMenuPosition(_a) {
var toggler = _a.toggler, viewport = _a.viewport, menu = _a.menu, _b = _a.alignment, alignment = _b === void 0 ? ["right", "bottom"] : _b, _c = _a.spacing, spacing = _c === void 0 ? 0 : _c, _d = _a.offset, offset = _d === void 0 ? 0 : _d, _e = _a.topLevelMenu, topLevelMenu = _e === void 0 ? true : _e;
var _f;
var sharedArguments = { toggler: toggler, viewport: viewport, menu: menu, spacing: spacing, offset: offset };
var directionPreferredPrimary = alignment[0], directionPrefferedSecondary = alignment[1];
var _g = calculatePositionForDirection(__assign({}, sharedArguments, { direction: directionPreferredPrimary, isPrimaryDimension: true })), primaryCoordinateDirection = _g[0], primaryCoordinate = _g[1];
var _h = calculatePositionForDirection(__assign({}, sharedArguments, { direction: directionPrefferedSecondary, isPrimaryDimension: false })), secondaryCoordinateDirection = _h[0], secondaryCoordinate = _h[1];
var coordinates = (_f = {},
_f[primaryCoordinateDirection] = primaryCoordinate,
_f[secondaryCoordinateDirection] = secondaryCoordinate,
_f);
// Convert from left/right+top/bottom coordinates to left+top coordinates
var res = {
left: typeof coordinates.left === "number"
? coordinates.left
: toggler.width - menu.width - coordinates.right,
top: typeof coordinates.top === "number"
? coordinates.top
: toggler.height - menu.height - coordinates.bottom,
};
// Returned coordinates are relative to toggler.
// - Submenus are positioned relative to the toggler, so we do not do anything.
// - Top menu is inside portal positioned relative to the page, so we convert
// from coords relative to toggler to coords relative to page.
if (topLevelMenu) {
res.left += toggler.left;
res.top += toggler.top;
}
return res;
}
exports.calculateMenuPosition = calculateMenuPosition;
function calculatePositionForDirection(_a) {
// Toggler and viewport coordinates are absolute to the page.
// Returned coordinates are relative to the toggler.
var toggler = _a.toggler, viewport = _a.viewport, menu = _a.menu, direction = _a.direction, spacing = _a.spacing, offset = _a.offset, isPrimaryDimension = _a.isPrimaryDimension;
var directionReverse = reverseDirectionMap[direction];
var dimension = dimensionMap[direction];
var directionBottomRight = direction === "bottom" || direction === "right";
var directionBottomRightMultiplier = directionBottomRight ? 1 : -1;
var secondaryDimensionAdjust = isPrimaryDimension ? 0 : toggler[dimension];
var spacingAdjust = isPrimaryDimension ? spacing : 0;
var offsetAdjust = isPrimaryDimension ? 0 : offset;
// Primary space is size of the ideal position on the screen.
// eg.: for direction = "right" primary space would be space between
// toggler right and viewport right.
var primarySpace = viewport[direction] - toggler[direction];
primarySpace = primarySpace + secondaryDimensionAdjust * directionBottomRightMultiplier;
primarySpace = primarySpace * directionBottomRightMultiplier;
primarySpace = primarySpace - spacingAdjust;
primarySpace = primarySpace - offsetAdjust;
primarySpace = Math.max(0, primarySpace);
var fitsInPrimarySpace = menu[dimension] <= primarySpace;
if (fitsInPrimarySpace) {
// eg.: direction = "right"
// menu left side is placed to right side of toggler
// menu.left = toggler.width
var distance_1 = toggler[dimension] - secondaryDimensionAdjust + spacingAdjust + offsetAdjust;
return [directionReverse, distance_1];
}
var secondarySpace = toggler[directionReverse] - viewport[directionReverse];
secondarySpace = secondarySpace + secondaryDimensionAdjust * directionBottomRightMultiplier;
secondarySpace = secondarySpace * directionBottomRightMultiplier;
secondarySpace = secondarySpace - spacingAdjust;
secondarySpace = secondarySpace - offsetAdjust;
secondarySpace = Math.max(0, secondarySpace);
var fitsInSecondarySpace = menu[dimension] <= secondarySpace;
if (fitsInSecondarySpace) {
// eg.: direction = "right"
// menu right side is placed to left side of toggler
// menu.left = -menu.width
var distance_2 = -menu[dimension] + secondaryDimensionAdjust - spacingAdjust - offsetAdjust;
return [directionReverse, distance_2];
}
var doesNotFitInViewport = menu[dimension] > viewport[dimension];
if (doesNotFitInViewport) {
// eg.: direction = "right"
// menu left side is always placed to left side of viewport
// menu.left = viewport.left - menu.left
var distance_3 = (viewport[directionReverse] - toggler[directionReverse]) * directionBottomRightMultiplier;
return [directionReverse, distance_3];
}
// eg.: direction = "right"
// menu right is placed to the same viewport side
// menu.right = toggler.right - menu.right
var distance = (toggler[direction] - viewport[direction]) * directionBottomRightMultiplier;
return [direction, distance];
}
//# sourceMappingURL=positioningCalculations.js.map