# `LiveFilter.Pagination`
[🔗](https://github.com/agoodway/livefilter/blob/v0.2.0/lib/live_filter/pagination.ex#L1)

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

# `t`

```elixir
@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
}
```

# `change_limit`

```elixir
@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}

# `end_item`

```elixir
@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

# `go_to_page`

```elixir
@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

# `has_next?`

```elixir
@spec has_next?(t()) :: boolean()
```

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

# `has_prev?`

```elixir
@spec has_prev?(t()) :: boolean()
```

Returns true if there is a previous page.

## Example

    iex> pagination = %LiveFilter.Pagination{offset: 25}
    iex> LiveFilter.Pagination.has_prev?(pagination)
    true

# `new`

```elixir
@spec new(keyword()) :: t()
```

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, ...}

# `next_page`

```elixir
@spec next_page(t()) :: t()
```

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

# `page`

```elixir
@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

# `prev_page`

```elixir
@spec prev_page(t()) :: t()
```

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

# `reset`

```elixir
@spec reset(t()) :: t()
```

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

# `start_item`

```elixir
@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

# `total_pages`

```elixir
@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

# `with_total`

```elixir
@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, ...}

---

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