UNPKG

@coreui/vue-pro

Version:

UI Components Library for Vue.js

292 lines (288 loc) 9.7 kB
'use strict'; 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 '&laquo;' */ firstButton: { type: String, default: '&laquo;', }, /** * The content of 'lastButton' button * * @default '&raquo;' */ lastButton: { type: String, default: '&raquo;', }, /** * Maximum items number * * @default 5 */ limit: { type: Number, default: 5, }, /** * The content of 'nextButton' button * * @default '&rsaquo;' */ nextButton: { type: String, default: '&rsaquo;', }, /** * Number of pages */ pages: { type: Number, default: 1000, }, /** * The content of 'previousButton' button * * @default '&lsaquo;' */ previousButton: { type: String, default: '&lsaquo;', }, /** * 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