@engie-group/fluid-design-system-react
Version:
Fluid Design System React
95 lines (92 loc) • 4.72 kB
JavaScript
import { jsx, jsxs } from 'react/jsx-runtime';
import React__default, { useState, useEffect } from 'react';
import { Utils } from '../../utils/util.js';
import { NJMoreItem } from './NJMoreItem.js';
import { NJPaginationArrow } from './NJPaginationArrow.js';
import { NJPaginationItem } from './NJPaginationItem.js';
const NJPaginationRoot = React__default.forwardRef(({ count, currentItem = 1, ariaLabelPrevious, ariaLabelNext, onChange, renderPageAs, renderArrowAs, ...htmlProps }, ref) => {
const [current, setCurrent] = useState(currentItem);
const items = Array(count).fill({});
const more = getMorePosition(count, current);
useEffect(() => {
if (currentItem < 1)
currentItem = 1;
else if (currentItem > count)
currentItem = count;
setCurrent(currentItem);
}, [currentItem]);
const changeCurrentItem = (e, direction) => {
e.preventDefault();
const el = e.currentTarget;
let newItem = current;
if (direction?.previous) {
newItem = Math.max(current - 1, 1);
}
else if (direction?.next) {
newItem = Math.min(current + 1, count);
}
else {
newItem = Math.max(1, Math.min(parseInt(el.dataset.index ?? '0', 10), count));
}
setCurrent(newItem);
if (current !== newItem && typeof onChange === 'function') {
onChange(newItem, e);
}
};
const onArrowClick = (type) => (e) => {
changeCurrentItem(e, { [type]: true });
};
return (jsx("nav", { ...htmlProps, ref: ref, "aria-label": "pagination navigation", role: "navigation", children: jsxs("ul", { className: "nj-pagination", children: [jsx("li", { className: "nj-pagination__item", children: renderArrowAs ? (renderArrowAs({
arrowType: 'previous',
['aria-label']: ariaLabelPrevious,
onClick: onArrowClick('previous'),
disabled: current === 1
})) : (jsx(NJPaginationArrow, { arrowType: "previous", "aria-label": ariaLabelPrevious, onClick: (e) => changeCurrentItem(e, { previous: true }), disabled: current === 1 })) }), items.map((item, index) => {
if (isItemVisible(index + 1, current, count)) {
const isCurrent = current === index + 1;
const hasMoreAfter = index + 1 === count && more.right;
const hasMoreBefore = index + 1 === 1 && more.left;
const dataIndex = index + 1;
return (jsxs(React__default.Fragment, { children: [hasMoreAfter && jsx(NJMoreItem, {}), jsx("li", { className: Utils.classNames('nj-pagination__item', {
['nj-pagination__item--active']: isCurrent
}), children: renderPageAs ? (renderPageAs({
index: dataIndex,
current: isCurrent,
['aria-label']: `Page ${dataIndex}`,
onClick: changeCurrentItem
})) : (jsx(NJPaginationItem, { index: dataIndex, current: isCurrent, onClick: changeCurrentItem })) }, dataIndex), hasMoreBefore && jsx(NJMoreItem, {})] }, index));
}
}), jsx("li", { className: "nj-pagination__item", children: renderArrowAs ? (renderArrowAs({
arrowType: 'next',
['aria-label']: ariaLabelNext,
onClick: onArrowClick('next'),
disabled: current === count
})) : (jsx(NJPaginationArrow, { arrowType: "next", "aria-label": ariaLabelNext, onClick: (e) => changeCurrentItem(e, { next: true }), disabled: current === count })) })] }) }));
});
NJPaginationRoot.displayName = 'NJPaginationRoot';
const isItemVisible = (item, current, count) => {
if (item === 1 || item === count || item === current)
return true;
if (item >= current - 1 && item <= current + 1)
return true;
if (item < 6 && current < 6 - 2)
return true;
return item >= count - 6 + 2 && current >= count - 2;
};
const getMorePosition = (count, current) => {
const more = { left: false, right: false };
if (count > 6) {
let right = false;
let left = false;
if (current > 3) {
left = true;
}
if (current <= count - 3) {
right = true;
}
more.right = right;
more.left = left;
}
return more;
};
export { NJPaginationRoot };