Pagination

The Pagination component is typically used to paginate large sets of data divided into smaller parts called pages.

Examples

Pagination

Usage

astro logo

React, Vue, and Svelte examples on a single playground page 🚀 💥

react logoReact

View source
import { useEffect, useState } from 'react';
import 'agnostic-react/dist/common.min.css';
import 'agnostic-react/dist/esm/index.css';
import { Pagination } from 'agnostic-react';
import { usePagination } from 'agnostic-helpers/dist/index.esm';

export const YourComponent = () => {
  const [page, setPage] = useState(1);
  const paging = usePagination({ offset: 2 });
  // usePagination will generate your paging controls
  const pages = paging.generate(page, 20);

  useEffect(() => {
    // 1. `onPageChange` fires when a user clicks on a new page
    // 2. That calls `setPage` which `onPageChange` is pointed to
    // 3. `useEffect` here fires as we have the `page` dependency
    // listed in our dependencies array below
    // 4. We feed the new page into `paging.generate` and rerender
    paging.generate(page, 20);
  }, [page, pages, paging]);

  return (
    <section className="mbe24">
      <Pagination
        onPageChange={setPage}
        current={page}
        pages={pages}
        ariaLabel="Pagination to help navigate table"
      />
    </section>
  );
};

React: component source, storybook tests

Vue 3 logoVue 3

View source
<script setup>
// Components CSS
import "agnostic-vue/dist/index.css";
import { usePagingGenerator, Pagination } from "agnostic-vue";

const { currentPaginationPage, paginationPages, handlePaginationUpdate } =
  usePagingGenerator(1, 1, 20);

const interceptPageUpdate = (newPage) => {
  // Typcically we'd fetch or update the data set here
  console.log("interceptPageUpdate--page: ", newPage);
  // This takes care of updating the paging controls appropriately
  handlePaginationUpdate(newPage);
};
</script>
<template>
  <section>
    <h2>Pagination</h2>
    <Pagination
      @update-page="interceptPageUpdate"
      :current="currentPaginationPage"
      :pages="paginationPages"
    />
  </section>
</template>

Vue 3: component source, storybook tests

Svelte logoSvelte

View source
<script>
  import "agnostic-svelte/css/common.min.css";
  import { usePagination } from "agnostic-helpers/dist/index.esm";
  import { Pagination } from "agnostic-svelte";

  // Offset describes how many siblings besides current (must be 1 | 2)
  // Example of offset of 1: [1][2(current)][3]...[50]
  // Example of offset of 2: [1][2][3(current)][4][5]...[50]
  // Pagination by default uses a generator with an offset of 1
  // but we are including the use of a custom paging generator here as an example
  const paging = usePagination({ offset: 2 });

  let currentPage = 1;

  // Using $: here declares a reactive block, this code will run whenever
  // currentPage is given a new value
  $: console.log(`Current page is: ${currentPage}`);

  const paginationArgs = {
    total: 50,
    pageGenerator: paging,
    navigationLabels: {
      previous: "Previa",
      next: "Siguiente",
      first: "Primera",
      last: "Última",
    },
    ariaLabel: "Pagination",
    justify: "center",
  };
</script>

<!-- Using bind: here we establish a two way connection with the 'current' property -->
<!-- meaning 'currentPage' will be updated whenever 'current' is updated internally -->
<Pagination {...paginationArgs} bind:current="{currentPage}" />

Svelte: component source, storybook tests

Angular logoAngular (Experimental)

View source

In your Angular configuration (likely angular.json) ensure you're including the common AgnosticUI styles:

"styles": ["agnostic-angular/common.min.css"],

Add AgnosticUI's AgModule module:



 





 





import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { AgModule } from 'agnostic-angular';

import { AppComponent } from './app.component';

@NgModule({
  declarations: [AppComponent],
  imports: [BrowserModule, AgModule],
  providers: [],
  bootstrap: [AppComponent],
})
export class AppModule {}

Now you can use in your components:

import { Component, OnInit } from '@angular/core';
import { usePagination } from 'agnostic-helpers/dist/index.esm';
@Component({
  selector: 'your-component',
  template: `<div>
  <ag-pagination (onPageChange)="onPageChange($event)"
                   [current]="page"
                   [navigationLabels]="customNavigationLabels"
                   [pages]="pages"
                   attr.aria-label="pagination">
    ></ag-pagination>
  </div>`
})
export class YourComponent  implements OnInit {
  /**
   * usePagination generates the paging control numbers and
   * "gap" e.g. '...'
   */
  paging = usePagination({ offset: 2 });
  page: number = 1;
  /**
   * Typically you'd derive this by dividing the total number of items
   * in your data set, by the number of items per page you'd like displayed:
   *   totalPage = Math.ceil(this.items.length / this.displayedPerPage);
   */
  totalPages: number = 50;
  pages: any[] = [];
  /**
   * Default looks like:
   * First | Previous | 1 | 2 | 3 ... | 50 | Next | Last
   */
  customLabels = {
    previous: 'Previa',
    next: 'Siguiente',
    first: 'Primera',
    last: 'Última',
  };
  public get customNavigationLabels() {
    return this.customLabels;
  }
  ngOnInit() {
    this.pages = this.paging.generate(this.page, this.totalPages)
  }

  public onPageChange(pageNumber: number) {
    // 1. `onPageChange` fires when a user clicks on a new page
    // 2. We simply feed new page into `paging.generate` below
    this.page = pageNumber;
    this.pages = this.paging.generate(this.page, this.totalPages)
  }
}

Angular: component source, storybook tests

Storybook

You can run the framework Storybooks and see live examples for React, Vue 3, Svelte, Astro, and Angular (experimental). The following will set up Storybook and run locally:

How to run Storybook
git clone git@github.com:AgnosticUI/agnosticui.git
cd agnosticui/<PACKAGE_NAME> && npm i # e.g. cd agnosticui/agnostic-react && npm i
npm run storybook

See Running Storybook.