Permalink
Browse files

perf(pagination+pagination-nav): convert templates to render function (

…#1348)

* perf(pagination-nav): convert template to render function

* [pagination mixn] create common render function

* [pagination] Use mixin render function

* [pagination-nav] use mixin render function
  • Loading branch information...
tmorehouse committed Nov 15, 2017
1 parent 9d0ae3e commit e04291f0aac2014059b27e09e1c1bb9ab825f70c
Showing with 208 additions and 260 deletions.
  1. +20 −125 src/components/pagination-nav/pagination-nav.vue
  2. +21 −134 src/components/pagination/pagination.vue
  3. +167 −1 src/mixins/pagination.js
@@ -1,133 +1,22 @@
<template>
<nav>
<ul :class="['pagination',btnSize,alignment]"
:aria-disabled="disabled ? 'true' : 'false'"
:aria-label="ariaLabel ? ariaLabel : null"
role="menubar"
tabindex="0"
@keydown.left.prevent="focusPrev"
@keydown.right.prevent="focusNext"
@keydown.shift.left.prevent="focusFirst"
@keydown.shift.right.prevent="focusLast"
>
<!-- Goto First Page button -->
<template v-if="!hideGotoEndButtons">
<li v-if="isActive(1) || disabled" class="page-item disabled" role="none presentation" aria-hidden="true">
<span class="page-link" v-html="firstText"></span>
</li>
<li v-else class="page-item" role="none presentation">
<b-link class="page-link"
v-bind="linkProps(1)"
:aria-label="labelFirstPage"
role="menuitem"
tabindex="-1"
@click="onClick(1)"
><span aria-hidden="true" v-html="firstText"></span></b-link>
</li>
</template>
<!-- Goto Previous page button -->
<li v-if="isActive(1) || disabled" class="page-item disabled" role="none presentation" aria-hidden="true">
<span class="page-link" v-html="prevText"></span>
</li>
<li v-else class="page-item" role="none presentation">
<b-link class="page-link"
v-bind="linkProps(currentPage - 1)"
:aria-label="labelPrevPage"
role="menuitem"
tabindex="-1"
@click="onClick(currentPage - 1)"
><span aria-hidden="true" v-html="prevText"></span></b-link>
</li>
<!-- First Ellipsis Bookend -->
<li v-if="showFirstDots" class="page-item disabled d-none d-sm-flex" role="separator">
<span class="page-link" v-html="ellipsisText"></span>
</li>
<!-- Pages links -->
<li v-for="page in pageList" role="none presentation" :class="pageItemClasses(page)" :key="page.number">
<span v-if="disabled" class="page-link">{{ page.number }}</span>
<b-link v-else
v-bind="linkProps(page.number)"
:class="pageLinkClasses(page)"
:disabled="disabled"
:aria-disabled="disabled ? 'true' : null"
:aria-label="labelPage + ' ' + page.number"
:aria-checked="isActive(page.number) ? 'true' : 'false'"
:aria-posinset="page.number"
:aria-setsize="numberOfPages"
role="menuitemradio"
:tabindex="isActive(page.number) ? '0' : '-1'"
@click="onClick(page.number)"
v-html="makePage(page.number)"
></b-link>
</li>
<!-- Last Ellipsis Bookend -->
<li v-if="showLastDots" class="page-item disabled d-none d-sm-flex" role="separator">
<span class="page-link" v-html="ellipsisText"></span>
</li>
<!-- Goto Next page -->
<li v-if="isActive(numberOfPages) || disabled" class="page-item disabled" role="none presentation" aria-hidden="true">
<span class="page-link" v-html="nextText"></span>
</li>
<li v-else class="page-item" role="none presentation">
<b-link class="page-link"
v-bind="linkProps(currentPage + 1)"
:aria-label="labelNextPage"
role="menuitem"
tabindex="-1"
@click="onClick(currentPage + 1)"
><span aria-hidden="true" v-html="nextText"></span></b-link>
</li>
<!-- Goto Last page -->
<template v-if="!hideGotoEndButtons">
<li v-if="isActive(numberOfPages) || disabled"
class="page-item disabled"
role="none presentation"
aria-hidden="true"
>
<span class="page-link" v-html="lastText"></span>
</li>
<li v-else class="page-item" role="none presentation">
<b-link class="page-link"
v-bind="linkProps(numberOfPages)"
:aria-label="labelLastPage"
role="menuitem"
tabindex="-1"
@click="onClick(numberOfPages)"
><span aria-hidden="true" v-html="lastText"></span></b-link>
</li>
</template>
</ul>
</nav>
</template>
<style scoped>
.page-item {
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
<style>
.b-pagination .page-item {
user-select: none;
}
.page-item.disabled {
.b-pagination .page-item.disabled {
cursor: not-allowed;
opacity: .65;
}
.page-item .page-link.active:focus {
.b-pagination .page-item .page-link.active:focus {
box-shadow: 0 0 0 3px rgba(0,123,255,.5);
z-index: 1;
}
</style>
<script>
import bLink, { pickLinkProps } from '../link/link';
import { assign } from '../../utils/object';
import { KeyCodes } from '../../utils';
import { paginationMixin } from '../../mixins';
import { pickLinkProps } from '../link/link';
// Props needed for router links
const routerProps = pickLinkProps('activeClass','exactActiveClass','append','exact','replace','target','rel');
@@ -161,27 +50,33 @@ const props = assign(
routerProps
);
// Our render function is brought in via the pagination mixin
export default {
components: { bLink },
mixins: [ paginationMixin ],
props,
computed: {
// Used by render function to trigger wraping in '<nav>' element
isNav() {
return true;
}
},
methods: {
onClick(pageNum) {
onClick(pageNum, evt) {
this.currentPage = pageNum;
},
makePage(pagenum) {
if (this.pageGen && typeof this.pageGen === 'function') {
return this.pageGen(pagenum);
}
return pagenum;
},
makeLink(pagenum) {
if (this.linkGen && typeof this.linkGen === 'function') {
return this.linkGen(pagenum);
}
const link = `${this.baseUrl}${pagenum}`;
return this.useRouter ? { path: link } : link;
},
makePage(pagenum) {
if (this.pageGen && typeof this.pageGen === 'function') {
return this.pageGen(pagenum);
}
return pagenum;
},
linkProps(pagenum) {
const link = this.makeLink(pagenum);
let props = {
@@ -1,133 +1,15 @@
<template>
<ul :class="['pagination',btnSize,alignment]"
:aria-disabled="disabled ? 'true' : 'false'"
:aria-label="ariaLabel ? ariaLabel : null"
role="menubar"
@keydown.left.prevent="focusPrev"
@keydown.right.prevent="focusNext"
@keydown.shift.left.prevent="focusFirst"
@keydown.shift.right.prevent="focusLast"
>
<!-- Goto First Page button -->
<template v-if="!hideGotoEndButtons">
<li v-if="isActive(1) || disabled" class="page-item disabled" role="none presentation" aria-hidden="true">
<span class="page-link" v-html="firstText"></span>
</li>
<li v-else class="page-item" role="none presentation">
<a class="page-link"
:aria-label="labelFirstPage"
:aria-controls="ariaControls || null"
role="menuitem"
href="#"
tabindex="-1"
@click.prevent="setPage($event, 1)"
@keydown.enter.prevent="setPage($event, 1)"
@keydown.space.prevent="setPage($event, 1)"
><span aria-hidden="true" v-html="firstText"></span></a>
</li>
</template>
<!-- Goto Previous page button -->
<li v-if="isActive(1) || disabled" class="page-item disabled" role="none presentation" aria-hidden="true">
<span class="page-link" v-html="prevText"></span>
</li>
<li v-else class="page-item" role="none presentation">
<a class="page-link"
:aria-label="labelPrevPage"
:aria-controls="ariaControls || null"
role="menuitem"
href="#"
tabindex="-1"
@click.prevent="setPage($event, currentPage - 1)"
@keydown.enter.prevent="setPage($event, currentPage - 1)"
@keydown.space.prevent="setPage($event, currentPage - 1)"
><span aria-hidden="true" v-html="prevText"></span></a>
</li>
<!-- First Ellipsis Bookend -->
<li v-if="showFirstDots" class="page-item disabled d-none d-sm-flex" role="separator">
<span class="page-link" v-html="ellipsisText"></span>
</li>
<!-- Pages links -->
<li v-for="page in pageList" role="none presentation" :class="pageItemClasses(page)" :key="page.number">
<a :class="pageLinkClasses(page)"
:disabled="disabled"
:aria-disabled="disabled ? 'true' : null"
:aria-label="labelPage + ' ' + page.number"
:aria-checked="isActive(page.number) ? 'true' : 'false'"
:aria-controls="ariaControls || null"
:aria-posinset="page.number"
:aria-setsize="numberOfPages"
role="menuitemradio"
href="#"
:tabindex="isActive(page.number) ? '0' : '-1'"
@click.prevent="setPage($event, page.number)"
@keydown.enter.prevent="setPage($event, page.number)"
@keydown.space.prevent="setPage($event, page.number)"
>{{ page.number }}</a>
</li>
<!-- Last Ellipsis Bookend -->
<li v-if="showLastDots" class="page-item disabled d-none d-sm-flex" role="separator">
<span class="page-link" v-html="ellipsisText"></span>
</li>
<!-- Goto Next page -->
<li v-if="isActive(numberOfPages) || disabled" class="page-item disabled" role="none presentation" aria-hidden="true">
<span class="page-link" v-html="nextText"></span>
</li>
<li v-else class="page-item" role="none presentation">
<a class="page-link"
:aria-label="labelNextPage"
:aria-controls="ariaControls || null"
role="menuitem"
href="#"
tabindex="-1"
@click.prevent="setPage($event, currentPage + 1)"
@keydown.enter.prevent="setPage($event, currentPage + 1)"
@keydown.space.prevent="setPage($event, currentPage + 1)"
><span aria-hidden="true" v-html="nextText"></span></a>
</li>
<!-- Goto Last page -->
<template v-if="!hideGotoEndButtons">
<li v-if="isActive(numberOfPages) || disabled"
class="page-item disabled"
role="none presentation"
aria-hidden="true"
>
<span class="page-link" v-html="lastText"></span>
</li>
<li v-else class="page-item" role="none presentation">
<a class="page-link"
:aria-label="labelLastPage"
:aria-controls="ariaControls || null"
role="menuitem"
href="#"
tabindex="-1"
@click.prevent="setPage($event, numberOfPages)"
@keydown.enter.prevent="setPage($event, numberOfPages)"
@keydown.space.prevent="setPage($event, numberOfPages)"
><span aria-hidden="true" v-html="lastText"></span></a>
</li>
</template>
</ul>
</template>
<style scoped>
.page-item {
<style>
.b-pagination .page-item {
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
}
.page-item.disabled {
.b-pagination .page-item.disabled {
cursor: not-allowed;
opacity: .65;
}
.page-item .page-link.active:focus {
.b-pagination .page-item .page-link.active:focus {
box-shadow: 0 0 0 3px rgba(0,123,255,.5);
z-index: 1;
}
@@ -136,6 +18,7 @@
<script>
import { paginationMixin } from '../../mixins';
import { isVisible } from '../../utils/dom';
import { KeyCodes } from '../../utils';
const props = {
perPage: {
@@ -152,6 +35,7 @@ const props = {
}
};
// Our render function is brought in from the pagination mixin
export default {
mixins: [ paginationMixin ],
props,
@@ -162,28 +46,31 @@ export default {
}
},
methods: {
setPage(e, num) {
if (this.disabled) {
e.preventDefault();
e.stopPropagation();
return;
}
// These methods are used by the render function
onClick(num, evt) {
// Handle edge cases where number of pages has changed (i.e. if perPage changes)
if (num > this.numberOfPages) {
this.currentPage = this.numberOfPages;
num = this.numberOfPages;
} else if (num < 1) {
this.currentpage = 1;
} else {
this.currentPage = num;
num = 1;
}
this.currentPage = num;
this.$nextTick(() => {
// Keep the current button focused if possible
if (isVisible(e.target) && e.target.focus) {
e.target.focus();
const target = evt.target;
if (isVisible(target) && this.$el.contains(target) && target.focus) {
target.focus();
} else {
this.focusCurrent();
}
});
this.$emit('change', this.currentPage);
},
makePage(pagenum) {
return pagenum;
},
linkProps(pagenum) {
return { href: '#' };
}
}
};
Oops, something went wrong.

0 comments on commit e04291f

Please sign in to comment.