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 from showingFrom/showingTo/totalItems) alongside the nav, justified between on sm+ 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, PagingPresetComponent keeps the inherited cssClass with its class alias. PagingComponent instantiates the injected component with ViewContainerRef.createComponent and forwards inputs via setInput('class', …) (the public alias) — not NgComponentOutlet — so dropping the alias would break the forwarded class binding. Bind class on either <smart-paging> or <smart-paging-preset>.

PagingComponent forwards the variant input (via setInput('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 a data-variant attribute 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

InputTypeDefaultDescription
currentPageInputSignal<number>1Current active page
totalPagesInputSignal<number>1Total number of pages
pageSizeInputSignal<number>10Items per page
totalItemsInputSignal<number>0Total number of items
variantInputSignal<PagingVariant>'card-footer'Layout variant, styled by the preset; the standard exposes it as data-variant
classInputSignal<string>''External CSS classes (alias for cssClass)

Outputs

OutputTypeDescription
pageChangeOutputEmitter<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">&hellip;</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.