Skip to content

Instantly share code, notes, and snippets.

@hinsxd
Last active September 6, 2023 14:51
Show Gist options
  • Save hinsxd/550f9679537cf539a602de193958e1b3 to your computer and use it in GitHub Desktop.
Save hinsxd/550f9679537cf539a602de193958e1b3 to your computer and use it in GitHub Desktop.
Pagination hook
import { useMemo } from "react";
type PaginationProps = {
onPageChange: (page: number) => void;
totalCount: number;
siblingCount?: number;
currentPage: number;
pageSize: number;
};
type ItemInfo = {
value: number | string;
active?: boolean;
disabled?: boolean;
action?: () => void;
};
export const usePagination = (props: PaginationProps) => {
const {
onPageChange,
totalCount,
siblingCount = 1,
currentPage,
pageSize,
} = props;
const maxPage = Math.max(1, Math.ceil(totalCount / pageSize));
const items = useMemo(() => {
const _items: ItemInfo[] = [{ value: currentPage, active: true }];
for (let i = 1; i <= siblingCount; i++) {
if (currentPage - i >= 1) {
_items.unshift({
value: currentPage - i,
action: () => onPageChange(currentPage - i),
});
}
if (currentPage + i <= maxPage) {
_items.push({
value: currentPage + i,
action: () => onPageChange(currentPage + i),
});
}
}
if (_items[0].value > 2) {
_items.unshift({ value: "...", disabled: true });
}
if (_items[0].value > 1) {
_items.unshift({ value: 1, action: () => onPageChange(1) });
}
if (_items[_items.length - 1].value < maxPage - 1) {
_items.push({ value: "...", disabled: true });
}
if (_items[_items.length - 1].value < maxPage) {
_items.push({ value: maxPage, action: () => onPageChange(maxPage) });
}
return _items;
}, [currentPage, maxPage, onPageChange, siblingCount]);
return {
items,
// any helper functions you want
}
};
@hinsxd
Copy link
Author

hinsxd commented Feb 11, 2022

Usage

     <Button
        disabled={!canPrevPage}
        onClick={() => onPageChange(1)}
      />
      <Button
        disabled={!canPrevPage}
        onClick={() => onPageChange(currentPage - 1)}
      />

      {items.map((item, i) => (
        <Button
          key={i}
          disabled={item.disabled}
          onClick={item.action}
        >
          {item.value}
        </Button>
      ))}

      <Button
        disabled={!canNextPage}
        onClick={() => onPageChange(currentPage + 1)}
      />
      <Button
        disabled={!canNextPage}
        onClick={() => onPageChange(maxPage)}
      />

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment