PhoenixKitWeb.Components.Core.Pagination (phoenix_kit v2.29.1)

Copy Markdown View Source

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. <.page_size_selector> sits next to either and lets the viewer pick the rows per page.

  • 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).

Summary

Functions

Load-more footer for incrementally-loaded lists.

Rows-per-page selector, a sibling of <.pagination>.

Renders complete pagination controls with automatic URL building.

Displays pagination controls with page numbers and navigation buttons.

Displays pagination information showing result range.

Functions

load_more(assigns)

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 "".
  • Global attributes are accepted. Forwarded to the button, so a page with more than one load-more list can tell its handler which one was clicked (phx-value-*). Without this a caller has to mint a separate event name per list.

page_size_selector(assigns)

Rows-per-page selector, a sibling of <.pagination>.

A daisyUI <select> wrapped in its own <form phx-change>, so a change reaches the LiveView as %{"per_page" => "25"} under the event named in on_change. The LiveView is expected to push the value into the URL and reset the page to 1 — with PhoenixKitWeb.Live.UrlState that is one push_url_state(socket, per_page: n), which does both.

Attributes

  • value — the current page size (required)
  • options — selectable sizes (default [10, 25, 50, 100]). A value outside the list is appended so the select never shows a blank.
  • on_change — LV event name (default "change_per_page")
  • class — additional classes on the wrapper
  • id — DOM id of the <select>; the wrapping form gets id <> "-form" (default "pk-page-size-" <> on_change — pass one when a page renders two selectors with the same event)
  • auto_fit — adds an "Auto" option backed by the PageSizeAutoFit JS hook, which measures how many rows of table_id fit the viewport and pushes on_change with %{"per_page" => n, "auto" => "1"}, n being the largest option that fits (default false)
  • auto — whether Auto is currently selected (default false)
  • table_id — DOM id of the table the hook measures; required when auto_fit

Example

<.page_size_selector value={@per_page} />

<%!-- Auto-fit pilot --%>
<.page_size_selector
  id="users-per-page"
  value={@per_page}
  auto_fit
  auto={@auto_fit}
  table_id="users-table"
/>

Attributes

  • value (:integer) (required)
  • options (:list) - Defaults to [10, 25, 50, 100].
  • on_change (:string) - Defaults to "change_per_page".
  • class (:string) - Defaults to "".
  • id (:string) - Defaults to nil.
  • auto_fit (:boolean) - Defaults to false.
  • auto (:boolean) - Defaults to false.
  • table_id (:string) - Defaults to nil.

pagination(assigns)

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(assigns)

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(assigns)

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".

Every string is translated. noun_plural names what is being counted (default gettext("results")); pass an already-translated word so the line reads "… of 40 sessions" in the viewer's language:

<.pagination_info
  page={@page}
  per_page={@per_page}
  total_count={@total_count}
  noun_plural={gettext("sessions")}
/>

Attributes

  • page (:integer) (required)
  • per_page (:integer) (required)
  • total_count (:integer) (required)
  • noun_plural (:string) - Defaults to nil.
  • class (:string) - Defaults to "".