0.0.7 • Published 12 months ago

mth-pagination v0.0.7

Weekly downloads
-
License
ISC
Repository
-
Last release
12 months ago

MTH Pagination

Overview

mth-pagination is a class written in TypeScript that provides functionality for managing pagination in your applications. The mth-pagination class generates a range of page numbers and provides methods to navigate between pages.

Features

  • Provides a range of page numbers for pagination
  • Allows customizing the number of page boundaries and sibling pages
  • Handles page changes, with a callback function to manage what happens on each page change
  • Includes methods for setting the current page and navigating to the next, previous, first, and last page

Install

Using npm, yarn, or pnpm

npm install mth-pagination
yarn add mth-pagination
pnpm add mth-pagination

Using CDN

<html>
	<head>
		<script src="https://unpkg.com/mth-pagination"></script>
		<script>
		  const pagination = new mthPagination.default({
			total: 1000,
			page: 1,
			siblings: 2,
			boundaries: 2,
			onChange(page) {
			  console.log(page);
			},
		  });
    </script>
	</head>
</html>

Importing

esm

	import mthPagination from 'mth-pagination';

cjs

const mthPagination = require('mth-pagination').default;

Usage

import MthPagination, { type PaginationParams } from 'mth-pagination';

const params: PaginationParams = {
  page: 1,
  total: 10,
  siblings: 1,
  boundaries: 1,
  onChange: (page: number) => console.log(`Current page is ${page}`),
};

const pagination = new mthPagination(params);

pagination.range; // -> [1, 2, 3, 4, 5, 'dots', 10];

pagination.setPage(5);
pagination.range; // -> [1, 'dots', 4, 5, 6, 'dots', 10];

pagination.next();
pagination.range; // -> [1, 'dots', 5, 6, 7, 'dots', 10];

pagination.previous();
pagination.range; // -> [1, 'dots', 4, 5, 6, 'dots', 10];

pagination.last();
pagination.range; // -> [1, 'dots', 6, 7, 8, 9, 10];

pagination.first();
pagination.range; // -> [1, 2, 3, 4, 5, 'dots', 10];

Siblings

	const pagination = mthPagination({ total: 20, siblings: 3 });

Boundaries

	const pagination = mthPagination({ total: 20, boundaries: 3 });

Definition

export const DOTS = 'dots';

function range(start: number, end: number) {
  const length = end - start + 1;
  return Array.from({ length }, (_, index) => index + start);
}

export interface PaginationParams {
  /**  Active page number */
  page?: number;

  /** Total amount of pages */
  total: number;

  /** Siblings amount on left/right side of selected page, defaults to 1 */
  siblings?: number;

  /** Amount of elements visible on left/right edges, defaults to 1  */
  boundaries?: number;

  /** Callback fired after change of each page */
  onChange?: (page: number) => void;
}

class MthPagination {
  total: number;
  page: number;
  siblings: number;
  boundaries: number;
  private _total: number;
  activePage: number;
  onChange: ((page: number) => void) | undefined;

  constructor({
    boundaries = 1,
    onChange,
    page = 1,
    siblings = 1,
    total,
  }: PaginationParams) {
    this.boundaries = boundaries;
    this.page = page;
    this.siblings = siblings;
    this.total = total;
    this.onChange = onChange;
    this._total = Math.max(Math.trunc(total), 0);
    this.activePage = this.page;
  }

  get range(): (number | typeof DOTS)[] {
    const totalPageNumbers = this.siblings * 2 + 3 + this.boundaries * 2;
    if (totalPageNumbers >= this._total) {
      return range(1, this._total);
    }
    const leftSiblingIndex = Math.max(
      this.activePage - this.siblings,
      this.boundaries
    );

    const rightSiblingIndex = Math.min(
      this.activePage + this.siblings,
      this._total - this.boundaries
    );

    const shouldShowLeftDots = leftSiblingIndex > this.boundaries + 2;
    const shouldShowRightDots =
      rightSiblingIndex < this._total - (this.boundaries + 1);

    if (!shouldShowLeftDots && shouldShowRightDots) {
      const leftItemCount = this.siblings * 2 + this.boundaries + 2;
      return [
        ...range(1, leftItemCount),
        DOTS,
        ...range(this._total - (this.boundaries - 1), this._total),
      ];
    }

    if (shouldShowLeftDots && !shouldShowRightDots) {
      const rightItemCount = this.boundaries + 1 + 2 * this.siblings;
      return [
        ...range(1, this.boundaries),
        DOTS,
        ...range(this._total - rightItemCount, this._total),
      ];
    }

    return [
      ...range(1, this.boundaries),
      DOTS,
      ...range(leftSiblingIndex, rightSiblingIndex),
      DOTS,
      ...range(this._total - this.boundaries + 1, this._total),
    ];
  }

  private _setActivePage(page: number) {
    this.activePage = page;
    if (this.onChange) {
      this.onChange(page);
    }
  }

  setPage(page: number) {
    if (page < 0) {
      this._setActivePage(1);
      return;
    }
    if (page > this._total) {
      this._setActivePage(this._total);
      return;
    }
    this._setActivePage(page);
  }

  next() {
    this.setPage(this.activePage + 1);
  }

  prev() {
    this.setPage(this.activePage - 1);
  }

  first() {
    this.setPage(1);
  }

  last() {
    this.setPage(this._total);
  }
}

export default MthPagination;

Example

Example

License

This project is licensed under the MIT License.

0.0.7

12 months ago

0.0.6

12 months ago

0.0.5

12 months ago

0.0.4

12 months ago

0.0.3

12 months ago

0.0.2

12 months ago

0.0.1

12 months ago