Pagination
Pagination with page navigation, next and previous links.
import { Component } from '@angular/core';
import {
HlmPagination,
HlmPaginationContent,
HlmPaginationEllipsis,
HlmPaginationItem,
HlmPaginationLink,
HlmPaginationNext,
HlmPaginationPrevious,
} from '@spartan-ng/helm/pagination';
@Component({
selector: 'spartan-pagination-preview',
imports: [
HlmPagination,
HlmPaginationContent,
HlmPaginationItem,
HlmPaginationPrevious,
HlmPaginationNext,
HlmPaginationLink,
HlmPaginationEllipsis,
],
template: `
<nav hlmPagination>
<ul hlmPaginationContent>
<li hlmPaginationItem>
<hlm-pagination-previous link="/components/menubar" />
</li>
<li hlmPaginationItem>
<a hlmPaginationLink link="#">1</a>
</li>
<li hlmPaginationItem>
<a hlmPaginationLink link="#" isActive>2</a>
</li>
<li hlmPaginationItem>
<a hlmPaginationLink link="#">3</a>
</li>
<li hlmPaginationItem>
<hlm-pagination-ellipsis />
</li>
<li hlmPaginationItem>
<hlm-pagination-next link="/components/popover" />
</li>
</ul>
</nav>
`,
})
export class PaginationPreview {}
Installation
npx nx g @spartan-ng/cli:ui pagination
ng g @spartan-ng/cli:ui pagination
Usage
import {
HlmPaginationContent
HlmPagination
HlmPaginationEllipsis
HlmPaginationItem
HlmPaginationLink
HlmPaginationNext
HlmPaginationPrevious
} from '@spartan-ng/helm/pagination';
<nav hlmPagination>
<ul hlmPaginationContent>
<li hlmPaginationItem>
<hlm-pagination-previous link="/components/menubar" />
</li>
<li hlmPaginationItem>
<a hlmPaginationLink link="#">1</a>
</li>
<li hlmPaginationItem>
<a hlmPaginationLink link="#" isActive>2</a>
</li>
<li hlmPaginationItem>
<a hlmPaginationLink link="#">3</a>
</li>
<li hlmPaginationItem>
<hlm-pagination-ellipsis />
</li>
<li hlmPaginationItem>
<hlm-pagination-next link="/components/popover" />
</li>
</ul>
</nav>
Helm API
HlmNumberedPaginationQueryParams
Selector: hlm-numbered-pagination-query-params
Inputs
Prop | Type | Default | Description |
---|---|---|---|
totalItems* (required) | number | - | The total number of items in the collection. Only useful when doing server-side paging, where the collection size is limited to a single page returned by the server API. |
link | string | . | The URL path to use for the pagination links. Defaults to '.' (current path). |
maxSize | number | 7 | The number of page links to show. |
showEdges | boolean | true | Show the first and last page buttons. |
pageSizes | number[] | [10, 20, 50, 100] | The page sizes to show. Defaults to [10, 20, 50, 100] |
HlmNumberedPagination
Selector: hlm-numbered-pagination
Inputs
Prop | Type | Default | Description |
---|---|---|---|
totalItems* (required) | number | - | The total number of items in the collection. Only useful when doing server-side paging, where the collection size is limited to a single page returned by the server API. |
maxSize | number | 7 | The number of page links to show. |
showEdges | boolean | true | Show the first and last page buttons. |
pageSizes | number[] | [10, 20, 50, 100] | The page sizes to show. Defaults to [10, 20, 50, 100] |
HlmPaginationContent
Selector: [hlmPaginationContent]
Inputs
Prop | Type | Default | Description |
---|---|---|---|
class | ClassValue | - | - |
HlmPaginationEllipsis
Selector: hlm-pagination-ellipsis
Inputs
Prop | Type | Default | Description |
---|---|---|---|
class | ClassValue | - | - |
srOnlyText | string | More pages | Screen reader only text for the ellipsis |
HlmPaginationItem
Selector: [hlmPaginationItem]
Inputs
Prop | Type | Default | Description |
---|---|---|---|
class | ClassValue | - | - |
HlmPaginationLink
Selector: [hlmPaginationLink]
Inputs
Prop | Type | Default | Description |
---|---|---|---|
class | ClassValue | - | - |
isActive | boolean | false | Whether the link is active (i.e., the current page). |
size | ButtonVariants['size'] | icon | The size of the button. |
link | RouterLink['routerLink'] | - | The link to navigate to the page. |
HlmPaginationNext
Selector: hlm-pagination-next
Inputs
Prop | Type | Default | Description |
---|---|---|---|
class | ClassValue | - | - |
link | RouterLink['routerLink'] | - | The link to navigate to the next page. |
queryParams | RouterLink['queryParams'] | - | The query parameters to pass to the next page. |
queryParamsHandling | RouterLink['queryParamsHandling'] | - | How to handle query parameters when navigating to the next page. |
aria-label | string | Go to next page | The aria-label for the next page link. |
text | string | Next | The text to display for the next page link. |
iconOnly | boolean | false | Whether the button should only display the icon. |
HlmPaginationPrevious
Selector: hlm-pagination-previous
Inputs
Prop | Type | Default | Description |
---|---|---|---|
class | ClassValue | - | - |
link | RouterLink['routerLink'] | - | The link to navigate to the previous page. |
queryParams | RouterLink['queryParams'] | - | The query parameters to pass to the previous page. |
queryParamsHandling | RouterLink['queryParamsHandling'] | - | How to handle query parameters when navigating to the previous page. |
aria-label | string | Go to previous page | The aria-label for the previous page link. |
text | string | Previous | The text to display for the previous page link. |
iconOnly | boolean | false | Whether the button should only display the icon. |
HlmPagination
Selector: [hlmPagination]
Inputs
Prop | Type | Default | Description |
---|---|---|---|
class | ClassValue | - | - |
aria-label | string | pagination | The aria-label for the pagination component. |
Examples
Query Params
import { Component, computed, inject, numberAttribute } from '@angular/core';
import { toSignal } from '@angular/core/rxjs-interop';
import { ActivatedRoute } from '@angular/router';
import {
HlmPagination,
HlmPaginationContent,
HlmPaginationItem,
HlmPaginationLink,
HlmPaginationNext,
HlmPaginationPrevious,
} from '@spartan-ng/helm/pagination';
import { map } from 'rxjs/operators';
@Component({
selector: 'spartan-pagination-query-params',
imports: [
HlmPagination,
HlmPaginationContent,
HlmPaginationItem,
HlmPaginationPrevious,
HlmPaginationNext,
HlmPaginationLink,
],
template: `
<nav hlmPagination>
<ul hlmPaginationContent>
@if (currentPage() > 1) {
<li hlmPaginationItem>
<hlm-pagination-previous link="." [queryParams]="{ page: currentPage() - 1 }" queryParamsHandling="merge" />
</li>
}
@for (page of pages; track 'page_' + page) {
<li hlmPaginationItem>
<a
hlmPaginationLink
[link]="currentPage() !== page ? '.' : undefined"
[queryParams]="{ page }"
queryParamsHandling="merge"
[isActive]="currentPage() === page"
>
{{ page }}
</a>
</li>
}
@if (currentPage() < pages[pages.length - 1]) {
<li hlmPaginationItem>
<hlm-pagination-next link="." [queryParams]="{ page: currentPage() + 1 }" queryParamsHandling="merge" />
</li>
}
</ul>
</nav>
`,
})
export class PaginationQueryParams {
private readonly _route = inject(ActivatedRoute);
/**
* Alternative would be to enable `withComponentInputBinding` in `provideRouter`.
* Than you can bind `input` signal to the query param.
*
* ```ts
* pageQuery = input<number, NumberInput>(1, {
* alias: 'page',
* transform: (value) => numberAttribute(value, 1),
* });
* ```
*
* This can replace `_pageQuery` and `currentPage` computed property.
*/
private readonly _pageQuery = toSignal(
this._route.queryParamMap.pipe(
map((params) => {
const pageQuery = params.get('page');
return pageQuery ? numberAttribute(pageQuery, 1) : undefined;
}),
),
);
public currentPage = computed(() => this._pageQuery() ?? 1);
public pages = [1, 2, 3, 4];
}
Icon Only (Previous/Next)
import { Component } from '@angular/core';
import {
HlmPagination,
HlmPaginationContent,
HlmPaginationEllipsis,
HlmPaginationItem,
HlmPaginationLink,
HlmPaginationNext,
HlmPaginationPrevious,
} from '@spartan-ng/helm/pagination';
@Component({
selector: 'spartan-pagination-icon-only',
imports: [
HlmPagination,
HlmPaginationContent,
HlmPaginationItem,
HlmPaginationPrevious,
HlmPaginationNext,
HlmPaginationLink,
HlmPaginationEllipsis,
],
template: `
<nav hlmPagination>
<ul hlmPaginationContent>
<li hlmPaginationItem>
<hlm-pagination-previous iconOnly="true" link="/components/menubar" />
</li>
<li hlmPaginationItem>
<a hlmPaginationLink link="#">1</a>
</li>
<li hlmPaginationItem>
<a hlmPaginationLink link="#" isActive>2</a>
</li>
<li hlmPaginationItem>
<a hlmPaginationLink link="#">3</a>
</li>
<li hlmPaginationItem>
<hlm-pagination-ellipsis />
</li>
<li hlmPaginationItem>
<hlm-pagination-next iconOnly="true" link="/components/popover" />
</li>
</ul>
</nav>
`,
})
export class PaginationIconOnly {}
Advanced Pagination
100 total items | 7 pages
import { Component, signal } from '@angular/core';
import { HlmNumberedPagination } from '@spartan-ng/helm/pagination';
@Component({
selector: 'spartan-pagination-advanced',
imports: [HlmNumberedPagination],
template: `
<hlm-numbered-pagination [(currentPage)]="page" [(itemsPerPage)]="pageSize" [totalItems]="totalProducts()" />
`,
})
export class PaginationAdvanced {
public page = signal(1);
public pageSize = signal(10);
public totalProducts = signal(100);
}
Advanced Pagination - Query Params
Use hlm-numbered-pagination-query-params
instead of hlm-numbered-pagination
to synchronize pagination state with query params.
100 total items | 7 pages
import { Component, computed, inject, numberAttribute, signal } from '@angular/core';
import { toSignal } from '@angular/core/rxjs-interop';
import { ActivatedRoute } from '@angular/router';
import { HlmNumberedPaginationQueryParams } from '@spartan-ng/helm/pagination';
import { map } from 'rxjs/operators';
@Component({
selector: 'spartan-pagination-advanced-query-params',
imports: [HlmNumberedPaginationQueryParams],
template: `
<hlm-numbered-pagination-query-params
[currentPage]="page()"
[(itemsPerPage)]="pageSize"
[totalItems]="totalProducts()"
/>
`,
})
export class PaginationAdvancedQuery {
private readonly _route = inject(ActivatedRoute);
/**
* Alternative would be to enable `withComponentInputBinding` in `provideRouter`.
* Than you can bind `input` signal to the query param.
*
* ```ts
* pageQuery = input<number, NumberInput>(1, {
* alias: 'page',
* transform: (value) => numberAttribute(value, 1),
* });
* ```
*
* This can replace `_pageQuery` and `page` computed property.
*/
private readonly _pageQuery = toSignal(
this._route.queryParamMap.pipe(
map((params) => {
const pageQuery = params.get('page');
return pageQuery ? numberAttribute(pageQuery, 1) : undefined;
}),
),
);
public page = computed(() => this._pageQuery() ?? 1);
public pageSize = signal(10);
public totalProducts = signal(100);
}