UNPKG

@brutforce/vue3-paginate

Version:

<p> <b>Vue3 Paginate</b> is a very simple Pagination component for Vue 3 and TailwindCSS. </p>

421 lines (361 loc) 11.3 kB
import mitt from 'mitt'; import { openBlock, createElementBlock, createElementVNode, normalizeClass, renderSlot, createCommentVNode, Fragment, renderList, toDisplayString, createTextVNode } from 'vue'; const emitter = mitt(); var script$1 = { name: 'Vue3Paginate', props: { maxPages: { type: Number, required: false, default: 3 }, perPage: { type: Number, required: false, default: 5 }, totalPages: { type: Number, required: false, default: 10 }, currentPage: { type: Number, required: false, default: 1 }, showFirstLast: { type: Boolean, default: true }, wrapperClasses: { type: String, required: false, default: 'shadow-md border-1 rounded-lg' }, dotClasses: { type: String, required: false, default: 'px-3 py-auto cursor-not-allowed focus:outline-none focus:ring-2 focus:ring-indigo-300 focus:border-indigo-400' }, activePageClasses: { type: String, required: false, default: 'bg-indigo-500 hover:bg-indigo-600 text-white' }, pageClasses: { type: String, required: false, default: 'px-2 sm:px-4 py-2 focus:outline-none focus:ring-2 focus:ring-indigo-300 focus:border-indigo-400 hover:bg-gray-100' } }, computed: { totalNumPages() { let total = this.totalPages; if (total > this.perPage) { return Math.round(total / this.perPage); } else { return 1; } }, maxVisiblePages() { if (this.totalNumPages > this.maxPages) { return this.maxPages - 1; } else { return this.totalNumPages; } }, startPage() { if (this.theCurrentPage === 1) { return 1; } if (this.theCurrentPage === this.totalNumPages) { let start = this.totalNumPages - this.maxVisiblePages; return start >= 1 ? start : 1; } return this.theCurrentPage > 1 ? this.theCurrentPage - 1 : 1; }, pages() { const range = []; for (let i = this.startPage; i <= Math.min(this.startPage + this.maxVisiblePages, this.totalNumPages); i++) { if (i > 0) { range.push({ number: i, isActive: i === this.theCurrentPage }); } } return range; }, visiblePages() { return null; }, isOnFirstPage() { return this.theCurrentPage === 1; }, isOnLastPage() { return this.theCurrentPage === this.totalNumPages; }, showFirstDots() { return this.theCurrentPage > this.maxVisiblePages ? true : false; }, showLastDots() { return this.totalNumPages - this.theCurrentPage > 5 ? true : false; } }, data() { return { theCurrentPage: this.currentPage }; }, mounted() { emitter.on('btnClicked', this.handleBtnClicked); emitter.emit('gotTotalPages', this.totalNumPages); }, methods: { handleBtnClicked(page) { const previousText = ['prev', 'Prev', 'previous', 'Previos']; if (page === 'first' || page === 'First') { this.onClickFirstPage(); } if (previousText.includes(page)) { this.onClickPreviousPage(); } if (page === 'next' || page === 'Next') { this.onClickNextPage(); } if (page === 'last' || page === 'Last') { this.onClickLastPage(); } }, onClickFirstPage() { let page = 1; this.theCurrentPage = page; this.$emit('input', this.theCurrentPage); emitter.emit('pageChanged', this.theCurrentPage); }, onClickPreviousPage() { let page = this.getPage(this.theCurrentPage - 1); if (page) { page.isActive = true; this.theCurrentPage = page.number; this.$emit('input', this.theCurrentPage); emitter.emit('pageChanged', this.theCurrentPage); } }, onClickPage(page) { this.theCurrentPage = page.number; page.isActive = true; this.$emit('input', this.theCurrentPage); emitter.emit('pageChanged', this.theCurrentPage); }, onClickNextPage() { let page = this.getPage(this.theCurrentPage + 1); if (page) { page.isActive = true; this.theCurrentPage = page.number; this.$emit('input', this.theCurrentPage); emitter.emit('pageChanged', this.theCurrentPage); } }, onClickLastPage() { let page = this.totalNumPages; this.theCurrentPage = page; this.$emit('input', this.theCurrentPage); emitter.emit('pageChanged', this.theCurrentPage); }, getPage(num) { return this.pages.filter(page => page.number == num)[0]; } } }; const _hoisted_1$1 = { class: "z-10 inline-flex" }; const _hoisted_2 = { class: "flex justify-between items-center text-sm" }; const _hoisted_3 = { key: 0, class: "border-r-1" }; const _hoisted_4 = { class: "border-r-1 relative dark:border-gray-850" }; const _hoisted_5 = { key: 1, class: "border-r-1 hidden sm:block" }; const _hoisted_6 = /*#__PURE__*/createElementVNode("span", { class: "inline-block align-middle" }, [/*#__PURE__*/createElementVNode("svg", { xmlns: "http://www.w3.org/2000/svg", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", class: "w-4 h-4" }, [/*#__PURE__*/createElementVNode("path", { "stroke-linecap": "round", "stroke-linejoin": "round", "stroke-width": "2", d: "M5 12h.01M12 12h.01M19 12h.01M6 12a1 1 0 11-2 0 1 1 0 012 0zm7 0a1 1 0 11-2 0 1 1 0 012 0zm7 0a1 1 0 11-2 0 1 1 0 012 0z" })])], -1); const _hoisted_7 = [_hoisted_6]; const _hoisted_8 = ["onClick", "disabled"]; const _hoisted_9 = { key: 2, class: "border-r-1 hidden sm:block" }; const _hoisted_10 = /*#__PURE__*/createElementVNode("span", { class: "inline-block align-middle" }, [/*#__PURE__*/createElementVNode("svg", { xmlns: "http://www.w3.org/2000/svg", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", class: "w-4 h-4" }, [/*#__PURE__*/createElementVNode("path", { "stroke-linecap": "round", "stroke-linejoin": "round", "stroke-width": "2", d: "M5 12h.01M12 12h.01M19 12h.01M6 12a1 1 0 11-2 0 1 1 0 012 0zm7 0a1 1 0 11-2 0 1 1 0 012 0zm7 0a1 1 0 11-2 0 1 1 0 012 0z" })])], -1); const _hoisted_11 = [_hoisted_10]; const _hoisted_12 = { class: "relative" }; const _hoisted_13 = { key: 3, class: "border-l-1" }; function render$1(_ctx, _cache, $props, $setup, $data, $options) { return openBlock(), createElementBlock("div", _hoisted_1$1, [createElementVNode("nav", { class: normalizeClass(["", $props.wrapperClasses]), "aria-label": "Pagination" }, [createElementVNode("ul", _hoisted_2, [$props.showFirstLast ? (openBlock(), createElementBlock("li", _hoisted_3, [renderSlot(_ctx.$slots, "first")])) : createCommentVNode("", true), createElementVNode("li", _hoisted_4, [renderSlot(_ctx.$slots, "prev")]), $options.showFirstDots ? (openBlock(), createElementBlock("li", _hoisted_5, [createElementVNode("button", { type: "button", class: normalizeClass(["", $props.dotClasses]), disabled: true }, _hoisted_7, 2)])) : createCommentVNode("", true), (openBlock(true), createElementBlock(Fragment, null, renderList($options.pages, page => { return openBlock(), createElementBlock("li", { class: "border-r-1", key: page.number }, [createElementVNode("button", { onClick: $event => $options.onClickPage(page), type: "button", class: normalizeClass(["", [$props.pageClasses, page.isActive ? `${$props.activePageClasses}` : '']]), disabled: page.isActive }, toDisplayString(page.number), 11, _hoisted_8)]); }), 128)), $options.showLastDots ? (openBlock(), createElementBlock("li", _hoisted_9, [createElementVNode("button", { type: "button", class: normalizeClass($props.dotClasses), disabled: true }, _hoisted_11, 2)])) : createCommentVNode("", true), createElementVNode("li", _hoisted_12, [renderSlot(_ctx.$slots, "next")]), $props.showFirstLast ? (openBlock(), createElementBlock("li", _hoisted_13, [renderSlot(_ctx.$slots, "last")])) : createCommentVNode("", true)])], 2)]); } script$1.render = render$1; var script = { name: 'NavButton', props: { text: { type: String, required: false }, page: { type: [String, Number], required: true }, isFirst: { type: Boolean, required: false, default: false }, isPrev: { type: Boolean, required: false, default: false }, isNext: { type: Boolean, required: false, default: false }, isLast: { type: Boolean, required: false, default: false } }, data() { return { shouldDisable: true, totalPages: 0, currentPage: null }; }, mounted() { emitter.on('pageChanged', this.handlePageChange); emitter.on('gotTotalPages', this.setTotalPages); this.initShouldDisable(); }, methods: { setTotalPages(total) { this.totalPages = total; }, handleClick() { emitter.emit('btnClicked', this.page); }, handlePageChange(page) { const first = ['first', 'First']; const previous = ['prev', 'Prev', 'previous', 'Previous']; const next = ['next', 'Next']; const last = ['last', 'Last']; if (first.includes(this.page) && page == 1 || this.isFirst && page == 1) { return this.shouldDisable = true; } if (previous.includes(this.page) && page == 1 || this.isPrev && page == 1) { return this.shouldDisable = true; } if (next.includes(this.page) && page / this.totalPages == 1 || this.isNext && page / this.totalPages == 1) { return this.shouldDisable = true; } if (last.includes(this.page) && page / this.totalPages == 1 || this.isLast && page / this.totalPages == 1) { return this.shouldDisable = true; } if (page == this.page) { return this.shouldDisable = true; } return this.shouldDisable = false; }, initShouldDisable() { this.handlePageChange(1); } } }; const _hoisted_1 = ["disabled"]; function render(_ctx, _cache, $props, $setup, $data, $options) { return openBlock(), createElementBlock("button", { onClick: _cache[0] || (_cache[0] = function () { return $options.handleClick && $options.handleClick(...arguments); }), disabled: $data.shouldDisable, class: normalizeClass({ 'cursor-not-allowed': $data.shouldDisable }), type: "button" }, [renderSlot(_ctx.$slots, "default", {}, () => [createTextVNode(toDisplayString($props.text), 1)])], 10, _hoisted_1); } script.render = render; /* eslint-disable import/prefer-default-export */ var components = /*#__PURE__*/Object.freeze({ __proto__: null, Paginate: script$1, NavButton: script }); // Import vue components const install = function installVue3Paginate(app) { Object.entries(components).forEach(_ref => { let [componentName, component] = _ref; app.component(componentName, component); }); }; // Create module definition for Vue.use() export { script as NavButton, script$1 as Paginate, install as default };