# Paginator

`class` in `gateway` · v0.6.0

<https://docs.seedcord.org/packages/gateway/0.6.0/classes/paginator>

A restart-proof paginator. Each nav button's customId encodes its full target page, so clicks are idempotent and survive a restart. A persistent `@ButtonRoute` on `Handler` dispatches the clicks.

```ts
class Paginator<Item, Prefix extends string> extends PaginatorBase<
    Item,
    Prefix,
    PageContext
>
```

## Examples

```ts
export const Bans = new Paginator({
    prefix: 'bans',
    source: new ArraySource((ctx) => ctx.guild?.bans.fetch().then((b) => [...b.values()]) ?? [], { perPage: 10 }),
    renderItem: (ban) => ban.user.tag
});

\@ButtonRoute(Bans.cursor)
export class BansNav extends Bans.Handler {}
```

## Constructors

### constructor

```ts
Paginator(config: PaginatorConfig<Item, Prefix, PageContext>)
```

Constructs a new instance of the `Paginator` class

## Properties

### config

```ts
protected readonly config: PaginatorConfig<Item, Prefix, Ctx>
```

### cursor

```ts
readonly cursor: PageCursor<Prefix>
```

The page cursor, pass it to your `@ButtonRoute`.

### Handler

```ts
public readonly Handler: PaginatorHandlerCtor<Prefix>
```

The nav handler base. Extend it with an empty body and decorate it, `@ButtonRoute(p.cursor)`.

## Methods

### buildPage

```ts
protected async buildPage(
    ctx: Ctx,
    n: number
): Promise<ReplyResponse>
```

Build one page as a [`ReplyResponse`](/packages/types/0.13.0/interfaces/reply-response). Each transport wraps this in a `page()` taking its handler.

### page

```ts
public async page(
    handler: RepliableHandler<Repliables>,
    n: number
): Promise<ReplyResponse>
```

Render a page as a [`ReplyResponse`](/packages/types/0.13.0/interfaces/reply-response) without sending anything.

### start

```ts
public async start(
    handler: RepliableHandler<Repliables>,
    n?: number
): Promise<SentMessage>
```

Send a page through the handler's sender. The sender picks reply, edit, or followUp from its ack state.
