UNPKG

@engie-group/fluid-design-system-react

Version:

Fluid Design System React

95 lines (92 loc) 4.72 kB
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 };