UNPKG

@dnb/eufemia

Version:

DNB Eufemia Design System UI Library

433 lines (432 loc) 17 kB
"use strict"; "use client"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = void 0; var _parse = _interopRequireDefault(require("core-js-pure/stable/json/parse.js")); var _push = _interopRequireDefault(require("core-js-pure/stable/instance/push.js")); var _react = _interopRequireWildcard(require("react")); var _useIsomorphicLayoutEffect = require("../../shared/helpers/useIsomorphicLayoutEffect.js"); var _Context = _interopRequireDefault(require("../../shared/Context.js")); var _componentHelper = require("../../shared/component-helper.js"); var _PaginationHelpers = require("./PaginationHelpers.js"); var _PaginationContext = _interopRequireDefault(require("./PaginationContext.js")); var _jsxRuntime = require("react/jsx-runtime"); function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function (e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != typeof e && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (const t in e) "default" !== t && {}.hasOwnProperty.call(e, t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, t)) && (i.get || i.set) ? o(f, t, i) : f[t] = e[t]); return f; })(e, t); } function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; } const PaginationProvider = props => { const sharedContext = (0, _react.useContext)(_Context.default); const computeDerived = (0, _react.useCallback)(() => { const state = {}; if (props.pageCount != null) { state.pageCountInternal = parseFloat(props.pageCount) || 1; } state.parallelLoadCount = parseFloat(props.parallelLoadCount) || 1; state.minTime = parseFloat(props.minWaitTime) || 0; state.placeMakerBeforeContent = props.placeMarkerBeforeContent; return state; }, [props.pageCount, props.parallelLoadCount, props.minWaitTime, props.placeMarkerBeforeContent]); const [items, setItemsState] = (0, _react.useState)(() => { if (typeof props.items === 'string' && props.items[0] === '[') { return (0, _parse.default)(props.items); } else if (Array.isArray(props.items)) { return props.items; } return []; }); const [isLoading, setIsLoading] = (0, _react.useState)(false); const [hasEndedInfinity, setHasEndedInfinity] = (0, _react.useState)(false); const [currentPageInternal, setCurrentPageInternal] = (0, _react.useState)(() => { if (props.currentPage != null) { return parseFloat(props.currentPage) || 1; } return undefined; }); const [startupPage, setStartupPage] = (0, _react.useState)(() => { return parseFloat(props.startupPage) || parseFloat(props.currentPage) || (props.currentPage != null ? parseFloat(props.currentPage) || 1 : undefined); }); const [lowerPage, setLowerPage] = (0, _react.useState)(() => { if (props.useMarkerOnly) { return parseFloat(props.startupPage) || parseFloat(props.currentPage) || 1; } return undefined; }); const [upperPage, setUpperPage] = (0, _react.useState)(() => { if (props.useMarkerOnly) { const sp = parseFloat(props.startupPage) || parseFloat(props.currentPage) || 1; return sp + (parseFloat(props.startupCount) || 1) - 1 || 1; } return undefined; }); const isMountedRef = (0, _react.useRef)(false); const updateStackRef = (0, _react.useRef)([]); const rerenderTimeoutRef = (0, _react.useRef)(undefined); const resetContentTimeoutRef = (0, _react.useRef)(undefined); const resetInfinityTimeoutRef = (0, _react.useRef)(undefined); const callOnPageUpdateTimeoutRef = (0, _react.useRef)(undefined); const pendingCallOnPageUpdateRef = (0, _react.useRef)(false); const pendingSetItemsCbRef = (0, _react.useRef)(null); const pendingSetStateCbRef = (0, _react.useRef)(null); const itemsRef = (0, _react.useRef)(items); const currentPageInternalRef = (0, _react.useRef)(currentPageInternal); const startupPageRef = (0, _react.useRef)(startupPage); itemsRef.current = items; currentPageInternalRef.current = currentPageInternal; startupPageRef.current = startupPage; const propsRef = (0, _react.useRef)(props); propsRef.current = props; const derived = computeDerived(); const prevPropsRef = (0, _react.useRef)({ currentPage: props.currentPage, internalContent: props.internalContent }); const callOnPageUpdate = (0, _react.useCallback)(() => { if (Array.isArray(updateStackRef.current)) { updateStackRef.current.forEach(cb => { if (typeof cb === 'function') { cb(); } }); updateStackRef.current = []; } }, []); const onPageUpdate = (0, _react.useCallback)(fn => { var _context; updateStackRef.current = updateStackRef.current || []; (0, _push.default)(_context = updateStackRef.current).call(_context, fn); }, []); const prefillItems = (0, _react.useCallback)((pageNumber, itemProps = {}, existingItems = itemsRef.current) => { const position = itemProps.position || (pageNumber < currentPageInternalRef.current ? 'before' : 'after'); if (isNaN(pageNumber)) { pageNumber = 1; } const exists = existingItems.findIndex(({ pageNumber: p }) => p === pageNumber) > -1; if (exists) { return existingItems; } const obj = { pageNumber, position, skipObserver: false, ...itemProps }; switch (position) { case 'before': return [new _PaginationHelpers.ContentObject(obj), ...existingItems]; case 'after': return [...existingItems, new _PaginationHelpers.ContentObject(obj)]; } return undefined; }, []); const setContent = (0, _react.useCallback)((newContent, content = null, position = null) => { if (!Array.isArray(newContent) && content) { newContent = [newContent, content]; } const pageNumber = parseFloat(newContent[0]) || 1; newContent = newContent[1]; if (typeof newContent === 'function') { content = newContent(); } else if (_react.default.isValidElement(newContent)) { content = newContent; } if (content) { let itemToPrepare = itemsRef.current.find(({ pageNumber: p }) => p === pageNumber); let newItems = null; if (!itemToPrepare) { newItems = prefillItems(pageNumber, { position }); itemToPrepare = newItems.find(({ pageNumber: p }) => p === pageNumber); } if (itemToPrepare.content) { itemToPrepare.update(content); } else { itemToPrepare.insert(content); } const updatedItems = [...(newItems || itemsRef.current)]; setItemsState(updatedItems); setCurrentPageInternal(pageNumber); pendingCallOnPageUpdateRef.current = true; } }, [prefillItems]); const resetContent = (0, _react.useCallback)(() => { clearTimeout(resetContentTimeoutRef.current); resetContentTimeoutRef.current = setTimeout(() => { setItemsState([]); }, 10); }, []); const resetInfinity = (0, _react.useCallback)((pageNumber = startupPageRef.current) => { const newLowerPage = pageNumber; const newUpperPage = pageNumber + parseFloat(propsRef.current.startupCount) - 1; const newCurrentPageInternal = pageNumber; setItemsState([]); setHasEndedInfinity(true); setLowerPage(newLowerPage); setUpperPage(newUpperPage); setCurrentPageInternal(newCurrentPageInternal); setHasEndedInfinity(false); }, []); const endInfinityDispatchRef = (0, _react.useRef)(false); const endInfinityHandler = (0, _react.useCallback)(() => { setHasEndedInfinity(true); endInfinityDispatchRef.current = true; }, []); const setItems = (0, _react.useCallback)((newItems, cb) => { setItemsState(newItems); if (typeof cb === 'function') { pendingSetItemsCbRef.current = cb; } }, []); const setStateHandler = (0, _react.useCallback)((state, cb) => { if ('items' in state) { setItemsState(state.items); } if ('isLoading' in state) { setIsLoading(state.isLoading); } if ('hasEndedInfinity' in state) { setHasEndedInfinity(state.hasEndedInfinity); } if ('currentPageInternal' in state) { setCurrentPageInternal(state.currentPageInternal); } if ('startupPage' in state) { setStartupPage(state.startupPage); } if ('lowerPage' in state) { setLowerPage(state.lowerPage); } if ('upperPage' in state) { setUpperPage(state.upperPage); } if (typeof cb === 'function') { pendingSetStateCbRef.current = cb; } }, []); const updatePageContent = (0, _react.useCallback)(pageNumber => { const pn = pageNumber !== undefined ? pageNumber : currentPageInternalRef.current; let potentialElement = propsRef.current.internalContent; if (typeof propsRef.current.internalContent === 'function') { potentialElement = propsRef.current.internalContent({ updatePageContent, setContent, resetContent, resetInfinity, endInfinity: endInfinityHandler, setItems, prefillItems, setState: setStateHandler, onPageUpdate, ...propsRef.current, items: itemsRef.current, currentPageInternal: currentPageInternalRef.current, startupPage: startupPageRef.current, isLoading, hasEndedInfinity, lowerPage, upperPage, pageNumber: pn, page: pn }); } if (potentialElement && _react.default.isValidElement(potentialElement)) { setContent([pn, potentialElement]); } }, [setContent, resetContent, resetInfinity, endInfinityHandler, setItems, prefillItems, setStateHandler, onPageUpdate, isLoading, hasEndedInfinity, lowerPage, upperPage]); (0, _useIsomorphicLayoutEffect.useIsomorphicLayoutEffect)(() => { if (hasEndedInfinity && endInfinityDispatchRef.current) { endInfinityDispatchRef.current = false; const pageNumber = currentPageInternalRef.current + 1; (0, _componentHelper.dispatchCustomElementEvent)({ props: propsRef.current }, 'onEnd', { pageNumber, updatePageContent, setContent, resetContent, resetInfinity, endInfinity: endInfinityHandler, setItems, prefillItems, setState: setStateHandler, onPageUpdate, ...propsRef.current, items: itemsRef.current, currentPageInternal: currentPageInternalRef.current, startupPage: startupPageRef.current }); } }, [hasEndedInfinity, updatePageContent, setContent, resetContent, resetInfinity, endInfinityHandler, setItems, prefillItems, setStateHandler, onPageUpdate]); (0, _useIsomorphicLayoutEffect.useIsomorphicLayoutEffect)(() => { if (pendingCallOnPageUpdateRef.current) { pendingCallOnPageUpdateRef.current = false; callOnPageUpdate(); } if (pendingSetItemsCbRef.current) { const cb = pendingSetItemsCbRef.current; pendingSetItemsCbRef.current = null; cb(); } if (pendingSetStateCbRef.current) { const cb = pendingSetStateCbRef.current; pendingSetStateCbRef.current = null; cb(); } }); (0, _useIsomorphicLayoutEffect.useIsomorphicLayoutEffect)(() => { if (typeof props.items === 'string' && props.items[0] === '[') { setItemsState((0, _parse.default)(props.items)); } else if (Array.isArray(props.items)) { setItemsState(props.items); } }, [props.items]); (0, _useIsomorphicLayoutEffect.useIsomorphicLayoutEffect)(() => { if (props.currentPage != null && typeof currentPageInternalRef.current === 'undefined') { setCurrentPageInternal(parseFloat(props.currentPage) || 1); } }, [props.currentPage]); (0, _useIsomorphicLayoutEffect.useIsomorphicLayoutEffect)(() => { if (typeof startupPageRef.current !== 'number') { const derived = parseFloat(props.startupPage) || parseFloat(props.currentPage) || currentPageInternalRef.current; if (typeof derived === 'number' && !isNaN(derived)) { setStartupPage(derived); } } }, [props.startupPage, props.currentPage]); (0, _useIsomorphicLayoutEffect.useIsomorphicLayoutEffect)(() => { if (props.resetContentHandler === true) { setItemsState([]); } }, [props.resetContentHandler]); (0, _useIsomorphicLayoutEffect.useIsomorphicLayoutEffect)(() => { if (props.useMarkerOnly && props.resetPaginationHandler === true) { setLowerPage(undefined); setUpperPage(undefined); } }, [props.useMarkerOnly, props.resetPaginationHandler]); (0, _useIsomorphicLayoutEffect.useIsomorphicLayoutEffect)(() => { if (props.useMarkerOnly) { const sp = startupPageRef.current || parseFloat(props.currentPage) || 1; setLowerPage(prev => { if (typeof prev === 'undefined') { return sp; } const cur = parseFloat(props.currentPage); if (!isNaN(cur) && cur < prev) { return cur; } return prev; }); setUpperPage(prev => { if (typeof prev === 'undefined') { return sp + (parseFloat(props.startupCount) || 1) - 1 || 1; } return prev; }); } }, [props.useMarkerOnly, props.currentPage, props.startupCount]); (0, _react.useEffect)(() => { if (props.rerender) { const rerenderFn = ({ current: store }) => { if (store && store.pageNumber > 0) { clearTimeout(rerenderTimeoutRef.current); rerenderTimeoutRef.current = setTimeout(() => setContent(store.pageNumber, store.content), 1); } }; props.rerender.current = rerenderFn; } }, [props.rerender, setContent]); (0, _useIsomorphicLayoutEffect.useIsomorphicLayoutEffect)(() => { const { setContentHandler, resetContentHandler, resetPaginationHandler, endInfinityHandler: endInfinityHandlerProp } = props; if (typeof setContentHandler === 'function') { setContentHandler(setContent); } if (typeof resetContentHandler === 'function') { resetContentHandler(resetContent); } if (typeof resetPaginationHandler === 'function') { resetPaginationHandler(resetInfinity); } if (typeof endInfinityHandlerProp === 'function') { endInfinityHandlerProp(endInfinityHandler); } if (props.store && props.store.current) { const store = props.store.current; setContent(store.pageNumber, store.content); } isMountedRef.current = true; updatePageContent(startupPageRef.current || currentPageInternalRef.current); return () => { clearTimeout(rerenderTimeoutRef.current); clearTimeout(resetContentTimeoutRef.current); clearTimeout(resetInfinityTimeoutRef.current); clearTimeout(callOnPageUpdateTimeoutRef.current); isMountedRef.current = false; }; }, []); (0, _useIsomorphicLayoutEffect.useIsomorphicLayoutEffect)(() => { const prevCurrentPage = prevPropsRef.current.currentPage; const prevInternalContent = prevPropsRef.current.internalContent; if (props.currentPage !== prevCurrentPage) { const newCurrentPage = parseFloat(props.currentPage); setCurrentPageInternal(newCurrentPage); updatePageContent(newCurrentPage); } else if (props.internalContent !== prevInternalContent) { updatePageContent(); } prevPropsRef.current = { currentPage: props.currentPage, internalContent: props.internalContent }; }); (0, _react.useEffect)(() => { if (props.useMarkerOnly) { clearTimeout(callOnPageUpdateTimeoutRef.current); callOnPageUpdateTimeoutRef.current = setTimeout(callOnPageUpdate, 1); } }); const contextValue = (0, _react.useMemo)(() => ({ ...sharedContext, pagination: { updatePageContent, setContent, resetContent, resetInfinity, endInfinity: endInfinityHandler, setItems, prefillItems, setState: setStateHandler, onPageUpdate, ...props, ...derived, items, isLoading, hasEndedInfinity, currentPageInternal, startupPage, lowerPage, upperPage } }), [sharedContext, updatePageContent, setContent, resetContent, resetInfinity, endInfinityHandler, setItems, prefillItems, setStateHandler, onPageUpdate, props, derived, items, isLoading, hasEndedInfinity, currentPageInternal, startupPage, lowerPage, upperPage]); return (0, _jsxRuntime.jsx)(_PaginationContext.default, { value: contextValue, children: props.children }); }; const MemoizedPaginationProvider = _react.default.memo(PaginationProvider); var _default = exports.default = MemoizedPaginationProvider; //# sourceMappingURL=PaginationProvider.js.map