# discord-paginated-embeds

A simple, extensible discord.py pagination for embedded messages.

Create paginated embeds with **Prev / Next** buttons, or group multiple sections behind a **Select dropdown** — all with minimal boilerplate.

## Installation

```bash
pip install discord-paginated-embeds
```

## Quick Start

### Simple Pagination (Prev / Next)

```python
from paginatedembeds import Page, PaginatedView

pages = [
    Page(title="Welcome",  description="Page **1** of 3.", colour=0x2ECC71),
    Page(title="Features", description="Page **2** of 3.", colour=0x2ECC71),
    Page(title="Credits",  description="Page **3** of 3.", colour=0x2ECC71),
]

@bot.tree.command()
async def demo(interaction):
    await interaction.response.send_message("Loading…")
    message = await interaction.original_response()

    view = PaginatedView(pages)
    await view.send(message)
```

### Custom Page Subclasses

```python
from paginatedembeds import Page

class ProfilePage(Page):
    def __init__(self, username: str, avatar_url: str):
        super().__init__(title=f"Profile — {username}", colour=0x3498DB)
        self.set_thumbnail(url=avatar_url)
        self.add_field(name="Username", value=username, inline=False)

class StatsPage(Page):
    def __init__(self, wins: int, losses: int):
        super().__init__(title="Battle Stats", colour=0xE74C3C)
        self.add_field(name="Wins",   value=str(wins))
        self.add_field(name="Losses", value=str(losses))
```

### Grouped Pagination (Select Dropdown + Prev / Next)

```python
from paginatedembeds import Page, PageGroup, GroupedPaginator

info_group = PageGroup(
    label="Info",
    description="General information",
    emoji="ℹ️",
    default=True,
    pages=[ProfilePage("Ash", "https://example.com/ash.png")],
)

stats_group = PageGroup(
    label="Stats",
    description="Battle statistics",
    emoji="📊",
    pages=[StatsPage(wins=42, losses=7)],
)

@bot.tree.command()
async def profile(interaction):
    await interaction.response.send_message("Loading…")
    message = await interaction.original_response()

    paginator = GroupedPaginator(groups=[info_group, stats_group])
    await paginator.send(message)
```

## API Reference

### `Page`

A thin subclass of `discord.Embed`. Subclass it to create reusable page templates. Supports the full Embed API (`add_field`, `set_image`, `set_thumbnail`, etc.).

### `PaginatedView`

A `discord.ui.View` with **Prev / Next** buttons.

| Parameter | Type | Default | Description |
|---|---|---|---|
| `pages` | `Sequence[Embed]` | *required* | List of embeds to paginate |
| `timeout` | `float \| None` | `600` | View timeout in seconds |
| `wrap` | `bool` | `False` | Wrap from last→first page |
| `show_page_count` | `bool` | `True` | Show "X / Y" indicator |
| `prev_label` | `str` | `"Prev"` | Previous button label |
| `next_label` | `str` | `"Next"` | Next button label |

**Methods:**
- `await view.send(message)` — Edit a message to show page 1 with buttons.
- `await view.goto(page)` — Jump to a specific page index.

### `PageGroup`

A named group of pages for use with `GroupedPaginator`.

| Parameter | Type | Default | Description |
|---|---|---|---|
| `label` | `str` | *required* | Name in the select menu |
| `pages` | `list[Embed]` | `[]` | Pages in this group |
| `description` | `str \| None` | `None` | Dropdown description |
| `emoji` | `str \| None` | `None` | Dropdown emoji |
| `default` | `bool` | `False` | Selected by default |

### `GroupedPaginator`

A `discord.ui.View` with a **Select dropdown** + **Prev / Next** buttons. Each group maintains its own independent page index.

| Parameter | Type | Default | Description |
|---|---|---|---|
| `groups` | `Sequence[PageGroup]` | *required* | Page groups to switch between |
| `timeout` | `float \| None` | `600` | View timeout in seconds |
| `wrap` | `bool` | `False` | Wrap page navigation |
| `show_page_count` | `bool` | `True` | Show "X / Y" indicator |
| `prev_label` | `str` | `"Prev"` | Previous button label |
| `next_label` | `str` | `"Next"` | Next button label |

**Methods:**
- `await paginator.send(message)` — Edit a message to show the default group.
- `await paginator.goto(page)` — Jump to a page within the active group.

## Features

- Works with plain `discord.Embed` or custom `Page` subclasses
- Automatic button state management (disable at boundaries)
- Optional wrapping navigation (last → first)
- Page counter indicator (`1 / 5`)
- Customizable button labels
- Auto-disables all controls on timeout
- Per-group independent page tracking in `GroupedPaginator`

## Requirements

- Python 3.10+
- discord.py 2.0+

## License

MIT
