import React, {useCallback, useState} from "react"; import {Pagination} from "./Pagination"; import {SpinningLoader} from "../Loaders/SpinningLoader"; import {Await, useAsync} from "../../Async"; /** * Paginated content component with custom page handling. */ export function Paginate({ page, onChange, count, children }: React.PropsWithChildren<{ /** * The current page. */ page: number; /** * Called when a new page is selected. * @param newPage The newly selected page. */ onChange: (newPage: number) => void; /** * Pages count. */ count: number; }>) { return ( <> {children} ); } /** * Paginated content component. */ export function AutoPaginate({ count, children }: { /** * Pages count. */ count: number; /** * Show the given page. * @param page The page to show. */ children: (page: number) => React.ReactElement; }) { // The current page. const [page, setPage] = useState(1); return ( {children(page)} ); } /** * Asynchronous paginated content component. */ export function AsyncPaginate({ count, getData, children }: { /** * Get pages count. */ count: () => Promise; /** * Get data for the given page. * @param page The page for which to get data. */ getData: (page: number) => Promise; /** * Show the current page with its retrieved data. * @param data Data of the page to show. * @param page The page to show. */ children: (data: T, page: number) => React.ReactElement; }) { // Getting pages count. const [asyncCount] = useAsync(count, []); return ( }> { (count) => ( {(page) => } ) } ); } /** * An async page to render. */ export function AsyncPage({page, getData, render}: { /** * The page number to show. */ page: number; /** * Get data for the given page. * @param page The page for which to get data. */ getData: (page: number) => Promise; /** * Render the page with its retrieved data. * @param data Data of the page to show. * @param page The page to show. */ render: (data: T, page: number) => React.ReactElement; }) { // Store function to get page data. const getPageData = useCallback(() => { return getData(page); }, [page]); // Getting page data. const [asyncPageData] = useAsync(getPageData, [getPageData]); return ( }> {(pageData) => render(pageData, page)} ); }