Pagination

Pagination utilities and components for the media gallery.

PaginationInfo

Computed pagination information.


PaginationInfo


def PaginationInfo(
    total_items:int, items_per_page:int, current_page:int
)->None:

Computed pagination information.

# Test PaginationInfo
info = PaginationInfo(total_items=100, items_per_page=24, current_page=1)

# Test basic properties
assert info.total_pages == 5  # 100/24 = 4.16, rounds up to 5
assert info.has_prev == False
assert info.has_next == True
assert info.start_index == 0
assert info.end_index == 24
assert info.items_on_page == 24

# Test middle page
info = PaginationInfo(total_items=100, items_per_page=24, current_page=3)
assert info.has_prev == True
assert info.has_next == True
assert info.start_index == 48
assert info.end_index == 72

# Test last page
info = PaginationInfo(total_items=100, items_per_page=24, current_page=5)
assert info.has_prev == True
assert info.has_next == False
assert info.start_index == 96
assert info.end_index == 100
assert info.items_on_page == 4

# Test visible pages
info = PaginationInfo(total_items=100, items_per_page=10, current_page=5)
visible = info.get_visible_pages(5)
assert len(visible) == 5
assert 5 in visible  # Current page

# Test empty
info = PaginationInfo(total_items=0, items_per_page=24, current_page=1)
assert info.total_pages == 1
assert info.items_on_page == 0

print("PaginationInfo tests passed!")
PaginationInfo tests passed!

Pagination Component

Render pagination controls.


render_pagination


def render_pagination(
    info:PaginationInfo, # Pagination info
    page_url:str, # URL for page change handler
    hx_target:Optional=None, # HTMX target for swap
    max_visible:int=5, # Maximum visible page buttons
)->Any: # Pagination component

Render pagination controls.

from fasthtml.common import to_xml

# Test pagination
info = PaginationInfo(total_items=100, items_per_page=24, current_page=3)
pagination = render_pagination(info, "/page", "#gallery")
html = to_xml(pagination)

assert 'id="media-gallery-pagination"' in html
assert "join" in html
assert "hx-post" in html
# Current page should be highlighted
assert "btn-primary" in html

# Test single page (no pagination)
info = PaginationInfo(total_items=10, items_per_page=24, current_page=1)
pagination = render_pagination(info, "/page")
assert pagination is None

print("render_pagination tests passed!")
render_pagination tests passed!

Pagination Info Bar

Shows “Showing X-Y of Z items”.


render_pagination_info


def render_pagination_info(
    info:PaginationInfo, # Pagination info
)->Any: # Info text component

Render pagination info text.

# Test pagination info
info = PaginationInfo(total_items=100, items_per_page=24, current_page=1)
info_text = render_pagination_info(info)
html = to_xml(info_text)
assert "Showing 1-24 of 100 items" in html

# Test last page
info = PaginationInfo(total_items=100, items_per_page=24, current_page=5)
info_text = render_pagination_info(info)
html = to_xml(info_text)
assert "Showing 97-100 of 100 items" in html

# Test empty
info = PaginationInfo(total_items=0, items_per_page=24, current_page=1)
info_text = render_pagination_info(info)
html = to_xml(info_text)
assert "No items" in html

print("render_pagination_info tests passed!")
render_pagination_info tests passed!