Page navigation and page-size control for qds-data-table, usable standalone under any paged list.
The qds-pagination component provides page navigation (first, previous, numbered pages, next, last) and a page-size selector. It is designed to sit below a qds-data-table or any paged collection. It is a navigation control, not a form-associated input.
<qds-pagination
page="1"
page-size="25"
total="1284"
></qds-pagination>
const pagination = document.querySelector('qds-pagination');
pagination.addEventListener('qds-page-change', (e) => {
const { page, pageSize, total } = e.detail;
// Refetch data with the new page and page size
fetchData({ page, pageSize });
});
page - 1-based current page number (default 1, clamped to [1, pageCount])page-size - Items per page (default 25)total - Total items, not pages (default 0)page-size-options - Comma-separated list of page sizes (default "10,25,50,100")sibling-count - Page buttons shown either side of the current page (default 1)boundary-count - Page buttons pinned at each end (default 1)show-first-last - Show first/last buttons (default true)show-page-size - Show the page-size selector (default true)show-summary - Show the range summary (default true)compact - Compact mode: drops numbered buttons, shows prev/next and “Page N of M” only (default false)disabled - Disable all controls (default false)size - Control size: sm, md, or lg (default md)page - number - 1-based current page (clamped on set)pageSize - number - Items per pagetotal - number - Total itemspageSizeOptions - number[] - Array of page size optionssiblingCount - number - Sibling countboundaryCount - number - Boundary countshowFirstLast - boolean - Whether first/last buttons are shownshowPageSize - boolean - Whether the page-size selector is shownshowSummary - boolean - Whether the range summary is showncompact - boolean - Compact modedisabled - boolean - Disabled statesize - 'sm' | 'md' | 'lg' - Control sizepageCount - number - Read-only. Math.max(1, Math.ceil(total / pageSize))container - The <nav> containersummary - The range summary spanpage-size - The page-size selector wrapperpage-size-label - The “Rows:” labelcontrols - The page controls wrapperfirst - The first-page buttonprev - The previous-page buttonpage - A page-number buttonpage-current - The current-page button (also carries the page part)ellipsis - An ellipsis spannext - The next-page buttonlast - The last-page buttoncompact-label - The compact “Page N of M” label--qds-pagination-height - Bar height (default 48px)--qds-pagination-button-size - Page button size (default 32px, 44px on coarse pointers)--qds-pagination-gap - Gap between controls (default var(--theme-space-1, 4px))--qds-pagination-border-color - Top border color (default var(--theme-border-primary))qds-page-change - Fired when the page or page size changes via user interaction. detail: { component, page, pageSize, total }Changing the page size keeps the first visible item in view rather than keeping the page number. Going from page 3 at 25 items per page (item 51) to 50 items per page lands on page 2 (items 51-100), not page 3 (items 101-150). Users read page size as “show me more of what I am looking at.”
One event (qds-page-change) fires for both page and page-size changes. A consumer refetching data needs page and size together, and two events means two fetches. The detail always carries both page and pageSize, whichever changed.
No event fires when a click resolves to the current page, or when page is set programmatically. Programmatic changes are the consumer’s own state, and echoing them back causes update loops.
| Key | Behaviour |
|---|---|
Tab |
Each control is its own tab stop; the number strip is not a single stop |
Enter / Space |
Activates the focused button |
ArrowLeft / ArrowRight |
Moves focus between page buttons without activating |
<qds-pagination
id="pager"
page="1"
page-size="25"
total="1284"
page-size-options="10,25,50,100"
></qds-pagination>
<script>
const pager = document.getElementById('pager');
pager.addEventListener('qds-page-change', (e) => {
console.log('Page:', e.detail.page, 'Size:', e.detail.pageSize);
});
</script>