Paging
The <smart-paging> component provides a flexible pagination wrapper with an InjectionToken-based extension mechanism. It renders a default PagingStandardComponent which can be replaced via PAGING_STANDARD_COMPONENT_TOKEN.
Usage
<smart-paging
[currentPage]="currentPage()"
[totalPages]="totalPages"
[pageSize]="pageSize"
[totalItems]="totalItems"
(pageChange)="onPageChange($event)"
/>
Components
PagingComponent (<smart-paging>)
Main wrapper component. Renders PagingStandardComponent by default. When PAGING_STANDARD_COMPONENT_TOKEN is provided, renders the injected component via NgComponentOutlet.
PagingStandardComponent (<smart-paging-standard>)
Default concrete implementation. Simple Tailwind-styled pagination placeholder with prev/next buttons, numeric page buttons (with ellipsis handling) and aria-current for the active page. Supports dark mode and disabled states.
PagingPresetComponent (<smart-paging-preset>)
Styled variation that extends PagingBaseComponent and is a drop-in replacement for PagingStandardComponent. Register it via PAGING_STANDARD_COMPONENT_TOKEN to restyle every <smart-paging>, or use the <smart-paging-preset> selector directly. Translates the Preline pagination examples into smart:-prefixed vanilla Tailwind classes with explicit dark: variants. It drives page state purely through the inherited signals/methods (pages, canGoBack, canGoForward, goToPage, nextPage, previousPage) — no Preline JS runtime is required. The variant input selects the layout:
card-footer— a "Showing X to Y of Z results" summary (built fromshowingFrom/showingTo/totalItems) alongside the nav, justified between onsm+ screens;centered— the nav centered horizontally;simple— the bare nav.
The per-variant class recipes live in preset/preset-classes.util.ts (getPagingContainerClasses, getPagingNavClasses, getPagingPageClasses, plus the PAGING_* const class strings); they are kept out of the public barrel and prefixed with the component name.
Unlike most preset components,
PagingPresetComponentkeeps the inheritedcssClasswith itsclassalias.PagingComponentinstantiates the injected component withViewContainerRef.createComponentand forwards inputs viasetInput('class', …)(the public alias) — notNgComponentOutlet— so dropping the alias would break the forwarded class binding. Bindclasson either<smart-paging>or<smart-paging-preset>.
PagingComponentforwards thevariantinput (viasetInput('variant', …), including later changes), so<smart-paging variant="centered">selects the preset layout when the preset is registered. The standard component ignores it visually and only exposes it as adata-variantattribute on its<nav>.
PagingBaseComponent (abstract)
Abstract base directive for extending custom paging implementations. Provides signal-based state (currentPage, totalPages, pageSize, totalItems, variant, cssClass), computed helpers (showingFrom, showingTo, canGoBack, canGoForward, pages) and navigation methods (goToPage, nextPage, previousPage).
API
Inputs
| Input | Type | Default | Description |
|---|---|---|---|
currentPage | InputSignal<number> | 1 | Current active page |
totalPages | InputSignal<number> | 1 | Total number of pages |
pageSize | InputSignal<number> | 10 | Items per page |
totalItems | InputSignal<number> | 0 | Total number of items |
variant | InputSignal<PagingVariant> | 'card-footer' | Layout variant, styled by the preset; the standard exposes it as data-variant |
class | InputSignal<string> | '' | External CSS classes (alias for cssClass) |
Outputs
| Output | Type | Description |
|---|---|---|
pageChange | OutputEmitter<number> | Emits the requested page number |
PAGING_STANDARD_COMPONENT_TOKEN
InjectionToken that allows replacing the default PagingStandardComponent with a custom implementation. Provide a Type<PagingBaseComponent> to override.
Extending the base class
import {
ChangeDetectionStrategy,
Component,
signal,
ViewEncapsulation,
} from '@angular/core';
import {
PAGING_STANDARD_COMPONENT_TOKEN,
PagingBaseComponent,
PagingComponent,
} from '@smartsoft001/angular';
@Component({
selector: 'docs-custom-paging',
template: `
<nav class="docs-paging" [class]="cssClass()" aria-label="Pagination">
<p class="docs-paging__summary">
Showing {{ showingFrom() }} to {{ showingTo() }} of
{{ totalItems() }} results
</p>
<div class="docs-paging__pages">
<button
type="button"
class="docs-paging__previous"
[disabled]="!canGoBack()"
(click)="previousPage()"
>
Previous
</button>
@for (page of pages(); track $index) {
@if (page === '...') {
<span class="docs-paging__gap" aria-hidden="true">…</span>
} @else {
<button
type="button"
class="docs-paging__page"
[attr.aria-current]="page === currentPage() ? 'page' : null"
(click)="goToPage(+page)"
>
{{ page }}
</button>
}
}
<button
type="button"
class="docs-paging__next"
[disabled]="!canGoForward()"
(click)="nextPage()"
>
Next
</button>
</div>
</nav>
`,
encapsulation: ViewEncapsulation.None,
changeDetection: ChangeDetectionStrategy.OnPush,
})
// smart-paging builds the custom component with createComponent() and calls
// setInput('class', ...), which resolves the alias, so the inherited cssClass
// input is used as is - do not redeclare it here.
export class CustomPagingComponent extends PagingBaseComponent {}
@Component({
selector: 'docs-paging-custom-example',
changeDetection: ChangeDetectionStrategy.OnPush,
imports: [PagingComponent],
// The token swaps the standard paging for the custom one everywhere below
// this component, so consumers keep writing `<smart-paging>`.
providers: [
{
provide: PAGING_STANDARD_COMPONENT_TOKEN,
useValue: CustomPagingComponent,
},
],
template: `
<smart-paging
[currentPage]="currentPage()"
[totalPages]="5"
[pageSize]="10"
[totalItems]="48"
(pageChange)="currentPage.set($event)"
/>
`,
})
export class PagingCustomExampleComponent {
readonly currentPage = signal(1);
}
Source
The component lives in packages/shared/angular/src/lib/components/paging and is documented for Claude Code by the angular-components-paging skill.