@exadel/esl
Version:
Exadel Smart Library (ESL) is the lightweight custom elements library that provide a set of super-flexible components
81 lines (80 loc) • 3.6 kB
JavaScript
import { resolveOffset, getDocScrollingEl } from './incremental-scroll-utils';
/**
* Alignment strategy that keeps current scroll position unchanged.
* Always returns zero distance, effectively disabling scroll on this axis.
*/
export const keepPosition = () => () => 0;
/** Creates alignment strategy that positions element at the top of container or viewport */
export function alignToTop(options) {
const offset = resolveOffset(options.offset, 'y');
return (opts) => {
const { elRect, containerRect } = opts;
if (containerRect)
return elRect ? elRect.top - containerRect.top - offset : 0;
return elRect ? elRect.top - offset : -window.scrollY + offset;
};
}
/** Creates alignment strategy that centers element vertically in container or viewport */
export function alignToMiddle(options) {
const offset = resolveOffset(options.offset, 'y');
return (opts) => {
const { elRect, containerRect } = opts;
if (containerRect)
return elRect ? elRect.cy - containerRect.cy - offset : 0;
if (!elRect) {
const desiredY = Math.max(0, (getDocScrollingEl().scrollHeight - window.innerHeight) / 2);
return desiredY - window.scrollY + offset;
}
const viewportCenter = window.innerHeight / 2;
return elRect.cy - viewportCenter - offset;
};
}
/** Creates alignment strategy that positions element at the bottom of container or viewport */
export function alignToBottom(options) {
const offset = resolveOffset(options.offset, 'y');
return (opts) => {
const { elRect, containerRect } = opts;
if (containerRect)
return elRect ? elRect.bottom - containerRect.bottom - offset : 0;
if (!elRect)
return getDocScrollingEl().scrollHeight - window.innerHeight - window.scrollY + offset;
return elRect.bottom - window.innerHeight - offset;
};
}
/** Creates alignment strategy that positions element at the left edge of container or viewport */
export function alignToLeft(options) {
const offset = resolveOffset(options.offset, 'x');
return (opts) => {
const { elRect, containerRect } = opts;
if (containerRect)
return elRect ? elRect.left - containerRect.left - offset : 0;
return elRect ? elRect.left - offset : -window.scrollX + offset;
};
}
/** Creates alignment strategy that centers element horizontally in container or viewport */
export function alignToCenter(options) {
const offset = resolveOffset(options.offset, 'x');
return (opts) => {
const { elRect, containerRect } = opts;
if (containerRect)
return elRect ? elRect.cx - containerRect.cx - offset : 0;
if (!elRect) {
const desiredX = Math.max(0, (getDocScrollingEl().scrollWidth - window.innerWidth) / 2);
return desiredX - window.scrollX + offset;
}
const viewportCenter = window.innerWidth / 2;
return elRect.cx - viewportCenter - offset;
};
}
/** Creates alignment strategy that positions element at the right edge of container or viewport */
export function alignToRight(options) {
const offset = resolveOffset(options.offset, 'x');
return (opts) => {
const { elRect, containerRect } = opts;
if (containerRect)
return elRect ? elRect.right - containerRect.right - offset : 0;
if (!elRect)
return getDocScrollingEl().scrollWidth - window.innerWidth - window.scrollX + offset;
return elRect.right - window.innerWidth - offset;
};
}