@coreui/vue-pro
Version:
UI Components Library for Vue.js
290 lines (287 loc) • 9.47 kB
JavaScript
import { defineComponent, ref, watch, computed, h } from 'vue';
import { CPagination } from '../pagination/CPagination.js';
import { CPaginationItem } from '../pagination/CPaginationItem.js';
const CSmartPagination = 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 = ref(props.activePage);
const limit = ref(props.limit);
const pages = ref(props.pages);
watch(() => props.activePage, () => {
activePage.value = props.activePage;
});
watch(() => props.limit, () => {
limit.value = props.limit;
});
watch(() => props.pages, () => {
pages.value = props.pages;
});
const showDots = computed(() => {
return props.dots && limit.value > 4 && limit.value < pages.value;
});
const maxPrevItems = computed(() => {
return Math.floor((limit.value - 1) / 2);
});
const maxNextItems = computed(() => {
return Math.ceil((limit.value - 1) / 2);
});
const beforeDots = computed(() => {
return showDots.value && activePage.value > maxPrevItems.value + 1;
});
const afterDots = computed(() => {
return showDots.value && activePage.value < pages.value - maxNextItems.value;
});
const computedLimit = computed(() => {
return limit.value - (afterDots.value ? 1 : 0) - (beforeDots.value ? 1 : 0);
});
const range = computed(() => {
return activePage.value + maxNextItems.value;
});
const lastItem = computed(() => {
return range.value >= pages.value ? pages.value : range.value - (afterDots.value ? 1 : 0);
});
const itemsAmount = computed(() => {
return pages.value < computedLimit.value ? pages.value : computedLimit.value;
});
const items = 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 () => h(CPagination, {
align: props.align,
'aria-label': 'pagination',
size: props.size,
}, {
default: () => [
props.doubleArrows &&
h(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'
? h('span', {
innerHTML: props.firstButton,
})
: props.firstButton,
}),
props.arrows &&
h(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'
? h('span', {
innerHTML: props.previousButton,
})
: props.previousButton,
}),
beforeDots.value &&
h(CPaginationItem, {
role: 'separator',
disabled: true,
}, {
default: () => '...',
}),
items.value.map((i) => {
return h(CPaginationItem, {
onClick: () => setPage(i),
'aria-label': activePage.value === i ? `Current page ${i}` : `Go to page ${i}`,
active: activePage.value === i,
}, {
default: () => i,
});
}),
afterDots.value &&
h(CPaginationItem, {
role: 'separator',
disabled: true,
}, {
default: () => '...',
}),
props.arrows &&
h(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'
? h('span', {
innerHTML: props.nextButton,
})
: props.nextButton,
}),
props.doubleArrows &&
h(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'
? h('span', {
innerHTML: props.lastButton,
})
: props.lastButton,
}),
],
});
},
});
export { CSmartPagination };
//# sourceMappingURL=CSmartPagination.js.map