PaginationItem.tsx 2.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798
  1. import clsx from "clsx";
  2. import { UsePaginationItem } from "libs/hooks/usePagination";
  3. import { ElementType, forwardRef, ReactNode } from "react";
  4. import styles from "./index.module.scss";
  5. export interface PaginationItemProps extends Docs {
  6. className?: string;
  7. component?: ElementType;
  8. /**
  9. * The components used for first, last, next & previous item type
  10. * @default {
  11. * first: FirstPageIcon,
  12. * last: LastPageIcon,
  13. * next: NavigateNextIcon,
  14. * previous: NavigateBeforeIcon,
  15. * }
  16. */
  17. components?: {
  18. first?: string;
  19. last?: string;
  20. next?: string;
  21. previous?: string;
  22. };
  23. /**
  24. * If `true`, the component is disabled.
  25. * @default false
  26. */
  27. disabled?: boolean;
  28. /**
  29. * The current page number.
  30. */
  31. page?: ReactNode;
  32. /**
  33. * If `true` the pagination item is selected.
  34. * @default false
  35. */
  36. selected?: boolean;
  37. /**
  38. * The type of pagination item.
  39. * @default 'page'
  40. */
  41. type?: UsePaginationItem["type"];
  42. }
  43. const PaginationItem = forwardRef<HTMLDivElement, PaginationItemProps>(
  44. function PaginationItem(props, ref) {
  45. const {
  46. className,
  47. component: PaginationItemPage = "button",
  48. components = {
  49. previous: "navigate-prev",
  50. next: "navigate-next",
  51. first: "first-page",
  52. last: "last-page",
  53. },
  54. disabled = false,
  55. page,
  56. selected = false,
  57. type = "page",
  58. ...other
  59. } = props;
  60. const normalizedIcons = {
  61. previous: components.previous || "navigate-prev",
  62. next: components.next || "navigate-next",
  63. first: components.first || "first-page",
  64. last: components.last || "last-page",
  65. };
  66. const icon = normalizedIcons[type as keyof typeof normalizedIcons];
  67. return type === "start-ellipsis" || type === "end-ellipsis" ? (
  68. <div ref={ref} className={clsx(styles.text, className)}>
  69. </div>
  70. ) : (
  71. <PaginationItemPage
  72. ref={ref}
  73. disabled={disabled}
  74. className={clsx(styles.item, className, {
  75. [styles.selected]: selected,
  76. [styles.disabled]: disabled,
  77. })}
  78. {...other}
  79. >
  80. {type === "page" && page}
  81. {icon ? (
  82. <svg className={styles.icon}>
  83. <use xlinkHref={`/icons.svg#${icon}`}></use>
  84. </svg>
  85. ) : null}
  86. </PaginationItemPage>
  87. );
  88. }
  89. );
  90. export default PaginationItem;