react-cursor-pagination
Version:
A simple React cursor-based pagination library
69 lines (68 loc) • 2.33 kB
JavaScript
import { atom, useAtom } from "jotai";
import { atomWithStorage } from "jotai/utils";
import { cursorsAtomsMap } from "./atoms.js";
import { DEFAULT_PAGINATION_KEY } from "./config.js";
export function useCursorPagination(paginationKey = DEFAULT_PAGINATION_KEY, options) {
const mapKey = `cursor-${paginationKey}`;
if (!cursorsAtomsMap.has(mapKey)) {
const newAtom = (options === null || options === void 0 ? void 0 : options.persist) === 'session'
? createSessionAtom({ mapKey, options })
: atom([]);
cursorsAtomsMap.set(mapKey, newAtom);
}
const cursorsAtom = cursorsAtomsMap.get(mapKey);
const [cursors, setCursors] = useAtom(cursorsAtom);
const addNextCursor = (cursor) => {
if (!cursor)
return;
setCursors([...cursors, cursor]);
};
const removeLastCursor = () => {
setCursors(cursors.slice(0, -1));
};
const removeAllCursors = () => {
setCursors([]);
};
const currentCursor = cursors[cursors.length - 1];
return {
cursors,
currentCursor,
currentPage: cursors.length + 1,
addNextCursor,
removeLastCursor,
removeAllCursors,
paginationKey,
};
}
function createSessionAtom(params) {
const { mapKey, options } = params;
const { storage } = options || {};
const { serialize = JSON.stringify, deserialize = JSON.parse } = storage || {};
return atomWithStorage(mapKey, [], {
getItem: (key) => {
const storedStr = sessionStorage.getItem(key);
try {
return storedStr
? JSON.parse(storedStr).map(s => deserialize(s))
: [];
}
catch (err) {
console.warn('Failed to parse values.');
return [];
}
},
setItem: (key, values) => {
try {
const saveStr = JSON.stringify(values.map(v => serialize(v)));
sessionStorage.setItem(key, saveStr);
}
catch (err) {
console.warn('Failed to set values.');
sessionStorage.setItem(key, JSON.stringify([]));
}
},
removeItem: (key) => {
sessionStorage.removeItem(key);
}
});
}