Pagination state with PostgREST-compatible limit/offset.
Provides computed properties for page number, total pages, and navigation state.
Uses strict PostgREST URL parameters (limit/offset) for compatibility.
Example
# Parse from URL params
{pagination, remaining} = LiveFilter.pagination_from_params(params, default_limit: 25)
# Access computed properties
LiveFilter.Pagination.page(pagination) # => 3
LiveFilter.Pagination.total_pages(pagination) # => 10
LiveFilter.Pagination.has_next?(pagination) # => true
# Serialize back to URL params
LiveFilter.Params.Serializer.pagination_to_params(pagination)
# => %{"limit" => "25", "offset" => "50"}
Summary
Functions
Returns pagination with a new limit (items per page).
Returns the end item number for display.
Returns pagination for a specific page number (1-indexed).
Returns true if there is a next page.
Returns true if there is a previous page.
Creates a new pagination struct with the given options.
Returns pagination for the next page.
Returns the current page number (1-indexed).
Returns pagination for the previous page, or the same pagination if already on page 1.
Resets pagination to the first page (offset: 0).
Returns the 1-indexed start item number for display.
Returns the total number of pages, or nil if total_count is unknown.
Updates the pagination with a new total count and computes navigation state.
Types
@type t() :: %LiveFilter.Pagination{ limit: pos_integer(), limit_options: [pos_integer()], max_limit: pos_integer(), offset: non_neg_integer(), total_count: non_neg_integer() | nil }
Functions
@spec change_limit(t(), pos_integer()) :: t()
Returns pagination with a new limit (items per page).
Resets offset to 0 to start at page 1.
Example
iex> pagination = %LiveFilter.Pagination{limit: 25, offset: 50}
iex> new_pagination = LiveFilter.Pagination.change_limit(pagination, 50)
iex> {new_pagination.limit, new_pagination.offset}
{50, 0}
@spec end_item(t()) :: pos_integer()
Returns the end item number for display.
Capped at total_count if known.
Example
iex> pagination = %LiveFilter.Pagination{limit: 25, offset: 50, total_count: 60}
iex> LiveFilter.Pagination.end_item(pagination)
60
@spec go_to_page(t(), pos_integer()) :: t()
Returns pagination for a specific page number (1-indexed).
Clamps to valid page range if total_count is known.
Example
iex> pagination = %LiveFilter.Pagination{limit: 25, total_count: 100}
iex> page5 = LiveFilter.Pagination.go_to_page(pagination, 5)
iex> page5.offset
100 # Clamped to max valid offset
Returns true if there is a next page.
Returns false if total_count is nil (unknown).
Example
iex> pagination = %LiveFilter.Pagination{limit: 25, offset: 0, total_count: 100}
iex> LiveFilter.Pagination.has_next?(pagination)
true
Returns true if there is a previous page.
Example
iex> pagination = %LiveFilter.Pagination{offset: 25}
iex> LiveFilter.Pagination.has_prev?(pagination)
true
Creates a new pagination struct with the given options.
Options
:limit- Number of items per page (default: 25):offset- Number of items to skip (default: 0):total_count- Total number of items (default: nil):limit_options- Available per-page options for UI dropdown (default: [10, 25, 50, 100]):max_limit- Maximum allowed limit value (default: 100)
Example
iex> LiveFilter.Pagination.new(limit: 50, offset: 100)
%LiveFilter.Pagination{limit: 50, offset: 100, ...}
Returns pagination for the next page.
Does not check if a next page exists — caller should check has_next?/1.
Example
iex> pagination = %LiveFilter.Pagination{limit: 25, offset: 50}
iex> next = LiveFilter.Pagination.next_page(pagination)
iex> next.offset
75
@spec page(t()) :: pos_integer()
Returns the current page number (1-indexed).
Example
iex> pagination = %LiveFilter.Pagination{limit: 25, offset: 50}
iex> LiveFilter.Pagination.page(pagination)
3
Returns pagination for the previous page, or the same pagination if already on page 1.
Example
iex> pagination = %LiveFilter.Pagination{limit: 25, offset: 50}
iex> prev = LiveFilter.Pagination.prev_page(pagination)
iex> prev.offset
25
Resets pagination to the first page (offset: 0).
Example
iex> pagination = %LiveFilter.Pagination{limit: 25, offset: 100}
iex> reset = LiveFilter.Pagination.reset(pagination)
iex> reset.offset
0
@spec start_item(t()) :: pos_integer()
Returns the 1-indexed start item number for display.
Example
iex> pagination = %LiveFilter.Pagination{offset: 50}
iex> LiveFilter.Pagination.start_item(pagination)
51
@spec total_pages(t()) :: pos_integer() | nil
Returns the total number of pages, or nil if total_count is unknown.
Example
iex> pagination = %LiveFilter.Pagination{limit: 25, total_count: 100}
iex> LiveFilter.Pagination.total_pages(pagination)
4
@spec with_total(t(), non_neg_integer()) :: t()
Updates the pagination with a new total count and computes navigation state.
Example
iex> pagination = %LiveFilter.Pagination{limit: 25, offset: 50}
iex> LiveFilter.Pagination.with_total(pagination, 127)
%LiveFilter.Pagination{limit: 25, offset: 50, total_count: 127, ...}