@react-md/utils
Version:
General utils for react-md.
204 lines • 8.59 kB
JavaScript
import { getAboveCoord, getBelowCoord, getBottomCoord, getCenterYCoord, getTopCoord, } from "./getCoord";
/**
* Attempts to position the fixed element so that it will appear completely
* above the container element but also within the viewport boundaries. When
* swapping is enabled, it will attempt to swap to the below position if it
* can't fit within the viewport above the container element. If it can't fit in
* the viewport even after being swapped below or swapping is disabled, it will
* be positioned to the top viewport boundary.
*
* @internal
*/
export function createAnchoredAbove(config) {
var yMargin = config.yMargin, vhMargin = config.vhMargin, screenBottom = config.screenBottom, elHeight = config.elHeight, containerRect = config.containerRect, preventOverlap = config.preventOverlap, disableSwapping = config.disableSwapping, disableVHBounds = config.disableVHBounds;
var top = getAboveCoord(config);
var actualY = "above";
if (disableVHBounds) {
// can't actually allow a top value as a negative number since browsers
// won't scroll upwards past the normal page top
return { actualY: actualY, top: Math.max(0, top) };
}
if (top > vhMargin) {
// don't need to do anything else since the top is still in the viewport and
// since it's positioned above, we already know it can't overlap the
// container element
return { actualY: actualY, top: top };
}
var swappedTop = getBelowCoord(config);
if (disableSwapping || swappedTop + elHeight > screenBottom) {
top = Math.min(top, vhMargin);
}
else {
actualY = "below";
top = swappedTop;
}
var bottom;
if (preventOverlap &&
// can't overlap if it's positioned below
actualY === "above" &&
top + elHeight > containerRect.top) {
bottom = screenBottom - containerRect.top + yMargin;
}
return { actualY: actualY, top: top, bottom: bottom };
}
/**
* Attempts to position the fixed element so that it will appear fixed to the
* top of the container element but also within the viewport boundaries. When
* swapping is enabled, it will attempt to swap to the bottom position if it
* can't fit within the viewport. If it can't fit in the viewport even after
* being swapped to the bottom position or swapping is disabled, it will be
* positioned to the top viewport boundary.
*
* @internal
*/
export function createAnchoredTop(config) {
var vhMargin = config.vhMargin, screenBottom = config.screenBottom, elHeight = config.elHeight, disableSwapping = config.disableSwapping, disableVHBounds = config.disableVHBounds;
var top = getTopCoord(config);
var actualY = "top";
if (disableVHBounds || top + elHeight <= screenBottom) {
return { actualY: actualY, top: top };
}
var swappedTop = getBottomCoord(config);
if (disableSwapping || swappedTop < vhMargin) {
top = Math.max(top, vhMargin);
}
else {
actualY = "bottom";
top = swappedTop;
}
return { actualY: actualY, top: top };
}
/**
* Attempts to position the fixed element so that it will appear at the center
* of the container element but also within the viewport boundaries. If the
* entered element can't fit within the viewport, it'll update the top value
* to either be the vhMargin or position to the screen bottom boundary
*
* @internal
*/
export function createAnchoredCenter(config) {
var vhMargin = config.vhMargin, screenBottom = config.screenBottom, elHeight = config.elHeight, disableVHBounds = config.disableVHBounds;
var top = getCenterYCoord(config);
var actualY = "center";
if (disableVHBounds) {
return { actualY: actualY, top: Math.max(0, top) };
}
top = Math.max(vhMargin, top);
if (top + elHeight > screenBottom) {
top = screenBottom - elHeight;
}
return { actualY: actualY, top: top };
}
/**
* Attempts to position the fixed element so that it will appear fixed to the
* bottom of the container element but also within the viewport boundaries. When
* swapping is enabled, it will attempt to swap to the top position if it can't
* fit within the viewport. If it can't fit in the viewport even after being
* swapped to the top position or swapping is disabled, it will be positioned to
* the bottom viewport boundary.
*
* @internal
*/
export function createAnchoredBottom(config) {
var vhMargin = config.vhMargin, screenBottom = config.screenBottom, elHeight = config.elHeight, disableSwapping = config.disableSwapping, disableVHBounds = config.disableVHBounds;
var top = getBottomCoord(config);
var actualY = "bottom";
if (disableVHBounds || top > vhMargin) {
return { actualY: actualY, top: top };
}
var swappedTop = getTopCoord(config);
if (disableSwapping || swappedTop + elHeight > screenBottom) {
top = Math.min(top, screenBottom - elHeight);
}
else {
actualY = "top";
top = swappedTop;
}
return { actualY: actualY, top: top };
}
/**
* Attempts to position the fixed element so that it will appear completely
* below the container element but also within the viewport boundaries. When
* swapping is enabled, it will attempt to swap to the above position if it
* can't fit within the viewport below the container element. If it can't fit in
* the viewport even after being swapped above or swapping is disabled, it will
* be positioned to the bottom viewport boundary.
*
* @internal
*/
export function createAnchoredBelow(config) {
var yMargin = config.yMargin, vhMargin = config.vhMargin, elHeight = config.elHeight, screenBottom = config.screenBottom, containerRect = config.containerRect, preventOverlap = config.preventOverlap, disableSwapping = config.disableSwapping, disableVHBounds = config.disableVHBounds;
var top = getBelowCoord(config);
var actualY = "below";
if (disableVHBounds || top + elHeight <= screenBottom) {
return { actualY: actualY, top: top };
}
if (preventOverlap) {
var availableTop = containerRect.top - yMargin;
if (disableSwapping || availableTop < screenBottom - top) {
return {
actualY: actualY,
top: top,
bottom: vhMargin,
};
}
return {
actualY: "above",
top: Math.max(vhMargin, availableTop - elHeight),
// this makes it so that the bottom of the fixed element is the top of the container
// element. this ensures that it won't ever overlap the container element
bottom: window.innerHeight - availableTop,
};
}
var swappedTop = getAboveCoord(config);
if (disableSwapping || swappedTop < vhMargin) {
top = Math.min(top, screenBottom - elHeight);
}
else {
actualY = "above";
top = swappedTop;
}
return { actualY: actualY, top: top };
}
/**
* Creates the vertical position for a fixed element with the provided options.
*
* @internal
*/
export function createVerticalPosition(options) {
var y = options.y, vh = options.vh, vhMargin = options.vhMargin, yMargin = options.yMargin, elHeight = options.elHeight, initialY = options.initialY, containerRect = options.containerRect, disableSwapping = options.disableSwapping, preventOverlap = options.preventOverlap, disableVHBounds = options.disableVHBounds;
if (!disableVHBounds && !preventOverlap && elHeight > vh - vhMargin * 2) {
// the element is too big to be displayed in the viewport, so just span the
// full viewport excluding margins
return {
top: vhMargin,
bottom: vhMargin,
actualY: "center",
transformOriginY: containerRect.top,
};
}
var config = {
vhMargin: vhMargin,
yMargin: yMargin,
elHeight: elHeight,
initialY: initialY,
containerRect: containerRect,
screenBottom: vh - vhMargin,
preventOverlap: preventOverlap,
disableSwapping: disableSwapping,
disableVHBounds: disableVHBounds,
};
switch (y) {
case "above":
return createAnchoredAbove(config);
case "top":
return createAnchoredTop(config);
case "center":
return createAnchoredCenter(config);
case "bottom":
return createAnchoredBottom(config);
case "below":
return createAnchoredBelow(config);
}
}
//# sourceMappingURL=createVerticalPosition.js.map