@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
JavaScript
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 };