# `PhoenixKitWeb.Components.Core.Pagination`
[🔗](https://github.com/BeamLabEU/phoenix_kit/blob/v1.7.165/lib/phoenix_kit_web/components/core/pagination.ex#L1)

Pagination components for list views in PhoenixKit.

Provides pagination controls and information display following daisyUI design patterns.

Two flavours:

  * Page-numbered (`<.pagination>`, `<.pagination_controls>`,
    `<.pagination_info>`) — URL-param driven, suits standalone admin
    pages with deep-linkable state.

  * Load-more (`<.load_more>`) — click-driven LV event that grows
    the loaded set in place. Suits embeddable LVs (no URL routing),
    lists with DnD reorder (rows append, don't replace), and lists
    with client-side bulk-select (selection persists across loads
    because rows stay in the DOM).

# `load_more`

Load-more footer for incrementally-loaded lists.

Renders a centered "Showing N of M %{noun}" line and a "Load more"
button (hidden when `loaded >= total`). Clicking the button emits
the LV event named in `on_load_more`.

Suited for embeddable LVs where URL-param pagination isn't an
option, lists with DnD reorder (rows append rather than navigate
away), and lists with client-side bulk-select (selection persists
because the DOM grows, it doesn't get replaced).

## Attributes

- `loaded` — number of rows currently rendered (required)
- `total` — total rows matching the current filter/sort (required)
- `on_load_more` — LV event name pushed on button click
  (default `"load_more"`)
- `noun_plural` — used in the "Showing N of M %{noun}" line
  (default `"items"`)
- `class` — additional classes on the outer wrapper
- `infinite` — when `true`, the footer also auto-loads on scroll via
  the `InfiniteScroll` hook (the manual button stays as a fallback).
  Requires `id`. (default `false`)
- `id` — DOM id, **required when `infinite`** (the JS hook needs it)
- `cursor` — an opaque per-page marker (e.g. `"items-<offset>"`) that
  changes on each load. The `InfiniteScroll` hook re-fires only when it
  changes, so it both keeps firing while still on screen and ignores
  unrelated diffs. Only used when `infinite`. Defaults to `@loaded`
  (which already changes per page), so most callers can omit it; pass
  an explicit value only when `@loaded` is not a faithful page marker.

## Example

    <.load_more
      loaded={length(@projects)}
      total={@total_count}
      on_load_more="load_more"
      noun_plural={gettext("projects")}
    />

    <%!-- Auto-load on scroll + manual fallback --%>
    <.load_more
      id="items-load-more"
      loaded={length(@items)}
      total={@total}
      infinite
      cursor={"items-#{@offset}"}
    />

## Attributes

* `loaded` (`:integer`) (required)
* `total` (`:integer`) (required)
* `on_load_more` (`:string`) - Defaults to `"load_more"`.
* `noun_plural` (`:string`) - Defaults to `"items"`.
* `class` (`:string`) - Defaults to `""`.
* `id` (`:string`) - Defaults to `nil`.
* `infinite` (`:boolean`) - Defaults to `false`.
* `cursor` (`:string`) - Defaults to `""`.

# `pagination`

Renders complete pagination controls with automatic URL building.

Simpler alternative to pagination_controls that handles URL building internally.
Preserves all query parameters while changing page number.

## Attributes
- `current_page` - Current active page number (required)
- `total_pages` - Total number of pages available (required)
- `base_path` - Base URL path without query params (required)
- `params` - Map of query parameters to preserve (default: %{})

## Examples

    <.pagination
      current_page={@page}
      total_pages={@total_pages}
      base_path="/admin/emails"
      params={%{"search" => @filters.search, "status" => @filters.status}}
    />

    <%!-- Minimal usage --%>
    <.pagination
      current_page={1}
      total_pages={10}
      base_path="/admin/logs"
    />

## Attributes

* `current_page` (`:integer`) (required)
* `total_pages` (`:integer`) (required)
* `base_path` (`:string`) (required)
* `params` (`:map`) - Defaults to `%{}`.

# `pagination_controls`

Displays pagination controls with page numbers and navigation buttons.

## Attributes
- `page` - Current page number (required)
- `total_pages` - Total number of pages (required)
- `build_url` - Function that takes page number and returns URL (required)
- `class` - Additional CSS classes

## Examples

    <.pagination_controls
      page={@page}
      total_pages={@total_pages}
      build_url={&build_page_url(&1, assigns)}
    />

## Attributes

* `page` (`:integer`) (required)
* `total_pages` (`:integer`) (required)
* `build_url` (`:any`) (required)
* `class` (`:string`) - Defaults to `""`.

# `pagination_info`

Displays pagination information showing result range.

## Attributes
- `page` - Current page number (required)
- `per_page` - Items per page (required)
- `total_count` - Total number of items (required)
- `class` - Additional CSS classes

## Examples

    <.pagination_info
      page={@page}
      per_page={@per_page}
      total_count={@total_count}
    />

    # Renders: "Showing 1 to 25 of 100 results"
    # Single-page result drops the redundant " of N" — e.g. with
    # total_count=4 and per_page=25: "Showing 1 to 4 results".

## Attributes

* `page` (`:integer`) (required)
* `per_page` (`:integer`) (required)
* `total_count` (`:integer`) (required)
* `class` (`:string`) - Defaults to `""`.

---

*Consult [api-reference.md](api-reference.md) for complete listing*
