Pagination
The Pagination
component is typically used to paginate large sets of data divided into smaller parts called pages.
Examples
Pagination
Usage
React
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
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
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 (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.