@postnord/web-components
Version:
PostNord Web Components
243 lines (237 loc) • 10.6 kB
JavaScript
/*!
* Built with Stencil
* By PostNord.
*/
'use strict';
var index = require('./index-DVv2io0H.js');
var arrow_left = require('./arrow_left-Crkz484c.js');
var arrow_right = require('./arrow_right-CABi9Wkp.js');
var index$1 = require('./index.cjs.js');
const translations = {
PAGINATION: {
sv: 'Paginering',
en: 'Pagination',
da: 'Paginering',
fi: 'Sivunumerointi',
no: 'Paginering',
},
PAGE: {
sv: 'Sida',
en: 'Page',
da: 'Side',
fi: 'Sivu',
no: 'Side',
},
PREVIOUS_PAGE: {
sv: 'Föregående sida',
en: 'Previous page',
da: 'Forrige side',
fi: 'Edellinen sivu',
no: 'Forrige side',
},
NEXT_PAGE: {
sv: 'Nästa sida',
en: 'Next page',
da: 'Næste side',
fi: 'Seuraava sivu',
no: 'Neste side',
},
ROWS_PAGE: {
sv: 'Object per sida',
en: 'Items per page',
da: 'Varer pr. side',
fi: 'Kohteita per sivu',
no: 'Elementer per side',
},
};
const pnPaginationCss = "pn-pagination{display:block;margin-top:1.5em}pn-pagination .pn-pagination{display:flex;gap:1em;flex-wrap:wrap;padding-top:1em;border-top:0.0625em solid #e9e6e5}pn-pagination .pn-pagination-container{display:flex;align-items:center;flex-wrap:wrap;gap:0.5em;margin:0 auto}pn-pagination .pn-pagination-container[data-right]{margin-right:0}pn-pagination .pn-pagination-container>[data-arrow]{display:none}pn-pagination .pn-pagination-container>[data-arrow][data-show]{display:inline-block}pn-pagination .pn-pagination-rows{flex:0 0 auto;margin-right:auto}pn-pagination .pn-pagination-pages{flex:0 0 auto;margin-left:auto}pn-pagination .pn-pagination-list{list-style:none;padding:0;margin:0;display:flex;flex-wrap:wrap;justify-content:center;gap:0.5em}pn-pagination .pn-pagination-list pn-button>.pn-button{padding:0.375em 0.75em}pn-pagination .pn-pagination-dot{display:none;padding:0.375em 0.5em;height:2em;width:2.5em;text-align:center}pn-pagination .pn-pagination-dot[data-show]{display:inline-block}";
const PnPagination = class {
constructor(hostRef) {
index.registerInstance(this, hostRef);
this.pageSelected = index.createEvent(this, "pageSelected");
this.rowsSelected = index.createEvent(this, "rowsSelected");
}
listElement;
get hostElement() { return index.getElement(this); }
list;
/** Set a label for the pagination element for screen readers. It defaults to `Pagination`. */
label;
/** Set a custom URL template. Use `{page}` within the string to position where the dynamic page number should be. */
urlTemplate = '?page={page}';
/** Set a HTML id on the pagination element. */
paginationId = null;
/** Manually set the language. */
language = null;
/**
* Set which page the user is currently viewing.
* Use this to set an inital page or if the selected page is changed from outside this component.
*
* @category Pages
**/
page = 1;
/** Set how many pages are available. @category Pages */
pages;
/** Set how many pages should be visible at one time. Use an odd number. Minimum is `5`. @category Pages */
pagesVisible = 5;
/**
* Allow the user to decide how many items should be shown per page.
* Make sure this value exists in the `rowsList` string.
*
* @see {@link rowsList}
* @category Rows per page
* */
rows = null;
/**
* Set available items per page options the user can select. Use a comma separated string.
*
* @see {@link rows}
* @category Rows per page
* */
rowsList = '10,25,50';
/**
* Default label is "Items per page".
* @see {@link rows}
* @category Rows per page
* */
rowsLabel = null;
handlePage() {
if (this.page > this.pages)
this.page = this.pages;
else if (this.page < 1)
this.page = 1;
}
handlePages() {
const list = [];
if (this.pages > 10000) {
console.error(`${this.hostElement.localName}: Invalid page count ${this.pages}. Maximum is 10000.`);
this.pages = 10000;
}
for (let index = 0; this.pages > index; index++) {
const page = index + 1;
list.push({ index, page });
}
this.list = list;
this.handlePage();
}
handlePagesVisible() {
if (5 > this.pagesVisible)
this.pagesVisible = 5;
if (this.pagesVisible % 2 === 0)
this.pagesVisible = Math.round(this.pagesVisible) - 1;
}
/** Emitted when the page is changed. Either via clicking a link or selecting a page in the select. */
pageSelected;
/** This event fires when the user changes how many items should be shown per page. */
rowsSelected;
async componentWillLoad() {
this.handlePagesVisible();
this.handlePages();
if (this.language === null)
await index$1.awaitTopbar(this.hostElement);
}
translate(prop) {
return translations[prop][this.language || index$1.en];
}
isActivePage(page) {
return page === this.page;
}
navigate({ page, event, focus }) {
if (typeof page === 'number' && page >= 1 && this.pages >= page)
this.page = page;
this.pageSelected.emit({ page: this.page, mouse: event });
if (focus)
requestAnimationFrame(() => {
const element = this.listElement.querySelector('a[aria-current="page"]');
element?.focus({ preventScroll: true });
});
}
useRowList() {
return !!this.rows && !!this.rowsList;
}
setRows(event) {
const target = event.target;
this.rows = Number(target.value);
this.rowsSelected.emit({ rows: this.rows, change: event });
}
getRowList() {
return this.rowsList.split(',').map(item => Number(item.trim()));
}
/** Get the page numbers of the lowest and highest visible page. */
getPaginationIndex() {
const current = this.page;
let low = current - Math.ceil(this.pagesVisible / 2);
let high = current + Math.floor(this.pagesVisible / 2);
for (let i = 0; this.pagesVisible > i; i++) {
if (low < 0) {
high++;
low++;
}
else if (high > this.pages) {
high--;
low--;
}
}
const lowest = 0 > low ? 0 : low;
const leftIndent = lowest >= 1;
const rightIndent = this.pages > high;
return {
low: rightIndent && leftIndent ? lowest + 1 : lowest,
high: rightIndent && leftIndent ? high - 1 : high,
leftIndent,
rightIndent,
};
}
getPagination() {
const { low, high } = this.getPaginationIndex();
return this.list.slice(low, high);
}
getUrl(page) {
return this.setPageText(this.urlTemplate, page);
}
setPageText(text, page) {
return text.replace('{page}', page.toString());
}
getPrevPage() {
let page = this.page;
return page > 1 ? (page -= 1) : 1;
}
getNextPage() {
let page = this.page;
return this.pages > page ? (page += 1) : this.pages;
}
showIntendation(last = false) {
const { leftIndent, rightIndent } = this.getPaginationIndex();
return last ? rightIndent : leftIndent;
}
renderDivider(last = false) {
return (index.h("span", { class: "pn-pagination-dot", "data-show": this.showIntendation(last) }, "..."));
}
renderButton({ page, dataAttr }) {
const active = this.isActivePage(page);
return (index.h("pn-button", { label: page.toString(), arialabel: `${this.translate('PAGE')} ${page}`, ariacurrent: active ? 'page' : null, href: this.getUrl(page), variant: active ? 'outlined' : '', appearance: "light", small: true, "data-arrow": dataAttr, "data-show": dataAttr && this.showIntendation(dataAttr === 'last'), onPnClick: ({ detail }) => this.navigate({ page, event: detail, focus: true }) }));
}
renderItem({ page }) {
return (index.h("li", { class: "pn-pagination-list-item", "aria-setsize": this.pages, "aria-posinset": page }, this.renderButton({ page })));
}
renderJumpButton(last = false) {
const rel = last ? 'next' : 'prev';
const icon = last ? arrow_right.arrow_right : arrow_left.arrow_left;
const page = last ? this.getNextPage() : this.getPrevPage();
const current = last ? this.pages === this.page : 1 === this.page;
const text = last ? 'NEXT_PAGE' : 'PREVIOUS_PAGE';
const showPageNumber = current ? '' : ` (${page})`;
const label = `${this.translate(text)}${showPageNumber}`;
return (index.h("pn-button", { arialabel: label, ariacurrent: current ? 'page' : null, href: this.getUrl(page), rel: current ? null : rel, appearance: "light", small: true, icon: icon, iconOnly: true, onPnClick: ({ detail }) => this.navigate({ page, event: detail }) }));
}
render() {
return (index.h(index.Host, { key: '4ad127b837d974c1e4c67654f211f7779a279506' }, index.h("nav", { key: '2bad34d058a2b8d8db69abcc4c7643299b16d59f', id: this.paginationId, class: "pn-pagination", "aria-label": this.label || this.translate('PAGINATION') }, this.useRowList() && (index.h("pn-select", { key: 'bdcdd583f728cc6e65a712273c503228b65c8f93', class: "pn-pagination-rows", label: this.rowsLabel || this.translate('ROWS_PAGE'), onChange: event => this.setRows(event) }, this.getRowList().map(item => (index.h("option", { value: item, selected: this.rows === Number(item), innerHTML: `${item}` }))))), index.h("div", { key: '84c23f8abad96f9e7f6ec2350b2eb7a0468b0319', class: "pn-pagination-container", "data-right": this.useRowList() }, this.renderJumpButton(), this.renderButton({ page: 1, dataAttr: 'first' }), this.renderDivider(), index.h("ol", { key: 'fb35432d7c31208a92e43f460c861029d5d5e2be', class: "pn-pagination-list", ref: el => (this.listElement = el) }, this.getPagination().map(item => this.renderItem(item))), this.renderDivider(true), this.renderButton({ page: this.pages, dataAttr: 'last' }), this.renderJumpButton(true)))));
}
static get watchers() { return {
"page": ["handlePage"],
"pages": ["handlePages"],
"pagesVisible": ["handlePagesVisible"]
}; }
};
PnPagination.style = pnPaginationCss;
exports.pn_pagination = PnPagination;
//# sourceMappingURL=pn-pagination.entry.cjs.js.map