@primer/react
Version:
An implementation of GitHub's Primer Design System using React
124 lines (123 loc) • 3.16 kB
JavaScript
//#region src/Pagination/model.tsx
function buildPaginationModel(pageCount, currentPage, showPages, marginPageCount, surroundingPageCount) {
const prev = {
type: "PREV",
num: currentPage - 1,
disabled: currentPage === 1
};
const next = {
type: "NEXT",
num: currentPage + 1,
disabled: currentPage === pageCount
};
if (!showPages) return [prev, next];
if (pageCount <= 0) return [prev, {
...next,
disabled: true
}];
const pages = [];
const standardGap = surroundingPageCount + marginPageCount;
if (pageCount <= standardGap + standardGap + 3) {
addPages(1, pageCount, false);
return [
prev,
...pages,
next
];
}
let startGap = 0;
let startOffset = 0;
if (currentPage - standardGap - 1 <= 1) startOffset = currentPage - standardGap - 2;
else startGap = currentPage - standardGap - 1;
let endGap = 0;
let endOffset = 0;
if (pageCount - currentPage - standardGap <= 1) endOffset = pageCount - currentPage - standardGap - 1;
else endGap = pageCount - currentPage - standardGap;
const hasStartEllipsis = startGap > 0;
const hasEndEllipsis = endGap > 0;
addPages(1, marginPageCount, hasStartEllipsis);
if (hasStartEllipsis) addEllipsis(marginPageCount);
addPages(marginPageCount + startGap + endOffset + 1, pageCount - startOffset - endGap - marginPageCount, hasEndEllipsis);
if (hasEndEllipsis) addEllipsis(pageCount - startOffset - endGap - marginPageCount);
addPages(pageCount - marginPageCount + 1, pageCount);
return [
prev,
...pages,
next
];
function addEllipsis(previousPage) {
pages.push({
type: "BREAK",
num: previousPage + 1
});
}
function addPages(start, end, precedesBreak = false) {
for (let i = start; i <= end; i++) pages.push({
type: "NUM",
num: i,
selected: i === currentPage,
precedesBreak: i === end && precedesBreak
});
}
}
function buildComponentData(page, hrefBuilder, onClick) {
const props = {};
let content = "";
let key = "";
switch (page.type) {
case "PREV":
key = "page-prev";
content = "Previous";
if (page.disabled) Object.assign(props, {
rel: "prev",
"aria-hidden": "true",
"aria-disabled": "true"
});
else Object.assign(props, {
rel: "prev",
href: hrefBuilder(page.num),
"aria-label": "Previous Page",
onClick
});
break;
case "NEXT":
key = "page-next";
content = "Next";
if (page.disabled) Object.assign(props, {
rel: "next",
"aria-hidden": "true",
"aria-disabled": "true"
});
else Object.assign(props, {
rel: "next",
href: hrefBuilder(page.num),
"aria-label": "Next Page",
onClick
});
break;
case "NUM":
key = `page-${page.num}`;
content = String(page.num);
Object.assign(props, {
href: hrefBuilder(page.num),
"aria-label": `Page ${page.num}${page.precedesBreak ? "..." : ""}`,
onClick,
"aria-current": page.selected ? "page" : void 0
});
break;
case "BREAK":
key = `page-${page.num}-break`;
content = "…";
Object.assign(props, {
as: "span",
role: "presentation"
});
}
return {
props,
key,
content
};
}
//#endregion
export { buildComponentData, buildPaginationModel };