<bmx-pagination>
Which page of a long list you are looking at, and how to get to another one.
17 properties · 1 events · 3 methods · 11 parts
Example
Page through 813 records. Watch the width of the control as you go: it does not change, so the button under your pointer stays where it was.
The same control on a narrow screen, where a row of numbers has nowhere to go:
Show markup
<div class="row">
<p style="margin: 0">
Page through 813 records. Watch the width of the control as you go: it does not change, so the button under your
pointer stays where it was.
</p>
</div>
<div class="row">
<bmx-pagination
id="ex-pagination"
total-items="813"
page-size="20"
page="1"
show-edges
show-summary
page-sizes="10,20,50,100"
></bmx-pagination>
</div>
<div class="row">
<span class="note" id="ex-pagination-out">Showing rows 1–20 of 813.</span>
</div>
<div class="row" style="margin-block-start: 1rem">
<p style="margin: 0">The same control on a narrow screen, where a row of numbers has nowhere to go:</p>
</div>
<div class="row">
<bmx-pagination total-items="813" page-size="20" page="7" compact show-edges></bmx-pagination>
</div>
<script type="module">
await customElements.whenDefined('bmx-pagination');
const out = document.getElementById('ex-pagination-out');
/*
* The event carries the row numbers as well as the page, because that is what
* a query needs - `OFFSET 40 LIMIT 20` rather than "page 3". The component
* fetches nothing itself: what a page *is* belongs to the data layer, which
* knows about the API and the cache and this component never will.
*/
document.getElementById('ex-pagination').addEventListener('bmxChange', event => {
const { page, firstItem, lastItem, pageSize, reason } = event.detail;
out.textContent =
reason === 'size'
? `Now ${pageSize} per page — rows ${firstItem}–${lastItem}, on page ${page}.`
: `Showing rows ${firstItem}–${lastItem} of 813.`;
});
</script>
<bmx-pagination total-items="813" page-size="20" page="1"></bmx-pagination>
THE ONE COMPONENT HERE THAT IS GIVEN A NUMBER RATHER THAN A LIST
Everything else in this library is handed the things it draws. This one is
handed a count, works out the rest, and its whole behaviour is therefore
arithmetic: which page numbers to show, where the ellipses go, what a key
press does, which page you land on when the page size changes. All of it is
src/core/pagination.ts, tested without a browser, and the two rules worth
knowing are there:
- The control never changes width as you page through it. The naive window - the current page, some siblings, an ellipsis at each jump - is four items on page 1 and seven in the middle, so every button moves under the pointer as you use it. Here the width is fixed and the window slides.
- An ellipsis never stands for a single page.
1 … 3 4 5replaces "2" with a wider symbol offering a jump nobody can take, so the page is drawn instead. It is free: the slot was reserved either way.
WHAT IT DOES NOT DO
It does not fetch anything and it does not slice anything. It tells you which
page was asked for; what a page is belongs to your data layer, which knows
about your API and your cache and this component never will. Give it page
back and it will draw what you decided.
Properties
| Property | Attribute | Type | Default | Description |
|---|---|---|---|---|
boundaries |
boundaries |
number |
1 |
How many pages to pin at each end. |
compact |
compact |
boolean |
false |
Draw only the previous and next buttons, with the page as text between. What a narrow screen wants. It is a property rather than a media query because the component cannot know how much room the page has given it - a container query in the consumer's stylesheet can set it, and often should. |
disabled |
disabled |
boolean |
false |
Nothing can be pressed. The current page is still readable. |
firstLabel |
first-label |
string |
'First page' |
The labels on the four movement buttons, and on the size control. |
label |
label |
string |
'Pagination' |
The navigation landmark's accessible name. |
lastLabel |
last-label |
string |
'Last page' |
|
nextLabel |
next-label |
string |
'Next page' |
|
page |
page |
number |
1 |
The page being looked at, counting from 1. |
pageSize |
page-size |
number |
20 |
How many rows a page holds. |
pageSizes |
page-sizes |
number[] | string |
[] |
The page sizes a reader may choose between. An empty list - the default - draws no size control at all. Given some, the control appears, and changing it keeps the row you are looking at on screen rather than the page number: at twenty per page, page 4 is rows 61 to 80, and at fifty per page those rows are on page 2. Landing on page 4 of the new pagination would show rows 151 to 200, which you have never seen. Accepts a comma-separated or JSON string as well, because an attribute is the only channel some templates have. See src/core/markup.ts. |
pages |
pages |
number |
— | How many pages there are. Set this when your API tells you a page count and nothing else. When totalItems is given, that wins - it is the more precise fact, and it is what the summary and the page-size control need. |
previousLabel |
previous-label |
string |
'Previous page' |
|
showEdges |
show-edges |
boolean |
false |
Whether to draw the jump-to-first and jump-to-last buttons. |
showSummary |
show-summary |
boolean |
false |
Whether to draw the "21-40 of 813" summary. Needs totalItems. |
siblings |
siblings |
number |
1 |
How many pages to show either side of the current one. |
sizeLabel |
size-label |
string |
'Rows per page' |
|
totalItems |
total-items |
number |
— | How many rows there are altogether. |
Events
| Event | Detail | Description |
|---|---|---|
bmxChange |
BmxPaginationChangeDetail |
Fired when the reader asks for a different page, or a different page size. |
Methods
| Method | Signature | Description |
|---|---|---|
goTo |
goTo(page: number) => Promise<void> |
Go to a page. Clamped, and silent if it is the page already showing. |
next |
next() => Promise<void> |
Go forward one page, if there is one. |
previous |
previous() => Promise<void> |
Go back one page, if there is one. |
CSS shadow parts
| Part | Description |
|---|---|
base |
The <nav>. |
current |
The page button for the page you are on. Carries part="page" as well. |
first |
The button that jumps to page one. |
gap |
An ellipsis. |
last |
The button that jumps to the final page. |
list |
The row of controls. |
next |
The button that goes forward one page. |
page |
One page button. |
previous |
The button that goes back one page. |
size |
The rows-per-page control. |
summary |
The "21-40 of 813" text. |
CSS custom properties
| Property | Description |
|---|---|
--bmx-pagination-background-hover |
A button's background under the pointer. |
--bmx-pagination-border-color |
The border on a page button. |
--bmx-pagination-color |
A page number's colour. |
--bmx-pagination-current-background |
The background behind it. |
--bmx-pagination-current-color |
The colour of the page you are on. |
--bmx-pagination-gap |
Space between one control and the next. |
--bmx-pagination-radius |
A button's corner radius. |
--bmx-pagination-size |
The height and minimum width of a page button. |
--bmx-pagination-summary-color |
The "21-40 of 813" text. |