# Feature Specification: Library Pagination UI **Feature Branch**: `015-library-pagination` **Created**: 2026-05-09 **Status**: Draft **Input**: User description: "Pagination UI for the image library" ## User Scenarios & Testing *(mandatory)* ### User Story 1 - Navigate Pages of Images (Priority: P1) A user with a large image library currently sees at most 50 images and a "Load more" button that appends more images below. There is no way to jump to a specific point in the library or know how many images exist in total. This story replaces the append-on-load pattern with page-by-page navigation: Previous/Next buttons and a "Page N of M" indicator so the user always knows where they are. **Why this priority**: The core usability gap — a library of any meaningful size is effectively unnavigable today. Without this, the feature has no value. **Independent Test**: Load the library page. Confirm a page indicator ("Page 1 of N") is visible and the total image count is shown. Click "Next" — confirm the next set of images loads and the indicator updates. Click "Previous" — confirm the first set returns. On the first page, "Previous" is absent or disabled. On the last page, "Next" is absent or disabled. Changing a tag filter resets to page 1. **Acceptance Scenarios**: 1. **Given** the library has more images than fit on one page, **When** the page loads, **Then** only the first page of images is shown with a "Next" button and "Page 1 of N" indicator visible. 2. **Given** the user is on page 1, **When** they click "Next", **Then** the next page of images replaces the current grid (not appended) and the indicator updates to "Page 2 of N". 3. **Given** the user is on the last page, **When** they view the page, **Then** the "Next" button is absent or disabled and "Previous" is present. 4. **Given** the user is on page 1, **When** they view the page, **Then** the "Previous" button is absent or disabled. 5. **Given** the library has fewer images than one page, **When** the page loads, **Then** no pagination controls are shown. 6. **Given** active tag filters are applied, **When** the user changes the filter, **Then** the page resets to 1 and the indicator updates. --- ### User Story 2 - Page State Reflected in URL (Priority: P2) The current library URL is always `/`. After implementing page navigation, a user who shares or bookmarks a URL should land on the same page they were viewing, not always page 1. **Why this priority**: Useful for bookmarking and sharing a specific point in the library, but the library is fully functional without it. **Independent Test**: Navigate to page 3 of the library. Copy the URL from the browser address bar. Open it in a new tab. Confirm page 3 loads directly. Confirm the Back button in the browser returns to page 2. **Acceptance Scenarios**: 1. **Given** the user navigates to page 3, **When** the page URL is copied and opened in a new tab, **Then** page 3 loads directly without navigating through prior pages. 2. **Given** the user navigates Next through several pages, **When** they press the browser Back button, **Then** the previous page is restored. 3. **Given** the URL includes a page number beyond the total pages available, **When** the page loads, **Then** page 1 is shown rather than an error. --- ### Edge Cases - What happens when the total drops below the current page (e.g., images deleted in another session)? → Display page 1. - What happens when the library is empty? → No pagination controls shown; existing empty state displayed. - What happens when only one page of results exists? → No pagination controls shown. - What happens when a filter change results in fewer pages than the current page? → Reset to page 1. ## Requirements *(mandatory)* ### Functional Requirements - **FR-001**: The library MUST display images in discrete pages rather than an appending list. - **FR-002**: The library MUST show a page indicator displaying the current page number and total page count (e.g., "Page 2 of 7"). - **FR-003**: The library MUST show the total number of images matching the current filters (e.g., "143 images"). - **FR-004**: A "Next" control MUST be available on all pages except the last; a "Previous" control MUST be available on all pages except the first. - **FR-005**: Pagination controls MUST NOT be shown when all images fit on a single page. - **FR-006**: Navigating to a new page MUST replace the displayed images, not append to them. - **FR-007**: Changing a tag filter MUST reset the current page to 1. - **FR-008**: The current page number MUST be reflected in the URL query string so that the URL is bookmarkable and shareable. - **FR-009**: Loading a URL with a page parameter MUST display the correct page directly. - **FR-010**: A page parameter beyond the available range MUST silently fall back to page 1. - **FR-011**: The page size (number of images per page) MUST be 24 images. ## Success Criteria *(mandatory)* ### Measurable Outcomes - **SC-001**: A user can navigate from page 1 to any other page using only Previous/Next controls within 2 clicks per page. - **SC-002**: The total image count and current position are visible without scrolling on page load. - **SC-003**: A bookmarked or shared page URL loads the correct page 100% of the time (within the valid range). - **SC-004**: Changing a tag filter always resets to page 1 with no stale images from the previous page visible. - **SC-005**: Pages with fewer images than the page size (the last page) display correctly without layout breakage. ## Assumptions - Page size is fixed at 24 images; no user-configurable page size is required. - The API already supports `limit` and `offset` parameters; no backend changes are needed. - The existing "Load more" / infinite-scroll pattern is fully replaced by page navigation. - Browser history integration (Back/Forward) is satisfied by URL query parameter updates. - Mobile responsiveness of pagination controls is required to match the existing library layout.