@coreui/vue-pro
Version:
UI Components Library for Vue.js
292 lines (288 loc) • 9.7 kB
JavaScript
var vue = require('vue');
var CPagination = require('../pagination/CPagination.js');
var CPaginationItem = require('../pagination/CPaginationItem.js');
const CSmartPagination = vue.defineComponent({
name: 'CSmartPagination',
props: {
/**
* Horizontall align
*
* @default 'start'
*/
align: {
type: String,
default: 'start',
validator: (value) => {
return ['start', 'center', 'end'].includes(value);
},
},
/**
* Current page number
*
* @default 1
*/
activePage: {
type: Number,
default: 1,
},
/**
* Show/hide arrows
*
* @default true
*/
arrows: {
type: Boolean,
default: true,
},
/**
* Show/hide dots
*
* @default true
*/
dots: {
type: Boolean,
default: true,
},
/**
* Show double arrows buttons
*
* @default true
*/
doubleArrows: {
type: Boolean,
default: true,
},
/**
* The content of 'firstButton' button
*
* @default '«'
*/
firstButton: {
type: String,
default: '«',
},
/**
* The content of 'lastButton' button
*
* @default '»'
*/
lastButton: {
type: String,
default: '»',
},
/**
* Maximum items number
*
* @default 5
*/
limit: {
type: Number,
default: 5,
},
/**
* The content of 'nextButton' button
*
* @default '›'
*/
nextButton: {
type: String,
default: '›',
},
/**
* Number of pages
*/
pages: {
type: Number,
default: 1000,
},
/**
* The content of 'previousButton' button
*
* @default '‹'
*/
previousButton: {
type: String,
default: '‹',
},
/**
* Size of pagination, valid values: 'sm', 'lg'
*/
size: {
type: String,
default: undefined,
required: false,
validator: (value) => {
return ['sm', 'lg'].includes(value);
},
},
},
emits: [
/**
* On active page change callback.
*/
'activePageChange',
],
setup(props, { emit }) {
const activePage = vue.ref(props.activePage);
const limit = vue.ref(props.limit);
const pages = vue.ref(props.pages);
vue.watch(() => props.activePage, () => {
activePage.value = props.activePage;
});
vue.watch(() => props.limit, () => {
limit.value = props.limit;
});
vue.watch(() => props.pages, () => {
pages.value = props.pages;
});
const showDots = vue.computed(() => {
return props.dots && limit.value > 4 && limit.value < pages.value;
});
const maxPrevItems = vue.computed(() => {
return Math.floor((limit.value - 1) / 2);
});
const maxNextItems = vue.computed(() => {
return Math.ceil((limit.value - 1) / 2);
});
const beforeDots = vue.computed(() => {
return showDots.value && activePage.value > maxPrevItems.value + 1;
});
const afterDots = vue.computed(() => {
return showDots.value && activePage.value < pages.value - maxNextItems.value;
});
const computedLimit = vue.computed(() => {
return limit.value - (afterDots.value ? 1 : 0) - (beforeDots.value ? 1 : 0);
});
const range = vue.computed(() => {
return activePage.value + maxNextItems.value;
});
const lastItem = vue.computed(() => {
return range.value >= pages.value ? pages.value : range.value - (afterDots.value ? 1 : 0);
});
const itemsAmount = vue.computed(() => {
return pages.value < computedLimit.value ? pages.value : computedLimit.value;
});
const items = vue.computed(() => {
if (activePage.value - maxPrevItems.value <= 1) {
return Array.from({
length: itemsAmount.value,
}, (_v, i) => i + 1);
}
else {
return Array.from({
length: itemsAmount.value,
}, (_v, i) => {
return lastItem.value - i;
}).reverse();
}
});
const setPage = (number) => {
if (number !== activePage.value) {
activePage.value = number;
emit('activePageChange', number);
}
};
return () => vue.h(CPagination.CPagination, {
align: props.align,
'aria-label': 'pagination',
size: props.size,
}, {
default: () => [
props.doubleArrows &&
vue.h(CPaginationItem.CPaginationItem, {
onClick: () => {
activePage.value !== 1 && setPage(1);
},
'aria-label': 'Go to first page',
...(activePage.value === 1 && {
'aria-disabled': true,
disabled: true,
}),
}, {
default: () => typeof props.firstButton === 'string'
? vue.h('span', {
innerHTML: props.firstButton,
})
: props.firstButton,
}),
props.arrows &&
vue.h(CPaginationItem.CPaginationItem, {
onClick: () => {
activePage.value !== 1 && setPage(activePage.value - 1);
},
'aria-label': 'Go to previous page',
...(activePage.value === 1 && {
'aria-disabled': true,
disabled: true,
}),
}, {
default: () => typeof props.previousButton === 'string'
? vue.h('span', {
innerHTML: props.previousButton,
})
: props.previousButton,
}),
beforeDots.value &&
vue.h(CPaginationItem.CPaginationItem, {
role: 'separator',
disabled: true,
}, {
default: () => '...',
}),
items.value.map((i) => {
return vue.h(CPaginationItem.CPaginationItem, {
onClick: () => setPage(i),
'aria-label': activePage.value === i ? `Current page ${i}` : `Go to page ${i}`,
active: activePage.value === i,
}, {
default: () => i,
});
}),
afterDots.value &&
vue.h(CPaginationItem.CPaginationItem, {
role: 'separator',
disabled: true,
}, {
default: () => '...',
}),
props.arrows &&
vue.h(CPaginationItem.CPaginationItem, {
onClick: () => {
activePage.value !== pages.value && setPage(activePage.value + 1);
},
'aria-label': 'Go to next page',
...(activePage.value === pages.value && {
'aria-disabled': true,
disabled: true,
}),
}, {
default: () => typeof props.nextButton === 'string'
? vue.h('span', {
innerHTML: props.nextButton,
})
: props.nextButton,
}),
props.doubleArrows &&
vue.h(CPaginationItem.CPaginationItem, {
onClick: () => {
activePage.value !== pages.value && setPage(pages.value);
},
'aria-label': 'Go to last page',
...(activePage.value === pages.value && {
'aria-disabled': true,
disabled: true,
}),
}, {
default: () => typeof props.lastButton === 'string'
? vue.h('span', {
innerHTML: props.lastButton,
})
: props.lastButton,
}),
],
});
},
});
exports.CSmartPagination = CSmartPagination;
//# sourceMappingURL=CSmartPagination.js.map
;