Skip to main content
zerotal

Documentation


Documentation / @zerotal/flow / index / Pagination

Function: Pagination()

Pagination<TBase>(Base): {(...args): Paginated; prototype: Paginated<any>; } & TBase

Defined in: flow/src/pagination.ts:219

Component mixin that adds URL-synced pagination state and navigation actions — flow's equivalent of Livewire's WithPagination trait.

Type Parameters

TBase

TBase extends AbstractComponentCtor

The (abstract) Component constructor being extended.

Parameters

Base

TBase

The component class to mix into.

Returns

{(...args): Paginated; prototype: Paginated<any>; } & TBase

A subclass of Base with pagination state and navigation.

Remarks

Composing this onto a component adds:

  • a page field, @exposed and @url-synced to the ?page= query string;
  • a paginators map holding the page of each NAMED paginator (snapshot-only), so a single component can drive several independent pagers by passing a pageName (e.g. nextPage("invoices"), paginate(rows, 10, "invoices"));
  • @exposed navigation actions callable straight from the browser: Paginated.gotoPage | gotoPage, resetPage, nextPage, previousPage;
  • a paginate(items, perPage, pageName?) helper that slices an in-memory array at the current page.

All page writes clamp to >= 1. Optional lifecycle hooks fire around a page change if you define them: updatingPage/updatedPage (default paginator) and the generic updatingPaginators/updatedPaginators. Call resetPage() when a filter or search term changes so the user isn't stranded on an empty page.

Example

class PostsPage extends ComponentWith(Pagination) {
  @locked posts: Post[] = [];
  async onMount() { this.posts = await Post.all(); }
  async render() {
    const posts = await Post.paginate(10); // uses this.page
    return (
      <div>
        {p.data.map((post) => <PostCard post={post} />)}
        <button onClick={this.previousPage} disabled={p.onFirstPage}>Prev</button>
        <button onClick={this.nextPage} disabled={!p.hasMorePages}>Next</button>
      </div>
    );
  }
}