UNPKG

@dnb/eufemia

Version:

DNB Eufemia Design System UI Library

284 lines (283 loc) 10.7 kB
"use strict"; "use client"; Object.defineProperty(exports, "__esModule", { value: true }); exports.useResizeObserver = exports.default = void 0; var _includes = _interopRequireDefault(require("core-js-pure/stable/instance/includes.js")); var _react = require("react"); var _clsx = require("clsx"); var _componentHelper = require("../../shared/component-helper.js"); var _PaginationCalculation = require("./PaginationCalculation.js"); var _PaginationContext = _interopRequireDefault(require("./PaginationContext.js")); var _Context = _interopRequireDefault(require("../../shared/Context.js")); var _Button = _interopRequireDefault(require("../button/Button.js")); var _IconPrimary = _interopRequireDefault(require("../icon-primary/IconPrimary.js")); var _properties = _interopRequireDefault(require("../../style/themes/ui/properties.js")); var _SpacingUtils = require("../space/SpacingUtils.js"); var _withComponentMarkers = _interopRequireDefault(require("../../shared/helpers/withComponentMarkers.js")); var _helpers = require("../../shared/helpers.js"); var _jsxRuntime = require("react/jsx-runtime"); function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; } const PaginationBar = localProps => { const context = (0, _react.useContext)(_PaginationContext.default); const sharedContext = (0, _react.useContext)(_Context.default); const props = (0, _componentHelper.extendPropsWithContext)(localProps, {}, context.pagination); const { currentPageInternal, pageCountInternal, disabled, skeleton: skeletonProp, space, transformNavigationItem } = props; const skeleton = skeletonProp !== null && skeletonProp !== void 0 ? skeletonProp : sharedContext?.skeleton; const focusPage = () => { const { onPageUpdate, contentRef } = props; onPageUpdate(() => { try { const elem = contentRef.current; elem.focus(); } catch (e) {} }); }; const keepPageHeight = () => { try { const elem = props.contentRef.current; const pageHeight = elem.offsetHeight; elem.style.height = `${pageHeight / 16}rem`; elem.style.minHeight = elem.style.height; } catch (e) {} const { onPageUpdate } = props; onPageUpdate(() => { try { const elem = props.contentRef.current; elem.style.height = 'auto'; elem.style.minHeight = elem.style.height; } catch (e) {} }); }; const setPage = (currentPageInternal, event = null) => { keepPageHeight(); const { setState: setContextState, updatePageContent } = props; setContextState({ currentPageInternal }); updatePageContent(currentPageInternal); (0, _componentHelper.dispatchCustomElementEvent)(props, 'onChange', { pageNumber: currentPageInternal, ...props, event }); }; const setPrevPage = (event = null) => { if ((0, _helpers.isModifiedClickEvent)(event)) { return; } if (event?.currentTarget instanceof HTMLAnchorElement) { event.preventDefault(); } setPage(props.currentPageInternal - 1); }; const setNextPage = (event = null) => { if ((0, _helpers.isModifiedClickEvent)(event)) { return; } if (event?.currentTarget instanceof HTMLAnchorElement) { event.preventDefault(); } setPage(props.currentPageInternal + 1); }; const clickHandler = ({ pageNumber, event }) => { const currentTarget = event?.currentTarget; const isAnchorLikeElement = currentTarget instanceof HTMLAnchorElement || currentTarget?.getAttribute?.('href'); if (isAnchorLikeElement && (0, _helpers.isModifiedClickEvent)(event)) { return; } if (isAnchorLikeElement) { event?.preventDefault(); } setPage(pageNumber, event); focusPage(); }; const { getTranslation } = (0, _react.useContext)(_Context.default); const { buttonTitle, prevTitle, nextTitle, morePages } = (0, _componentHelper.extendPropsWithContext)(props, {}, getTranslation(props).Pagination); const prevIsDisabled = currentPageInternal > -1 ? currentPageInternal === 1 : true; const nextIsDisabled = currentPageInternal > -1 ? currentPageInternal === pageCountInternal || pageCountInternal === 0 : true; const paginationBarRef = (0, _react.useRef)(null); const currentScreenSize = useResizeObserver(paginationBarRef); const pageNumberGroups = (0, _PaginationCalculation.calculatePagination)(pageCountInternal, currentPageInternal, currentScreenSize === 'small'); const renderPaginationButton = (pageNumber, extraClassName) => { const isCurrent = pageNumber === currentPageInternal; const label = buttonTitle.replace('%s', String(pageNumber)); if (!transformNavigationItem) { return (0, _jsxRuntime.jsx)(_Button.default, { className: (0, _clsx.clsx)('dnb-pagination__button', extraClassName), text: String(pageNumber), "aria-label": label, variant: isCurrent ? 'primary' : 'secondary', disabled: disabled, skeleton: skeleton, "aria-current": isCurrent ? 'page' : null, onClick: event => clickHandler({ pageNumber, event }) }, pageNumber); } if (isCurrent && !skeleton) { return (0, _jsxRuntime.jsx)("span", { className: (0, _clsx.clsx)('dnb-pagination__button', 'dnb-pagination__button--current', extraClassName), "aria-label": label, "aria-current": "page", children: String(pageNumber) }, pageNumber); } return (0, _jsxRuntime.jsx)(_react.Fragment, { children: transformNavigationItem(pageNumber, { className: (0, _clsx.clsx)('dnb-pagination__button', extraClassName), 'aria-label': label, skeleton, disabled, onClick: event => clickHandler({ pageNumber, event }), children: String(pageNumber) }) }, pageNumber); }; const renderStepButton = direction => { const isPrev = direction === 'prev'; const isDisabled = isPrev ? prevIsDisabled : nextIsDisabled; const title = isPrev ? prevTitle : nextTitle; const icon = isPrev ? 'chevron_left' : 'chevron_right'; const onNavigate = isPrev ? setPrevPage : setNextPage; if (!transformNavigationItem) { return (0, _jsxRuntime.jsx)(_Button.default, { disabled: disabled || isDisabled, skeleton: skeleton, variant: "tertiary", icon: icon, iconPosition: isPrev ? 'left' : 'right', text: title, onClick: onNavigate, title: isDisabled ? null : title }, `${direction}-arrow`); } if (isDisabled) { return null; } const pageNumber = currentPageInternal + (isPrev ? -1 : 1); return (0, _jsxRuntime.jsx)(_react.Fragment, { children: transformNavigationItem(pageNumber, { className: (0, _clsx.clsx)('dnb-pagination__button', `dnb-pagination__button--${direction}`), 'aria-label': title, title, skeleton, disabled, onClick: event => onNavigate(event), children: (0, _jsxRuntime.jsx)(_IconPrimary.default, { icon: icon }) }) }, `${direction}-arrow`); }; return (0, _jsxRuntime.jsxs)("div", { ref: paginationBarRef, ...(0, _SpacingUtils.useSpacing)({ space }, { className: (0, _clsx.clsx)('dnb-pagination__bar', pageCountInternal >= 8 && 'dnb-pagination--many-pages') }), children: [(0, _jsxRuntime.jsxs)("div", { className: "dnb-pagination__bar__wrapper", children: [!transformNavigationItem && (0, _jsxRuntime.jsxs)("div", { className: "dnb-pagination__bar__skip", children: [renderStepButton('prev'), renderStepButton('next')] }), (0, _jsxRuntime.jsxs)("div", { className: "dnb-pagination__bar__inner", children: [transformNavigationItem && renderStepButton('prev'), (pageNumberGroups?.[0] || []).map(pageNumber => renderPaginationButton(pageNumber)), pageNumberGroups.slice(1).map((numbersList, idx) => (0, _jsxRuntime.jsxs)(_react.Fragment, { children: [(0, _jsxRuntime.jsx)(_IconPrimary.default, { role: "separator", "aria-orientation": "vertical", "aria-hidden": false, title: (0, _PaginationCalculation.getDotsAriaLabel)({ morePages, numbersList, pageNumberGroups }), className: "dnb-pagination__dots", icon: "more", size: "medium" }), numbersList.map(pageNumber => renderPaginationButton(pageNumber, String(pageNumber).length > 3 ? 'dnb-pagination__button--large-number' : undefined))] }, idx)), transformNavigationItem && renderStepButton('next')] })] }), (0, _jsxRuntime.jsx)("span", { className: "dnb-sr-only", "aria-live": "assertive", children: buttonTitle.replace('%s', String(currentPageInternal)) })] }); }; const useResizeObserver = element => { const [currentSize, setSize] = (0, _react.useState)('large'); const resizeObserver = (0, _react.useRef)(null); (0, _react.useEffect)(() => { try { const handleSizeChange = width => { if (width <= getSizeInPx('small') && currentSize !== 'small') { setSize('small'); } else if (width <= getSizeInPx('medium') && currentSize !== 'medium') { setSize('medium'); } else if (width <= getSizeInPx('large') && currentSize !== 'large') { setSize('large'); } else if (width <= getSizeInPx('x-large') && currentSize !== 'x-large') { setSize('x-large'); } else if (width <= getSizeInPx('xx-large') && currentSize !== 'xx-large') { setSize('xx-large'); } }; resizeObserver.current = new ResizeObserver(entries => { handleSizeChange(entries[0].contentRect.width); }); resizeObserver.current?.observe(element.current); handleSizeChange(element.current.clientWidth); } catch (e) {} return () => { resizeObserver.current?.disconnect(); }; }, [element]); return currentSize; }; exports.useResizeObserver = useResizeObserver; const getSizeInPx = size => { const styleSize = _properties.default[`--layout-${size}`]; if ((0, _includes.default)(styleSize).call(styleSize, 'em')) { return parseFloat(styleSize.replace(/(rem|em)$/, '')) * 16; } return parseFloat(styleSize.replace(/(px)$/, '')); }; (0, _withComponentMarkers.default)(PaginationBar, { _supportsSpacingProps: true }); var _default = exports.default = PaginationBar; //# sourceMappingURL=PaginationBar.js.map