Skip to content
Twilight React Playground
ثيم رائدaren

PaginatedResult, Pagination

interfaceAdvanced

The shared pagination shapes: the API's cursor block, and the { items, next } result that list functions return.

import { PaginatedResult, Pagination } from '@salla.sa/twilight-theme-engine/api/types';

In plain words

Long lists arrive a page at a time. PaginatedResult<T> is what the engine's list functions give you: items for this page and next, which is null on the last page. Pagination is the raw cursor block some API answers carry.

These are types: they describe data for your editor and disappear from the built theme.

Signature

interface PaginatedResult<T> {
  items: T[];
  next: string | null;       // null on the last page
}

interface Pagination {
  current: number;
  next?: string | null;
  previous?: string | null;
}

Example

app/lib/firstOfferPages.ts
import type { PaginatedResult } from '@salla.sa/twilight-theme-engine/api/types';
import { product } from '@salla.sa/twilight-theme-engine/api/product';
import type { Product } from '@salla.sa/twilight-theme-engine/types';

/** `next` arrives as a whole URL: the next request wants only its cursor parameter. */
function cursorOf(next: string): string | null {
  try {
    return new URL(next).searchParams.get('cursor');
  } catch {
    return next;
  }
}

export async function firstOfferPages(pages = 3): Promise<Product[]> {
  const items: Product[] = [];
  let cursor: string | null = null;
  for (let i = 0; i < pages; i++) {
    const page: PaginatedResult<Product> = await product.list({ source: 'offers', cursor });
    items.push(...page.items);
    if (!page.next) break;
    cursor = cursorOf(page.next);
  }
  return items;
}

How it behaves

  • product.list and wishlist.list return PaginatedResult<Product> (plus filters for products), the shape ItemsList from @salla.sa/twilight-components-react expects from its loader.

  • order.list keeps the raw shape, { data, cursor?: Pagination }; notification.list has its own cursor with a numeric next and a count.

  • The module holds types only: import it with import type, and it adds nothing to the bundle.

Gotchas

  • The JSDoc calls cursors opaque tokens. The products API sends next as a whole URL; send back only its cursor parameter (see product.list).

  • The JSDoc example reads page1.cursor?.current from product.list. That result has no cursor (it has items and next), so the line does not compile.

  • src/api/README.md says every paginated endpoint uses cursors. The wishlist pages by number, and notifications use numeric cursors.

Related

Source and docs