UNPKG

isu-elements

Version:

Polymer components for building web apps.

420 lines (375 loc) 10.4 kB
import { html, PolymerElement } from '@polymer/polymer' import '@webcomponents/shadycss/entrypoints/apply-shim.js' import '@polymer/iron-icon' import '@polymer/iron-icons' import './behaviors/isu-elements-shared-styles' import './isu-select' /** * `isu-pagination` * * Example: * ```html * <isu-pagination total="5000" start="0" limit="20"></isu-pagination> * <isu-pagination total="50" page-sizes='[10,20,30]' start="0" limit="10"></isu-pagination> * <isu-pagination id="page2" total="5000" start="0" limit="20" size="small"></isu-pagination> * <isu-pagination id="page3" total="5000" start="0" limit="20" size="mini" hide-page-select></isu-pagination> * <isu-pagination id="pageSingle2" total="1" start="0" limit="20" hide-on-single-page></isu-pagination> * <isu-pagination id="pageSelect" total="5000" start="0" limit="20" hide-page-select></isu-pagination> * * ``` * * ### Styling * * `<isu-button>` provides the following custom properties and mixins * for styling: * * Custom property | Description | Default * ----------------|-------------|---------- * * `--isu-pagination` | Mixin applied to the pagination | {} * `--isu-pagination-size-selector` | Mixin applied to the page size selector | {} * @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; @apply --isu-pagination } 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; @apply --isu-pagination-inner-input } #last { @apply --isu-pagination-last } 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; } @apply --isu-pagination-size-selector } .page-count { display: inline-block; min-width: 20px; 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 1px; } :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 ]] 条<template is="dom-if" if="[[!hidePerPageNum]]">,每页 [[ limit ]] 条</template></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 of the pagination, small/mini * @type {string} * @default 0 */ size: { type: String, value: '', notify: true, reflectToAttribute: true }, /** * 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 * @type {boolean} * @default false */ hidePageSelect: { type: Boolean, value: false }, /** * Whether or not show the per page Num * @type {boolean} * @default false */ hidePerPageNum: { type: Boolean, value: false }, /** * The number of items that are displayed per page * @type {array} * @default [20, 40, 60] */ pageSizes: { type: Array, value: function () { return [20, 40, 60] } }, __pageIndex: { type: Number }, /** * The start page of the pagination * @type {number} * @default */ start: { type: Number, notify: true, reflectToAttribute: true }, __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) { 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 setTimeout(() => { this.dispatchEvent(new CustomEvent('isu-start-changed', { detail: { value: start }, bubbles: true, composed: true })) }, 0) } } _totalChanged (total) { if (total <= 1 && this.hideOnSinglePage) { this.style.display = 'none' } } _pageIndexChanged (__pageIndex) { if(!__pageIndex) return this.start = (__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('isu-limit-changed', { detail: { value: limit } })) } this.__limit = limit.toString() } __limitChanged (limit) { if (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)