完成分页组件的迁移;优化button组件
parent
211e90e4f0
commit
1665e881fb
|
@ -42,7 +42,7 @@
|
||||||
- [x] `wc-markd`markdown 组件
|
- [x] `wc-markd`markdown 组件
|
||||||
- [ ] `wc-meditor`md 文本编辑器
|
- [ ] `wc-meditor`md 文本编辑器
|
||||||
- [ ] `wc-neditor`富文本编辑器
|
- [ ] `wc-neditor`富文本编辑器
|
||||||
- [ ] `wc-pager`分页组件
|
- [x] `wc-pager`分页组件
|
||||||
- [x] `wc-color`颜色选择器
|
- [x] `wc-color`颜色选择器
|
||||||
- [ ] `wc-datepicker`日期选择器
|
- [ ] `wc-datepicker`日期选择器
|
||||||
- [ ] `wc-timepicker`时间选择器
|
- [ ] `wc-timepicker`时间选择器
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
* @date 2023/03/06 15:17:25
|
* @date 2023/03/06 15:17:25
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { css, html, Component, nextTick } from '@bd/core'
|
import { css, html, Component, nextTick, styleMap } from '@bd/core'
|
||||||
import '../icon/index.js'
|
import '../icon/index.js'
|
||||||
|
|
||||||
class Button extends Component {
|
class Button extends Component {
|
||||||
|
@ -62,7 +62,7 @@ class Button extends Component {
|
||||||
outline: none;
|
outline: none;
|
||||||
color: inherit;
|
color: inherit;
|
||||||
cursor: inherit;
|
cursor: inherit;
|
||||||
transition: background 0.15s linear;
|
transition: background 0.15s linear, color 0.15s linear;
|
||||||
|
|
||||||
&::-moz-focus-inner {
|
&::-moz-focus-inner {
|
||||||
border: none;
|
border: none;
|
||||||
|
@ -70,8 +70,7 @@ class Button extends Component {
|
||||||
}
|
}
|
||||||
|
|
||||||
.icon {
|
.icon {
|
||||||
--size: var(--icon-size, 18px);
|
--size: var(--icon-size, 14px);
|
||||||
margin-right: 4px;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
:host(:focus-within) {
|
:host(:focus-within) {
|
||||||
|
@ -121,7 +120,7 @@ class Button extends Component {
|
||||||
font-size: map.get($v, 'f');
|
font-size: map.get($v, 'f');
|
||||||
|
|
||||||
.icon {
|
.icon {
|
||||||
--size: #{map.get($v, 'f')};
|
--size: var(--icon-size, #{map.get($v, 'f')});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
:host([size='#{$s}'][circle]) {
|
:host([size='#{$s}'][circle]) {
|
||||||
|
@ -161,18 +160,19 @@ class Button extends Component {
|
||||||
warning: 'orange',
|
warning: 'orange',
|
||||||
danger: 'red',
|
danger: 'red',
|
||||||
secondary: 'dark',
|
secondary: 'dark',
|
||||||
help: 'grey'
|
help: 'grey',
|
||||||
|
plain: 'plain'
|
||||||
);
|
);
|
||||||
|
|
||||||
@loop $t, $c in $colors {
|
@loop $t, $c in $colors {
|
||||||
:host([type='#{$t}']) {
|
:host([type='#{$t}']) {
|
||||||
button {
|
button {
|
||||||
color: var(--color-#{$c}-2);
|
color: var(--color-#{$c}-2);
|
||||||
border-color: var(--color-#{$c}-2);
|
border-color: var(--color-#{$c}-1);
|
||||||
|
|
||||||
&:hover {
|
&:hover {
|
||||||
color: var(--color-#{$c}-1);
|
color: var(--color-#{$c}-1);
|
||||||
border-color: var(--color-#{$c}-1);
|
border-color: var(--color-#{$c}-2);
|
||||||
}
|
}
|
||||||
&:active {
|
&:active {
|
||||||
color: var(--color-#{$c}-3);
|
color: var(--color-#{$c}-3);
|
||||||
|
@ -184,7 +184,11 @@ class Button extends Component {
|
||||||
|
|
||||||
&:host([solid]) button {
|
&:host([solid]) button {
|
||||||
border: 0;
|
border: 0;
|
||||||
color: #fff;
|
@if $t == 'plain' {
|
||||||
|
color: var(--color-dark-1);
|
||||||
|
} @else {
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
background: var(--color-#{$c}-2);
|
background: var(--color-#{$c}-2);
|
||||||
|
|
||||||
&:hover {
|
&:hover {
|
||||||
|
@ -215,6 +219,13 @@ class Button extends Component {
|
||||||
`
|
`
|
||||||
]
|
]
|
||||||
|
|
||||||
|
#empty = true
|
||||||
|
|
||||||
|
fixStyle() {
|
||||||
|
this.#empty = this.$refs.cont?.assignedNodes().length === 0
|
||||||
|
this.$requestUpdate()
|
||||||
|
}
|
||||||
|
|
||||||
created() {
|
created() {
|
||||||
this.stamp = 0
|
this.stamp = 0
|
||||||
|
|
||||||
|
@ -241,13 +252,15 @@ class Button extends Component {
|
||||||
if (this.autofocus) {
|
if (this.autofocus) {
|
||||||
nextTick(_ => this.$refs.btn.focus())
|
nextTick(_ => this.$refs.btn.focus())
|
||||||
}
|
}
|
||||||
|
nextTick(_ => this.fixStyle())
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
|
let style = styleMap({ 'margin-right': this.#empty ? 0 : '4px' })
|
||||||
return html`
|
return html`
|
||||||
<button ref="btn" disabled=${this.disabled}>
|
<button ref="btn" disabled=${this.disabled}>
|
||||||
<wc-icon class="icon" name=${this.icon}></wc-icon>
|
<wc-icon class="icon" name=${this.icon} style=${style}></wc-icon>
|
||||||
<slot></slot>
|
<slot ref="cont"></slot>
|
||||||
</button>
|
</button>
|
||||||
`
|
`
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,316 @@
|
||||||
|
/**
|
||||||
|
* {}
|
||||||
|
* @author yutent<yutent.io@gmail.com>
|
||||||
|
* @date 2023/04/18 09:38:01
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { css, html, Component, bind, styleMap } from '@bd/core'
|
||||||
|
import '../form/button.js'
|
||||||
|
|
||||||
|
const LAYOUT_DICT = {
|
||||||
|
home: e =>
|
||||||
|
html`<wc-button
|
||||||
|
solid
|
||||||
|
type="plain"
|
||||||
|
data-act="1"
|
||||||
|
disabled=${e}
|
||||||
|
class="item"
|
||||||
|
icon="dbl-left"
|
||||||
|
></wc-button>`,
|
||||||
|
end: e =>
|
||||||
|
html`<wc-button
|
||||||
|
solid
|
||||||
|
type="plain"
|
||||||
|
data-act="end"
|
||||||
|
disabled=${e}
|
||||||
|
class="item"
|
||||||
|
icon="dbl-right"
|
||||||
|
></wc-button>`,
|
||||||
|
prev: e =>
|
||||||
|
html`<wc-button
|
||||||
|
solid
|
||||||
|
type="plain"
|
||||||
|
data-act="prev"
|
||||||
|
disabled=${e}
|
||||||
|
class="item"
|
||||||
|
icon="left"
|
||||||
|
></wc-button>`,
|
||||||
|
next: e =>
|
||||||
|
html`<wc-button
|
||||||
|
solid
|
||||||
|
type="plain"
|
||||||
|
data-act="next"
|
||||||
|
disabled=${e}
|
||||||
|
class="item"
|
||||||
|
icon="right"
|
||||||
|
></wc-button>`,
|
||||||
|
curr: n => html`<span class="curr item">${n}</span>`,
|
||||||
|
info: (t, p) => html`<span class="item">共 ${t}条, ${p}页</span>`,
|
||||||
|
jump(n) {
|
||||||
|
return html`<section class="item jump">
|
||||||
|
<span>Go to</span>
|
||||||
|
<input ref="input" @keydown=${this.gotoPage} maxlength="6" value=${n} />
|
||||||
|
</section>`
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 计算页码
|
||||||
|
function calculate(curr, total) {
|
||||||
|
var arr = []
|
||||||
|
var fixed = 0
|
||||||
|
var half = curr < 3 ? 6 - curr : 2 // 中间页码
|
||||||
|
|
||||||
|
// 总页码小于2
|
||||||
|
if (total < 2) {
|
||||||
|
arr.push({ to: curr, txt: curr })
|
||||||
|
return arr
|
||||||
|
}
|
||||||
|
|
||||||
|
// 当前页面比半数多时, 前面的用省略号代替
|
||||||
|
if (curr - half > 1 && total > 5) {
|
||||||
|
var to = curr - 2 * half
|
||||||
|
to = to < 1 ? 1 : to
|
||||||
|
arr.push({ to, txt: '...' })
|
||||||
|
}
|
||||||
|
|
||||||
|
if (total - curr < half) {
|
||||||
|
fixed = half - total + curr
|
||||||
|
}
|
||||||
|
|
||||||
|
// 把页码拆成2部分来
|
||||||
|
for (var i = curr - half - fixed; i < curr + half + 1 && i <= total; i++) {
|
||||||
|
if (i > 0) {
|
||||||
|
arr.push({ to: i, txt: i })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 总页码太多时, 以省略号代替
|
||||||
|
if (curr + half < total) {
|
||||||
|
var to = curr + 2 * half
|
||||||
|
to = to > total ? total : to
|
||||||
|
arr.push({ to, txt: '...' })
|
||||||
|
}
|
||||||
|
|
||||||
|
return arr
|
||||||
|
}
|
||||||
|
|
||||||
|
class Pager extends Component {
|
||||||
|
static props = {
|
||||||
|
layout: {
|
||||||
|
type: String,
|
||||||
|
default: 'home, prev, pages, next, end',
|
||||||
|
attribute: false
|
||||||
|
},
|
||||||
|
total: {
|
||||||
|
type: Number,
|
||||||
|
default: 0,
|
||||||
|
attribute: false,
|
||||||
|
observer(v) {
|
||||||
|
if (this.#mounted) {
|
||||||
|
this.totalpage = Math.ceil(v / this.pagesize)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
totalpage: {
|
||||||
|
type: Number,
|
||||||
|
default: 1,
|
||||||
|
attribute: false,
|
||||||
|
observer(v) {
|
||||||
|
if (this.page > v) {
|
||||||
|
this.page = v
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
page: {
|
||||||
|
type: Number,
|
||||||
|
default: 1,
|
||||||
|
attribute: false,
|
||||||
|
observer(v) {
|
||||||
|
if (v > this.totalpage) {
|
||||||
|
this.page = this.totalpage
|
||||||
|
} else if (v < 1) {
|
||||||
|
this.page = 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
pagesize: {
|
||||||
|
type: Number,
|
||||||
|
default: 20,
|
||||||
|
attribute: false,
|
||||||
|
observer(v) {
|
||||||
|
if (this.total > 0) {
|
||||||
|
this.totalpage = Math.ceil(this.total / v)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static styles = [
|
||||||
|
css`
|
||||||
|
:host {
|
||||||
|
display: block;
|
||||||
|
line-height: 1;
|
||||||
|
font-size: 14px;
|
||||||
|
user-select: none;
|
||||||
|
-moz-user-select: none;
|
||||||
|
color: var(--color-dark-1);
|
||||||
|
|
||||||
|
.layout {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
margin: 10px auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.item {
|
||||||
|
min-width: 32px;
|
||||||
|
width: auto;
|
||||||
|
--padding: 0;
|
||||||
|
margin: 0 5px;
|
||||||
|
--icon-size: 12px;
|
||||||
|
border-radius: 4px;
|
||||||
|
|
||||||
|
&.curr {
|
||||||
|
display: inline-flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
height: 32px;
|
||||||
|
background: var(--color-teal-1);
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.jump {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
&[size='l'] {
|
||||||
|
--icon-size: 12px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
input {
|
||||||
|
width: 48px;
|
||||||
|
height: 24px;
|
||||||
|
padding: 0 4px;
|
||||||
|
margin-left: 4px;
|
||||||
|
border: 1px solid var(--color-grey-2);
|
||||||
|
border-radius: 3px;
|
||||||
|
text-align: center;
|
||||||
|
outline: none;
|
||||||
|
transition: box-shadow 0.15s linear;
|
||||||
|
|
||||||
|
&:focus {
|
||||||
|
box-shadow: 0 0 0 2px var(--color-plain-a);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`,
|
||||||
|
|
||||||
|
css``
|
||||||
|
]
|
||||||
|
|
||||||
|
#mounted = false
|
||||||
|
|
||||||
|
handleBtnClick(ev) {
|
||||||
|
let elem = ev.target
|
||||||
|
if (elem.tagName === 'WC-BUTTON') {
|
||||||
|
let { page, totalpage } = this
|
||||||
|
let num = elem.dataset.act
|
||||||
|
|
||||||
|
if (elem.disabled) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (num) {
|
||||||
|
case 'prev':
|
||||||
|
num = page - 1
|
||||||
|
break
|
||||||
|
|
||||||
|
case 'next':
|
||||||
|
console.log(num, page)
|
||||||
|
num = page + 1
|
||||||
|
break
|
||||||
|
|
||||||
|
case 'end':
|
||||||
|
num = totalpage
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
if (+num === page) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
this.page = num
|
||||||
|
|
||||||
|
this.$emit('page-changed', { data: num })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
gotoPage(ev) {
|
||||||
|
if (ev.keyCode === 13) {
|
||||||
|
let n = +ev.target.value
|
||||||
|
if (n === n) {
|
||||||
|
this.page = n
|
||||||
|
this.$emit('page-changed', { data: this.page })
|
||||||
|
}
|
||||||
|
ev.target.value = this.page
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
mounted() {
|
||||||
|
this.#mounted = true
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
let layout = this.layout.split(',').map(s => s.trim())
|
||||||
|
let { page, total, totalpage } = this
|
||||||
|
|
||||||
|
return html`
|
||||||
|
<div class="layout" @click=${this.handleBtnClick}>
|
||||||
|
${layout.map(n => {
|
||||||
|
switch (n) {
|
||||||
|
case 'pages':
|
||||||
|
return calculate(page, totalpage).map(it =>
|
||||||
|
page === it.to
|
||||||
|
? LAYOUT_DICT.curr(page)
|
||||||
|
: html`<wc-button
|
||||||
|
type="plain"
|
||||||
|
solid
|
||||||
|
class="item"
|
||||||
|
data-act="${it.to}"
|
||||||
|
>${it.txt}</wc-button
|
||||||
|
>`
|
||||||
|
)
|
||||||
|
|
||||||
|
case 'home':
|
||||||
|
return LAYOUT_DICT.home(page === 1)
|
||||||
|
|
||||||
|
case 'prev':
|
||||||
|
return LAYOUT_DICT.prev(page === 1)
|
||||||
|
|
||||||
|
case 'next':
|
||||||
|
return LAYOUT_DICT.next(page >= totalpage)
|
||||||
|
|
||||||
|
case 'end':
|
||||||
|
return LAYOUT_DICT.end(page >= totalpage)
|
||||||
|
|
||||||
|
case 'curr':
|
||||||
|
return LAYOUT_DICT.curr(page)
|
||||||
|
|
||||||
|
case 'info':
|
||||||
|
return LAYOUT_DICT.info(total, totalpage)
|
||||||
|
|
||||||
|
case 'jump':
|
||||||
|
return LAYOUT_DICT.jump.call(this, page)
|
||||||
|
|
||||||
|
default:
|
||||||
|
return ''
|
||||||
|
}
|
||||||
|
})}
|
||||||
|
</div>
|
||||||
|
`
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Pager.reg('pager')
|
Loading…
Reference in New Issue