### Install and Override Dependency for @gramio/pagination Source: https://github.com/gramiojs/pagination/blob/main/README.md To use @gramio/pagination, you must install it along with a specific version of @gramio/callback-data. This JSON snippet shows how to override the dependency version in your package.json. ```json { "overrides": { "@gramio/callback-data": "^0.0.11" } } ``` -------------------------------- ### Register Pagination Handlers with Bot Plugin using TypeScript Source: https://context7.com/gramiojs/pagination/llms.txt The `paginationFor()` plugin function registers all provided pagination instances with the bot. It automatically handles callback queries for all registered paginations, simplifying the setup process. It takes an array of `AnyPagination` instances. ```typescript import { Bot } from "gramio"; import { Pagination, paginationFor } from "@gramio/pagination"; const data = [ { id: 1, title: "First Item" }, { id: 2, title: "Second Item" }, { id: 3, title: "Third Item" }, { id: 4, title: "Fourth Item" }, { id: 5, title: "Fifth Item" } ]; const myPagination = new Pagination("demo", 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(`You selected item ${id}`, { reply_markup: context.message?.replyMarkup?.payload }); }) .limit(2) .columns(2) .withFirstLastPage() .withPageInfo(({ currentPage, totalPages }) => `${currentPage}/${totalPages}`); const bot = new Bot(process.env.BOT_TOKEN as string) .extend(paginationFor([myPagination])) .command("start", async (ctx) => { await ctx.reply("Welcome! Browse items:", { reply_markup: await myPagination.getKeyboard(0) }); }); await bot.start(); ``` -------------------------------- ### Get Keyboard and Data for a Page with TypeScript Source: https://context7.com/gramiojs/pagination/llms.txt The `.getKeyboardWithData()` method returns both the generated inline keyboard and the actual data items for the current page. This is useful when both the UI representation and the underlying data are needed for rendering. ```typescript const pagination = new Pagination("posts", async ({ offset, limit }) => { return posts.slice(offset, offset + limit); }) .item(post => ({ title: post.title, id: post.id })) .limit(3); bot.command("posts", async (ctx) => { const { keyboard, data, pagination: paginationInfo } = await pagination.getKeyboardWithData(0); const postList = data.map(p => `• ${p.title}`).join("\n"); await ctx.reply( `Recent Posts:\n${postList}\n\nSelect a post to read more:`, { reply_markup: keyboard } ); }); ``` -------------------------------- ### Integrate Pagination with a Bot Command in TypeScript Source: https://github.com/gramiojs/pagination/blob/main/README.md This TypeScript code shows how to integrate the configured pagination instance with a bot. It uses the gramm.io bot framework, extends the bot with the pagination middleware, and sets up a '/start' command to display the initial paginated keyboard. ```typescript 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(); ``` -------------------------------- ### Initialize Pagination Instance Source: https://context7.com/gramiojs/pagination/llms.txt Demonstrates creating a new Pagination instance with a unique identifier and a data fetching function. It shows basic initialization and advanced usage with custom callback data payloads for filtering. ```typescript import { Pagination } from "@gramio/pagination"; // Basic pagination without payload const basicPagination = new Pagination("products", async ({ offset, limit }) => { const products = await database.products.findMany({ skip: offset, take: limit }); return products; }); // Pagination with custom payload for filtering import { CallbackData } from "@gramio/callback-data"; const filterPayload = new CallbackData("filter") .string("category") .boolean("inStock"); const filteredPagination = new Pagination( "products", filterPayload, async ({ offset, limit, payload }) => { return await database.products.findMany({ where: { category: payload.category, inStock: payload.inStock }, skip: offset, take: limit }); } ); ``` -------------------------------- ### Initialize and Configure Pagination with TypeScript Source: https://github.com/gramiojs/pagination/blob/main/README.md This TypeScript code demonstrates how to initialize and configure the Pagination class from @gramio/pagination. It defines data fetching, item transformation, selection handling, and UI customization like page limits, columns, and navigation. ```typescript 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 }) => { console.log(id, context); return context.editText(`Edited ${id}`, { reply_markup: context.message?.replyMarkup?.payload, }); }) .limit(2) .columns(2) .withFirstLastPage() .withPageInfo( ({ totalPages, currentPage }) => `${currentPage} / ${totalPages}` ); ``` -------------------------------- ### Pagination Class Constructor Source: https://context7.com/gramiojs/pagination/llms.txt Initializes a new Pagination instance. You can provide a unique identifier, a data fetching function, and an optional payload object for passing context. ```APIDOC ## Pagination Class Constructor ### Description Creates a new pagination instance with a unique identifier and data fetching function. The constructor supports optional payload data for passing additional context through pagination states. ### Method `new Pagination(id: string, payload?: CallbackData, fetcher: (context: PaginationContext) => Promise>)` ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Request Example ```typescript import { Pagination } from "@gramio/pagination"; // Basic pagination without payload const basicPagination = new Pagination("products", async ({ offset, limit }) => { const products = await database.products.findMany({ skip: offset, take: limit }); return products; }); // Pagination with custom payload for filtering import { CallbackData } from "@gramio/callback-data"; const filterPayload = new CallbackData("filter") .string("category") .boolean("inStock"); const filteredPagination = new Pagination( "products", filterPayload, async ({ offset, limit, payload }) => { return await database.products.findMany({ where: { category: payload.category, inStock: payload.inStock }, skip: offset, take: limit }); } ); ``` ### Response #### Success Response (200) N/A (Constructor does not return a response) #### Response Example N/A ``` -------------------------------- ### .withPageInfo(format: (data) => string) Source: https://context7.com/gramiojs/pagination/llms.txt Adds a centered button displaying the current pagination status. This feature only works when the `.count()` method is provided. ```APIDOC ## .withPageInfo(format: (data) => string) ### Description Adds a centered button displaying current pagination status. Only works when .count() is provided. ### Method `.withPageInfo(format: (data) => string): Pagination` ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Request Example ```typescript const pagination = new Pagination("items", async ({ offset, limit }) => { return items.slice(offset, offset + limit); }) .count(() => Promise.resolve(items.length)) .limit(3) .withPageInfo(({ currentPage, totalPages }) => { return `📄 ${currentPage}/${totalPages}`; }); ``` ### Response #### Success Response (200) Returns the `Pagination` instance for chaining. #### Response Example ```typescript // Example response is the modified Pagination instance ``` ``` -------------------------------- ### .onSelect(callback: (input) => void) Source: https://context7.com/gramiojs/pagination/llms.txt Defines the action to be performed when a user clicks an item button. Receives the item id, context, and optional payload. ```APIDOC ## .onSelect(callback: (input) => void) ### Description Defines the action when a user clicks an item button. Receives the item id, context, and optional payload. ### Method `.onSelect(callback: (input) => void): Pagination` ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Request Example ```typescript const pagination = new Pagination("movies", async ({ offset, limit }) => { return movies.slice(offset, offset + limit); }) .item(movie => ({ title: movie.title, id: movie.id })) .onSelect(async ({ id, context, payload }) => { const movie = movies.find(m => m.id === id); await context.editText( `You selected: ${movie.title}\nRating: ${movie.rating}/10`, { reply_markup: context.message?.replyMarkup?.payload } ); }); ``` ### Response #### Success Response (200) Returns the `Pagination` instance for chaining. #### Response Example ```typescript // Example response is the modified Pagination instance ``` ``` -------------------------------- ### Configure Items Per Page Source: https://context7.com/gramiojs/pagination/llms.txt Illustrates how to set the number of items to display on each page using the `.limit()` method. The default value is 10 items per page. ```typescript const pagination = new Pagination("items", async ({ offset, limit }) => { return items.slice(offset, offset + limit); }).limit(5); // Show 5 items per page ``` -------------------------------- ### Set Keyboard Columns Source: https://context7.com/gramiojs/pagination/llms.txt Shows how to define the number of columns for the item buttons within the inline keyboard layout using the `.columns()` method. ```typescript const pagination = new Pagination("grid", async ({ offset, limit }) => { return products.slice(offset, offset + limit); }) .columns(3) // 3 columns .item(product => ({ title: product.name, id: product.id })); ``` -------------------------------- ### Generate Inline Keyboard for a Page with TypeScript Source: https://context7.com/gramiojs/pagination/llms.txt The `.getKeyboard()` method generates and returns an `InlineKeyboard` instance for a specific page, which can be directly used in bot replies. It takes an optional offset for the desired page. ```typescript import { Bot } from "gramio"; const bot = new Bot(process.env.BOT_TOKEN as string); const pagination = new Pagination("catalog", async ({ offset, limit }) => { return catalog.slice(offset, offset + limit); }) .item(item => ({ title: item.name, id: item.id })) .limit(4) .columns(2); bot.command("catalog", async (ctx) => { const keyboard = await pagination.getKeyboard(0); await ctx.reply("Browse our catalog:", { reply_markup: keyboard }); }); ``` -------------------------------- ### Handle Item Selection Source: https://context7.com/gramiojs/pagination/llms.txt Shows how to define the action to be executed when a user clicks an item button using the `.onSelect()` method. It receives the item's `id`, `context`, and an optional `payload`. ```typescript const pagination = new Pagination("movies", async ({ offset, limit }) => { return movies.slice(offset, offset + limit); }) .item(movie => ({ title: movie.title, id: movie.id })) .onSelect(async ({ id, context, payload }) => { const movie = movies.find(m => m.id === id); await context.editText( `You selected: ${movie.title}\nRating: ${movie.rating}/10`, { reply_markup: context.message?.replyMarkup?.payload } ); }); ``` -------------------------------- ### Add First and Last Page Buttons to Keyboard with TypeScript Source: https://context7.com/gramiojs/pagination/llms.txt The `.withFirstLastPage()` method adds 'first' (⏮️) and 'last' (⏭️) page navigation buttons to the keyboard, enhancing user navigation for paginated content. ```typescript const pagination = new Pagination("articles", async ({ offset, limit }) => { return articles.slice(offset, offset + limit); }) .count(() => Promise.resolve(articles.length)) .limit(5) .withFirstLastPage() .withPageInfo(({ currentPage, totalPages }) => `Page ${currentPage}/${totalPages}`); ``` -------------------------------- ### .count(func: () => Promise) Source: https://context7.com/gramiojs/pagination/llms.txt Provides the total count of items for accurate pagination calculations. Without this, the library uses offset-based detection. ```APIDOC ## .count(func: () => Promise) ### Description Provides total count of items for accurate pagination calculations. Without this, the library uses offset-based detection (fetching limit+1 items). ### Method `.count(func: () => Promise): Pagination` ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Request Example ```typescript const data = [ { id: 1, name: "Item 1" }, { id: 2, name: "Item 2" }, { id: 3, name: "Item 3" }, { id: 4, name: "Item 4" }, { id: 5, name: "Item 5" } ]; const pagination = new Pagination("items", async ({ offset, limit }) => { return data.slice(offset, offset + limit); }) .count(() => Promise.resolve(data.length)) .limit(2); // This enables accurate page indicators like "Page 1/3" ``` ### Response #### Success Response (200) Returns the `Pagination` instance for chaining. #### Response Example ```typescript // Example response is the modified Pagination instance ``` ``` -------------------------------- ### Provide Total Item Count Source: https://context7.com/gramiojs/pagination/llms.txt Explains the use of the `.count()` method to provide the total number of items, enabling accurate pagination calculations and page indicators. If not provided, the library defaults to offset-based detection. ```typescript const data = [ { id: 1, name: "Item 1" }, { id: 2, name: "Item 2" }, { id: 3, name: "Item 3" }, { id: 4, name: "Item 4" }, { id: 5, name: "Item 5" } ]; const pagination = new Pagination("items", async ({ offset, limit }) => { return data.slice(offset, offset + limit); }) .count(() => Promise.resolve(data.length)) .limit(2); // This enables accurate page indicators like "Page 1/3" ``` -------------------------------- ### .item(func: (data) => PaginationItemOutput) Source: https://context7.com/gramiojs/pagination/llms.txt Transforms data items into button format with title and id. Required when data doesn't have default title/id fields. ```APIDOC ## .item(func: (data) => PaginationItemOutput) ### Description Transforms data items into button format with title and id. Required when data doesn't have default title/id fields. ### Method `.item(func: (data) => PaginationItemOutput): Pagination` ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Request Example ```typescript interface Product { productId: number; productName: string; price: number; } const products: Product[] = [ { productId: 101, productName: "Laptop", price: 999 }, { productId: 102, productName: "Mouse", price: 29 } ]; const pagination = new Pagination("products", async ({ offset, limit }) => { return products.slice(offset, offset + limit); }) .item(product => ({ title: `${product.productName} - $${product.price}`, id: product.productId })); ``` ### Response #### Success Response (200) Returns the `Pagination` instance for chaining. #### Response Example ```typescript // Example response is the modified Pagination instance ``` ``` -------------------------------- ### Customize Keyboard with Custom Buttons using TypeScript Source: https://context7.com/gramiojs/pagination/llms.txt The `.wrapKeyboard()` method allows for custom modification of the generated inline keyboard. It's useful for adding extra buttons or rows, such as navigation or action buttons. The function receives the current keyboard, pagination instance, and data. ```typescript import { InlineKeyboard } from "@gramio/keyboards"; const pagination = new Pagination("settings", async ({ offset, limit }) => { return settings.slice(offset, offset + limit); }) .wrapKeyboard(({ keyboard, pagination, data }) => { return keyboard .row() .text("🏠 Back to Menu", "main_menu") .text("❌ Close", "close"); }); ``` -------------------------------- ### Define Item Button Format Source: https://context7.com/gramiojs/pagination/llms.txt Demonstrates how to use the `.item()` method to transform data items into the required button format, including `title` and `id`. This is essential when the data structure does not have default `title` or `id` fields. ```typescript interface Product { productId: number; productName: string; price: number; } const products: Product[] = [ { productId: 101, productName: "Laptop", price: 999 }, { productId: 102, productName: "Mouse", price: 29 } ]; const pagination = new Pagination("products", async ({ offset, limit }) => { return products.slice(offset, offset + limit); }) .item(product => ({ title: `${product.productName} - $${product.price}`, id: product.productId })); ``` -------------------------------- ### Display Page Information Source: https://context7.com/gramiojs/pagination/llms.txt Illustrates adding a centered button that displays the current pagination status (e.g., 'Page 1/3') using the `.withPageInfo()` method. This feature requires the `.count()` method to be provided. ```typescript const pagination = new Pagination("items", async ({ offset, limit }) => { return items.slice(offset, offset + limit); }) .count(() => Promise.resolve(items.length)) .limit(3) .withPageInfo(({ currentPage, totalPages }) => { return `📄 ${currentPage}/${totalPages}`; }); ``` -------------------------------- ### E-commerce Product Catalog Pagination with Filtering (TypeScript) Source: https://context7.com/gramiojs/pagination/llms.txt This snippet implements a paginated product catalog for a Telegram bot using @gramio/pagination. It includes features like filtering by category, item selection to display product details, and a custom keyboard with navigation and action buttons. The code defines product data, filter callback data, and configures the pagination object with display and interaction logic. ```typescript import { Bot } from "gramio"; import { Pagination, paginationFor } from "@gramio/pagination"; import { CallbackData } from "@gramio/callback-data"; interface Product { id: number; name: string; price: number; category: string; stock: number; } const products: Product[] = [ { id: 1, name: "Gaming Laptop", price: 1299, category: "electronics", stock: 5 }, { id: 2, name: "Wireless Mouse", price: 49, category: "electronics", stock: 50 }, { id: 3, name: "Mechanical Keyboard", price: 129, category: "electronics", stock: 20 }, { id: 4, name: "USB-C Cable", price: 15, category: "accessories", stock: 100 }, { id: 5, name: "Monitor Stand", price: 79, category: "accessories", stock: 15 }, { id: 6, name: "Webcam HD", price: 89, category: "electronics", stock: 30 } ]; const filterData = new CallbackData("product_filter") .string("category"); const productPagination = new Pagination( "products", filterData, async ({ offset, limit, payload }) => { const filtered = products.filter(p => !payload || p.category === payload.category ); return filtered.slice(offset, offset + limit); } ) .count(async () => products.length) .item(product => ({ title: `${product.name} - $${product.price}`, id: product.id })) .onSelect(async ({ id, context }) => { const product = products.find(p => p.id === id); if (!product) return; await context.editText( `📦 *${product.name}*\n\n` + `💰 Price: $${product.price}\n` + `📂 Category: ${product.category}\n` + `📊 In Stock: ${product.stock} units\n\n` + `Click a button to continue browsing.`, { parse_mode: "Markdown", reply_markup: context.message?.replyMarkup?.payload } ); }) .limit(3) .columns(1) .withFirstLastPage() .withPageInfo(({ currentPage, totalPages }) => `Page ${currentPage} of ${totalPages}`) .wrapKeyboard(({ keyboard }) => { return keyboard .row() .text("🔍 Filter by Category", "filter_menu") .row() .text("🛒 View Cart", "view_cart") .text("❌ Close", "close"); }); const bot = new Bot(process.env.BOT_TOKEN as string) .extend(paginationFor([productPagination])) .command("shop", async (ctx) => { await ctx.reply( "🛍️ *Welcome to our Store!*\n\nBrowse our products:", { parse_mode: "Markdown", reply_markup: await productPagination.getKeyboard(0) } ); }) .callbackQuery("filter_menu", async (ctx) => { await ctx.editText("Select a category..."); }) .onStart(() => console.log("Bot started")); await bot.start(); ``` -------------------------------- ### .limit(count: number) Source: https://context7.com/gramiojs/pagination/llms.txt Sets the number of items to display per page. The default is 10 items. ```APIDOC ## .limit(count: number) ### Description Sets the number of items to display per page. Default is 10 items. ### Method `.limit(count: number): Pagination` ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Request Example ```typescript const pagination = new Pagination("items", async ({ offset, limit }) => { return items.slice(offset, offset + limit); }).limit(5); // Show 5 items per page ``` ### Response #### Success Response (200) Returns the `Pagination` instance for chaining. #### Response Example ```typescript // Example response is the modified Pagination instance ``` ``` -------------------------------- ### .columns(count: number) Source: https://context7.com/gramiojs/pagination/llms.txt Defines the number of columns for item buttons in the inline keyboard layout. ```APIDOC ## .columns(count: number) ### Description Defines the number of columns for item buttons in the inline keyboard layout. ### Method `.columns(count: number): Pagination` ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Request Example ```typescript const pagination = new Pagination("grid", async ({ offset, limit }) => { return products.slice(offset, offset + limit); }) .columns(3) // 3 columns .item(product => ({ title: product.name, id: product.id })); ``` ### Response #### Success Response (200) Returns the `Pagination` instance for chaining. #### Response Example ```typescript // Example response is the modified Pagination instance ``` ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.