wix-style-react
Version:
wix-style-react
248 lines (246 loc) • 10 kB
JavaScript
;
exports.__esModule = true;
exports.calculateWidth = void 0;
exports.createResponsiveLayout = createResponsiveLayout;
exports.createResponsiveLayoutTemplate = createResponsiveLayoutTemplate;
exports.createStaticLayout = createStaticLayout;
exports.measureAndSetRootMinWidth = exports.getId = void 0;
var getId = exports.getId = function getId() {
var idPrefix = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : '';
var name = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : '';
return idPrefix ? idPrefix + name : undefined;
};
var calculateWidth = totalPages => "".concat(totalPages.toString().length, "em");
exports.calculateWidth = calculateWidth;
var measureAndSetRootMinWidth = exports.measureAndSetRootMinWidth = function measureAndSetRootMinWidth(compNode, paginationMode) {
var idPrefix = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : '';
compNode.style.minWidth = '';
compNode.style.minHeight = '';
var getById = id => compNode.querySelector("#".concat(getId(idPrefix, id)));
var getMinWidth = elmnt => elmnt ? parseInt(window.getComputedStyle(elmnt).minWidth, 10) : 0;
var getWidthWithMargins = element => {
if (!element) {
return 0;
}
var style = window.getComputedStyle(element);
return parseInt(style.marginRight, 10) + element.offsetWidth + parseInt(style.marginLeft, 10);
};
var getHeightWithMargins = element => {
if (!element) {
return 0;
}
var style = window.getComputedStyle(element);
return parseInt(style.marginBottom, 10) + element.offsetHeight + parseInt(style.marginTop, 10);
};
var navButtonsMinWidth = getWidthWithMargins(getById('navButtonNext')) + getWidthWithMargins(getById('navButtonPrevious')) + getWidthWithMargins(getById('navButtonFirst')) + getWidthWithMargins(getById('navButtonLast'));
var selectionMinWidth = 0;
var minHeight = 0;
if (paginationMode === 'pages') {
// means we're in "pages" pagination mode
selectionMinWidth = getMinWidth(getById('pageStrip'));
minHeight = Math.max(getHeightWithMargins(getById('pageStrip')), getHeightWithMargins(getById('navButtonNext')));
} else if (paginationMode === 'input') {
// means we're in "input" pagination mode
selectionMinWidth = getWidthWithMargins(getById('totalPages')) + getWidthWithMargins(getById('slash')) + getWidthWithMargins(getById('pageInput'));
minHeight = Math.max(getHeightWithMargins(getById('pageInput')), getHeightWithMargins(getById('navButtonNext')));
} else if (paginationMode === 'compact') {
// means we're in "compact" pagination mode
selectionMinWidth = getWidthWithMargins(getById('totalPages')) + getWidthWithMargins(getById('slash')) + getWidthWithMargins(getById('currentPage'));
minHeight = Math.max(getHeightWithMargins(getById('currentPage')), getHeightWithMargins(getById('navButtonNext')));
}
compNode.style.minWidth = navButtonsMinWidth + selectionMinWidth + 'px';
compNode.style.minHeight = minHeight + 'px';
};
function createStaticLayout(_ref) {
var {
totalPages,
currentPage,
maxPagesToShow,
showFirstPage,
showLastPage
} = _ref;
return createLayout({
totalPages,
currentPage,
lowerBound: 1,
upperBound: totalPages,
pageRangeCost: (a, b) => b - a + 1,
showFirstPage,
showLastPage,
rewindToFirstCost: 2,
rewindToLastCost: 2,
budget: maxPagesToShow
});
}
function rangeToPreRenderForResponsiveLayout(totalPages, currentPage, maxPagesToShow) {
return [Math.max(currentPage - maxPagesToShow, 1), Math.min(currentPage + maxPagesToShow, totalPages)];
}
function createResponsiveLayoutTemplate(_ref2) {
var {
totalPages,
currentPage,
maxPagesToShow
} = _ref2;
var [lowerBound, upperBound] = rangeToPreRenderForResponsiveLayout(totalPages, currentPage, maxPagesToShow);
return [1, 0, ...closedRange(lowerBound, upperBound), 0, totalPages];
}
// Takes a container with children rendered using createResponsiveLayoutTemplate,
// measures the children, and decides how many can be shown without overflowing the container.
// For measurements to work correctly the pages must not have any dynamic spacing between them
// such as justify-content: space-evenly, but they can have static spacing such as margins.
// As long as we're using flexbox with centered pages we don't need to worry about the outer
// margins of the first and last page, they will be trimmed by flexbox automatically.
// maxPagesToShow is not really taken into account, it's used to derive the range of pages
// that was pre-rendered by createResponsiveLayoutTemplate().
function createResponsiveLayout(_ref3) {
var {
container,
totalPages,
currentPage,
maxPagesToShow,
showFirstPage,
showLastPage
} = _ref3;
var children = Array.from(container.children);
var pages = children.slice(2, -2);
var containerWidth = container.getBoundingClientRect().width;
var firstRect = children[0].getBoundingClientRect();
var lastRect = children[children.length - 1].getBoundingClientRect();
var lowerRect = pages[0].getBoundingClientRect();
var upperRect = pages[pages.length - 1].getBoundingClientRect();
var rewindToFirstCost = mergeBoundingRects(firstRect, lowerRect).width - lowerRect.width;
var rewindToLastCost = mergeBoundingRects(lastRect, upperRect).width - upperRect.width;
var [lowerBound, upperBound] = rangeToPreRenderForResponsiveLayout(totalPages, currentPage, maxPagesToShow);
var pageRangeCost = (a, b) => {
var aRect = pages[a - lowerBound].getBoundingClientRect();
var bRect = pages[b - lowerBound].getBoundingClientRect();
return mergeBoundingRects(aRect, bRect).width;
};
return createLayout({
totalPages,
currentPage,
lowerBound,
upperBound,
pageRangeCost,
showFirstPage,
showLastPage,
rewindToFirstCost,
rewindToLastCost,
budget: containerWidth
});
}
function createLayout(_ref4) {
var {
totalPages,
currentPage,
lowerBound,
upperBound,
pageRangeCost,
showFirstPage,
showLastPage,
rewindToFirstCost,
rewindToLastCost,
budget
} = _ref4;
var prevOrLowerBound = Math.max(currentPage - 1, lowerBound);
var nextOrUpperBound = Math.min(currentPage + 1, upperBound);
var expand = (low, high, showRewindToFirst, showRewindToLast) => createLayoutByExpandingPageRange({
totalPages,
low,
high,
lowerBound,
upperBound,
pageRangeCost,
budget,
showRewindToFirst,
showRewindToLast,
rewindToFirstCost,
rewindToLastCost
});
return (
// Try to show the entire range.
(lowerBound === 1 || !showFirstPage) && (upperBound === totalPages || !showLastPage) && expand(lowerBound, upperBound, false, false) ||
// Ellipsis only in the end. Show at least one page after the current.
showLastPage && lowerBound === 1 && expand(lowerBound, nextOrUpperBound, false, true) ||
// Ellipsis only in the beginning. Show at least one page before the current.
showFirstPage && upperBound === totalPages && expand(prevOrLowerBound, upperBound, true, false) ||
// Ellipses on both sides. Show at least one page before the current and one after.
showFirstPage && showLastPage && expand(prevOrLowerBound, nextOrUpperBound, true, true) ||
// Ellipsis only in the end. Don't try to include the next page.
showLastPage && lowerBound === 1 && expand(lowerBound, currentPage, false, true) ||
// Ellipsis only in the beginning. Don't try to include the previous page.
showFirstPage && upperBound === totalPages && expand(currentPage, upperBound, true, false) ||
// Ellipses on both sides. Don't try to include the previous and the next page.
showFirstPage && showLastPage && expand(currentPage, currentPage, true, true) ||
// Cut off both sides without adding ellipses.
expand(currentPage, currentPage, false, false) || [currentPage] // If there's not enough space even for the current page, still show it.
);
}
function createLayoutByExpandingPageRange(_ref5) {
var {
totalPages,
low,
high,
lowerBound,
upperBound,
pageRangeCost,
budget,
showRewindToFirst,
showRewindToLast,
rewindToFirstCost,
rewindToLastCost
} = _ref5;
var safeLowerBound = showRewindToFirst ? Math.max(lowerBound, 4) : lowerBound;
var safeUpperBound = showRewindToLast ? Math.min(upperBound, totalPages - 3) : upperBound;
if (!isNondecreasing([lowerBound, safeLowerBound, low, high, safeUpperBound, upperBound])) {
return null;
}
lowerBound = safeLowerBound;
upperBound = safeUpperBound;
budget -= (showRewindToFirst ? rewindToFirstCost : 0) + (showRewindToLast ? rewindToLastCost : 0);
var acceptableLow = 0;
var acceptableHigh = 0;
while (lowerBound <= low && high <= upperBound && pageRangeCost(low, high) <= budget) {
acceptableLow = low;
acceptableHigh = high;
if (low === lowerBound && high === upperBound) {
break;
}
low = Math.max(low - 1, lowerBound);
high = Math.min(high + 1, upperBound);
}
return acceptableLow && acceptableHigh ? [...(showRewindToFirst ? [1, 0] : []), ...closedRange(acceptableLow, acceptableHigh), ...(showRewindToLast ? [0, totalPages] : [])] : null;
}
function closedRange(start, stop) {
var step = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 1;
var result = [];
for (var i = start; i <= stop; i += step) {
result.push(i);
}
return result;
}
function isNondecreasing(sequence) {
for (var i = 1; i < sequence.length; i++) {
if (sequence[i] < sequence[i - 1]) {
return false;
}
}
return true;
}
function mergeBoundingRects(a, b) {
var top = Math.min(a.top, b.top);
var right = Math.max(a.right, b.right);
var bottom = Math.max(a.bottom, b.bottom);
var left = Math.min(a.left, b.left);
var width = right - left;
var height = bottom - top;
return {
top,
right,
bottom,
left,
width,
height
};
}
//# sourceMappingURL=utils.js.map