UNPKG

@postnord/web-components

Version:
243 lines (237 loc) 10.6 kB
/*! * 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