UNPKG

isu-element

Version:

Polymer components for building web apps.

366 lines (320 loc) 8.53 kB
import {html, PolymerElement} from "@polymer/polymer"; import '@polymer/iron-icon'; import '@polymer/iron-icons'; import './behaviors/isu-elements-shared-styles'; import './isu-select'; /** * `isu-pagination` * * Example: * ```html * <isu-pagination total="30" limit="5" paging="{{paging}}"></isu-pagination> * ``` * @customElement * @polymer * @demo demo/isu-pagination/index.html */ class IsuPagination extends PolymerElement { static get template() { return html` <style include="isu-elements-shared-styles"> :host { display: inline-block; --page_height: 38px; height: var(--page_height); line-height: var(--page_height); font-family: var(--isu-ui-font-family), sans-serif; font-size: var(--isu-ui-font-size); } .pagination { display: flex; margin: 0; padding: 0; list-style: none; height: var(--page_height); line-height: 38px; } li > div { padding: 0 8px; color: var(--isu-ui-color_skyblue); background-color: #fff; border: 1px solid #f0f0f0; border-right: none; line-height: var(--page_height); white-space: nowrap; cursor: pointer; text-decoration: none; user-select: none; } li:first-of-type > div { border-top-left-radius: var(--isu-ui-border-radius); border-bottom-left-radius: var(--isu-ui-border-radius); } li:last-of-type > div { border-top-right-radius: var(--isu-ui-border-radius); border-bottom-right-radius: var(--isu-ui-border-radius); border-right: 1px solid #f0f0f0; } #inner-input { width: 50px; font-size: inherit; padding: var(--isu-ui-border-radius); outline: none; border-radius: 2px; border: 1px solid #6fa5d3; } input[type=number] { -moz-appearance:textfield; } input[type=number]::-webkit-inner-spin-button, input[type=number]::-webkit-outer-spin-button { -webkit-appearance: none; margin: 0; } .size-selector { width: 120px; height: var(--page_height); line-height: var(--page_height); border: 1px solid #f0f0f0; border-top-right-radius: var(--isu-ui-border-radius); border-bottom-right-radius: var(--isu-ui-border-radius); --isu-select__container: { border: none; } --isu-select-tag: { background: #fff; border: none; line-height: 27px; padding: 0; color: var(--isu-ui-color_skyblue); } --isu-select-tag-deleter: { display: none; } --isu-label: { width: 100px; font-size: 12px; } } .page-count { display: inline-block; width: 30px; text-align: center; } :host([size=small]) .pagination > *{ font-size: 12px; padding: 0px; } :host([size=small]) li > div { padding: 0 4px; } :host([size=small]) .size-selector { width: 80px; --isu-select-tag-name: { font-size: 12px; } } :host([size=mini]) .pagination > *{ font-size: 12px; padding: 0px; } :host([size=mini]) li > div { padding: 0 2px; } :host([size=mini]) .size-selector { width: 78px; --isu-select-tag-name: { font-size: 12px; } } :host([size=mini]) #inner-input { width: 30px; } :host([size=mini]) iron-icon { width: 20px; } </style> <ul class="pagination"> <li> <div on-click="first" id="first"><iron-icon icon="icons:first-page"></iron-icon><template is="dom-if" if="[[!isMini(size)]]">第一页</template></div> </li> <li> <div on-click="prev" id="prev"><iron-icon icon="icons:chevron-left"></iron-icon><template is="dom-if" if="[[!isMini(size)]]">上一页</template></div> </li> <li> <div><input id="inner-input" value="{{ __pageIndex::input }}" type="number" maxlength="10" min="1"></div> </li> <li> <div on-click="next" id="next"><template is="dom-if" if="[[!isMini(size)]]">下一页</template><iron-icon icon="icons:chevron-right"></iron-icon></div> </li> <li> <div on-click="last" id="last"><template is="dom-if" if="[[!isMini(size)]]">最后一页</template><iron-icon icon="icons:last-page"></iron-icon></div> </li> <li> <div><div class="page-count">[[ totalPageSize ]]</div>页 [[ total ]] 条</div> </li> <template is="dom-if" if="[[!hidePageSelect]]"> <li> <isu-select class="size-selector" value="{{ __limit }}" items="[[ __pageSize ]]"></isu-select> </li> </template> </ul> `; } static get is() { return "isu-pagination"; } static get properties() { return { /** * Max count of single page. * @type {number} * @default 10 */ limit: { type: Number, observer: '_limitChanged' }, /** * Total count. * @type {number} * @default 0 */ total: { type: Number, value: 0 }, size: { type: String, value: '' }, /** * Total count. * @type {boolean} * @default false */ hideOnSinglePage: { type: Boolean, value: false }, /** * Total page sizes */ totalPageSize: { type: Number, computed: '_calTotalPageSize(total, limit)' }, /** * Whether or not show the page select items */ hidePageSelect: { type: Boolean, value: false }, pageSizes: { type: Array, value: function () { return [20, 40, 60]; } }, __pageIndex: { type: Number, }, start: { type: Number, observer: '_pageStartChanged' }, __pageSize: { type: Array, computed: '__computedPageSize(pageSizes)' }, __limit: { type: String } }; } __computedPageSize(pageSizes = []) { return pageSizes.map(ps => ({value: ps, label: `${ps}条/页`})) } static get observers() { return [ '_pageIndexChanged(__pageIndex)', '__limitChanged(__limit)', '_totalChanged(total)' // '_pageStartChanged(start)', ]; } _pageStartChanged(start, oldStart) { if(start >= 0) { const pageIndex = Math.floor(start / this.limit) + 1; if (pageIndex !== this.__pageIndex) { this.__pageIndex = pageIndex; } // would not dispatch event when at initial phase if (oldStart !== undefined) { this.dispatchEvent(new CustomEvent("start-changed", {detail: {value: start}})); } } } _totalChanged(total) { if (total <=1 && this.hideOnSinglePage) { this.style.display = 'none' } } _pageIndexChanged() { this.start = (this.__pageIndex - 1) * this.limit; } _limitChanged(limit, oldLimit) { const totalPage = Math.floor(this.total / limit) + 1; if (totalPage < this.__pageIndex) { this.__pageIndex = totalPage; } else { this.start = (this.__pageIndex - 1) * limit || 0; } // would not dispatch event when at initial phase if (oldLimit !== undefined) { this.dispatchEvent(new CustomEvent("limit-changed", {detail: {value: limit}})); } this.__limit = limit.toString(); } __limitChanged(limit) { this.limit = parseInt(limit); } _calTotalPageSize(total, limit) { return Math.ceil((total || 0) / limit); } /** * Go to the first page. */ first() { this.__pageIndex = 1; } /** * Go to previous page. */ prev() { if (this.__pageIndex > 1) { this.__pageIndex--; } } /** * Go to next page. */ next() { if (this.__pageIndex < this.totalPageSize) { this.__pageIndex++; } } /** * Go to the last page. */ last() { this.__pageIndex = this.totalPageSize; } isMini(size) { return size === 'mini' } } window.customElements.define(IsuPagination.is, IsuPagination);