UNPKG

@dialpad/dialtone

Version:

Dialpad's Dialtone design system monorepo

231 lines (230 loc) 7.21 kB
"use strict"; Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toStringTag]: { value: "Module" } }); const vue3 = require("@dialpad/dialtone-icons/vue3"); const vue = require("vue"); const _pluginVue_exportHelper = require("../../_virtual/_plugin-vue_export-helper.cjs"); const button = require("../button/button.vue.cjs"); const _sfc_main = { compatConfig: { MODE: 3 }, name: "DtPagination", components: { DtButton: button.default, DtIconChevronLeft: vue3.DtIconChevronLeft, DtIconChevronRight: vue3.DtIconChevronRight, DtIconMoreHorizontal: vue3.DtIconMoreHorizontal }, props: { /** * Descriptive label for the pagination content. */ ariaLabel: { type: String, required: true }, /** * The total number of the pages */ totalPages: { type: Number, required: true }, /** * Descriptive label for the previous button. */ prevAriaLabel: { type: String, required: true }, /** * Descriptive label for the next button. */ nextAriaLabel: { type: String, required: true }, /** * A method that will be called to get the aria label of each page. */ pageNumberAriaLabel: { type: Function, required: true }, /** * The active current page in the list of pages, defaults to the first page */ activePage: { type: Number, default: 1 }, /** * Determines the max pages to be shown in the list. Using an odd number is recommended. * If an even number is given, then it will be rounded down to the nearest odd number to always * keep current page in the middle when current page is in the mid-range. */ maxVisible: { type: Number, default: 5 }, /** * Sometimes you may need to hide start and end page number buttons when moving in between. * This prop will be used to hide the first and last page buttons when not near the edges. * This is useful when your backend does not support offset and you can only use cursor based pagination. */ hideEdges: { type: Boolean, default: false } }, emits: [ /** * Page change event * * @event change * @type {Number} */ "change" ], data() { return { currentPage: this.activePage }; }, computed: { isFirstPage() { return this.currentPage === 1; }, isLastPage() { return this.currentPage === this.totalPages; }, pages() { if (this.maxVisible === 0) { return []; } if (this.totalPages <= this.maxVisible) { return this.range(1, this.totalPages); } let start = this.maxVisible - 1; let end = this.totalPages - start + 1; if (this.hideEdges) { start = start + 1; end = end - 1; } if (this.currentPage < start) { const pages2 = [...this.range(1, start), "..."]; if (!this.hideEdges) { pages2.push(this.totalPages); } return pages2; } if (this.currentPage > end) { const pages2 = ["...", ...this.range(end, this.totalPages)]; if (!this.hideEdges) { pages2.unshift(1); } return pages2; } const total = this.maxVisible - (3 - this.maxVisible % 2); const centerIndex = Math.floor(total / 2); let left = this.currentPage - centerIndex; let right = this.currentPage + centerIndex; if (this.hideEdges) { left = left - 1; right = right + 1; } const pages = ["...", ...this.range(left, right), "..."]; if (!this.hideEdges) { return [1, ...pages, this.totalPages]; } return pages; } }, watch: { activePage() { this.currentPage = this.activePage; } }, methods: { range(from, to) { const range = []; from = from > 0 ? from : 1; for (let i = from; i <= to; i++) { range.push(i); } return range; }, changePage(page) { this.currentPage = page; this.$emit("change", this.currentPage); } } }; const _hoisted_1 = ["aria-label"]; const _hoisted_2 = { key: 0, class: "d-pagination__separator-icon", "data-qa": "dt-pagination-separator" }; function _sfc_render(_ctx, _cache, $props, $setup, $data, $options) { const _component_dt_icon_chevron_left = vue.resolveComponent("dt-icon-chevron-left"); const _component_dt_button = vue.resolveComponent("dt-button"); const _component_dt_icon_more_horizontal = vue.resolveComponent("dt-icon-more-horizontal"); const _component_dt_icon_chevron_right = vue.resolveComponent("dt-icon-chevron-right"); return vue.openBlock(), vue.createElementBlock("nav", { "aria-label": $props.ariaLabel, class: "d-pagination" }, [ vue.createVNode(_component_dt_button, { class: "d-pagination__button", "data-qa": "dt-pagination-prev", "aria-label": $props.prevAriaLabel, kind: "muted", importance: "clear", disabled: $options.isFirstPage, onClick: _cache[0] || (_cache[0] = ($event) => $options.changePage($data.currentPage - 1)) }, { icon: vue.withCtx(() => [ vue.createVNode(_component_dt_icon_chevron_left, { size: "300" }) ]), _: 1 }, 8, ["aria-label", "disabled"]), (vue.openBlock(true), vue.createElementBlock(vue.Fragment, null, vue.renderList($options.pages, (page, index) => { return vue.openBlock(), vue.createElementBlock("div", { key: `page-${page}-${index}`, class: vue.normalizeClass({ "d-pagination__separator": isNaN(Number(page)) }) }, [ isNaN(Number(page)) ? (vue.openBlock(), vue.createElementBlock("div", _hoisted_2, [ vue.createVNode(_component_dt_icon_more_horizontal, { size: "300" }) ])) : (vue.openBlock(), vue.createBlock(_component_dt_button, { key: 1, "aria-label": $props.pageNumberAriaLabel(page), kind: $data.currentPage === page ? "default" : "muted", importance: $data.currentPage === page ? "primary" : "clear", "label-class": "", onClick: ($event) => $options.changePage(page) }, { default: vue.withCtx(() => [ vue.createTextVNode(vue.toDisplayString(page), 1) ]), _: 2 }, 1032, ["aria-label", "kind", "importance", "onClick"])) ], 2); }), 128)), vue.createVNode(_component_dt_button, { class: "d-pagination__button", "data-qa": "dt-pagination-next", "aria-label": $props.nextAriaLabel, disabled: $options.isLastPage, kind: "muted", importance: "clear", onClick: _cache[1] || (_cache[1] = ($event) => $options.changePage($data.currentPage + 1)) }, { icon: vue.withCtx(() => [ vue.createVNode(_component_dt_icon_chevron_right, { size: "300" }) ]), _: 1 }, 8, ["aria-label", "disabled"]) ], 8, _hoisted_1); } const pagination = /* @__PURE__ */ _pluginVue_exportHelper.default(_sfc_main, [["render", _sfc_render]]); exports.default = pagination; //# sourceMappingURL=pagination.vue.cjs.map