Skip to content

Pagination

npmnpm downloadsJSRJSR Score

Fluent API с цепочками вызовов для создания постраничных inline-клавиатур в Telegram ботах. Обрабатывает загрузку данных, генерацию клавиатуры, кнопки навигации, информацию о странице и колбэки выбора элементов.

WARNING

Этот пакет находится в стадии разработки — API может измениться.

Установка

bash
npm install @gramio/pagination
bash
yarn add @gramio/pagination
bash
pnpm add @gramio/pagination
bash
bun install @gramio/pagination

IMPORTANT

Необходимо переопределить версию @gramio/callback-data в package.json:

json
{
    "overrides": {
        "@gramio/callback-data": "^0.0.11"
    }
}

Использование

ts
import { Bot } from "gramio";
import { Pagination } from "@gramio/pagination";
import { paginationFor } from "@gramio/pagination/plugin";

const data = [
    { id: 1, title: "test" },
    { id: 2, title: "test2" },
    { id: 3, title: "test3" },
    { id: 4, title: "test4" },
    { id: 5, title: "test5" },
];

const paginationTest = new Pagination("test", async ({ offset, limit }) => {
    return data.slice(offset, offset + limit);
})
    .count(() => Promise.resolve(data.length))
    .item((x) => ({
        title: x.title,
        id: x.id,
    }))
    .onSelect(({ id, context }) => {
        return context.editText(`Selected ${id}`, {
            reply_markup: context.message?.replyMarkup?.payload,
        });
    })
    .limit(2)
    .columns(2)
    .withFirstLastPage()
    .withPageInfo(
        ({ totalPages, currentPage }) => `${currentPage} / ${totalPages}`
    );

const bot = new Bot(process.env.BOT_TOKEN as string)
    .extend(paginationFor([paginationTest]))
    .command("start", async (ctx) =>
        ctx.reply("Hello", {
            reply_markup: await paginationTest.getKeyboard(0),
        })
    )
    .onStart(console.log);

await bot.start();

API

new Pagination(name, dataFunction)

Создание экземпляра пагинации.

  • name — уникальный идентификатор (используется как префикс callback data)
  • dataFunctionasync ({ offset, limit }) => Data[] — загружает одну страницу элементов

Цепочечные методы

МетодОписание
.limit(count)Элементов на странице (по умолчанию: 10)
.columns(count)Столбцов кнопок в сетке клавиатуры
.count(func)async () => number — общее количество элементов для полной информации о страницах
.item(func)(data) => { title, id } — маппинг элемента в кнопку
.onSelect(callback)({ id, context }) => void — обработчик нажатия на кнопку элемента
.withPageInfo(format)({ totalPages, currentPage }) => string — текст кнопки с информацией о странице
.withFirstLastPage()Добавить кнопки ⏮️/⏭️ первой/последней страницы
.wrapKeyboard(func)Постобработка клавиатуры для добавления дополнительных кнопок
.selectCallbackData(func)Переопределить callback data для кнопок выбора

Получение клавиатуры

ts
// Только клавиатура
const keyboard = await pagination.getKeyboard(offset);

// Клавиатура + загруженные данные + информация о пагинации
const { keyboard, data, pagination: info } = await pagination.getKeyboardWithData(offset);

// Данные + информация о пагинации без клавиатуры
const { data, pagination: info } = await pagination.getDataWithPaginationInfo(offset);

paginationFor(paginationList)

GramIO-плагин, который маршрутизирует события callback_query к нужному экземпляру Pagination.

ts
import { paginationFor } from "@gramio/pagination/plugin";

const bot = new Bot("")
    .extend(paginationFor([pagination1, pagination2]));

Стратегии пагинации

Без .count() (limit+1)

Загружает limit + 1 элементов для определения наличия следующей страницы. Без информации об общем количестве страниц и текущей странице.

С .count()

Запускает запросы количества и данных параллельно. Включает функции .withPageInfo() и .withFirstLastPage().

Кнопки навигации

КнопкаУсловие
⏮️ Первая страница.withFirstLastPage() + есть предыдущая
⬅️ Назадесть предыдущая страница
Инфо о странице.withPageInfo() + .count() установлен
➡️ Вперёдесть следующая страница
⏭️ Последняя страница.withFirstLastPage() + есть следующая