@dnb/eufemia
Version:
DNB Eufemia Design System UI Library
433 lines (432 loc) • 17 kB
JavaScript
;
"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