重构number组件完成

master
yutent 2023-11-21 12:07:22 +08:00
parent bef7dac956
commit 88634682f7
2 changed files with 118 additions and 110 deletions

View File

@ -23,7 +23,7 @@ class Button extends Component {
}
},
disabled: false,
lazy: 'num!0' // 并发拦截时间, 单位毫秒
lazy: 'num!1000' // 并发拦截时间, 单位毫秒
}
static styles = [
@ -252,9 +252,10 @@ class Button extends Component {
]
#cacheIcon
#stamp = 0
created() {
this.stamp = 0
this.#stamp = 0
this._clickFn = this.$on(
'click',
@ -266,10 +267,10 @@ class Button extends Component {
return ev.stopPropagation()
}
// 并发拦截
if (lazy > 0 && now - this.stamp < lazy) {
if (lazy > 0 && now - this.#stamp < lazy) {
return ev.stopPropagation()
}
this.stamp = now
this.#stamp = now
},
true
)

View File

@ -4,77 +4,84 @@
* @date 2023/03/06 15:17:25
*/
import { css, html, Component, nextTick } from 'wkit'
import { css, html, Component } from 'wkit'
class WcNumber extends Component {
const MAX_VALUE = 1e9 - 1
const MIN_VALUE = -MAX_VALUE
class InputNumber extends Component {
static props = {
type: 'primary',
size: 'l',
max: { type: Number, default: null },
min: { type: Number, default: null },
step: 1,
max: `num!${MAX_VALUE}`,
min: `num!${MIN_VALUE}`,
step: 'num!1',
value: {
type: Number,
default: 0,
attribute: false
observer(v) {
this.value = this.#fix(v)
}
},
readonly: false,
autofocus: false,
disabled: false,
lazy: 1000 // 并发拦截时间, 单位毫秒
lazy: 'num!1000' // 并发拦截时间, 单位毫秒
}
static styles = [
// 基础样式
css`
:host {
overflow: hidden;
display: inline-flex;
min-width: 128px;
height: 36px;
user-select: none;
-moz-user-select: none;
height: 32px;
color: var(--color-dark-1);
border-radius: 3px;
font-size: 14px;
cursor: text;
transition: box-shadow 0.15s linear;
-webkit-user-select: none;
user-select: none;
}
:host(:focus-within) {
box-shadow: 0 0 0 2px var(--color-plain-a);
}
.label {
.container {
display: flex;
width: 100%;
height: 100%;
margin: 0 auto;
line-height: 1;
font-size: 14px;
border: 1px solid var(--color-grey-2);
border-radius: inherit;
background: var(--bg-color, #fff);
background: #fff;
color: inherit;
cursor: text;
span {
button {
display: flex;
justify-content: center;
align-items: center;
width: 34px;
height: 100%;
border: 0;
font-size: 18px;
font-family: Tahoma, Verdana, Helvetica, Arial, sans-serif;
background: var(--color-plain-1);
color: inherit;
cursor: pointer;
&:first-child {
border-radius: 3px 0 0 3px;
border-right: 1px solid var(--color-grey-a);
border-radius: 2px 0 0 2px;
border-right: 1px solid var(--color-grey-1);
}
&:last-child {
border-radius: 0 3px 3px 0;
border-left: 1px solid var(--color-grey-a);
border-radius: 0 2px 2px 0;
border-left: 1px solid var(--color-grey-1);
}
&.disabled {
&[disabled] {
cursor: not-allowed;
opacity: 0.6;
}
@ -87,18 +94,12 @@ class WcNumber extends Component {
height: 100%;
padding: 0 6px;
border: 0;
border-radius: inherit;
color: inherit;
font: inherit;
font-size: inherit;
text-align: center;
background: none;
outline: none;
box-shadow: none;
cursor: inherit;
&::placeholder {
color: var(--color-grey-1);
}
}
/* ----- */
}
@ -117,11 +118,6 @@ class WcNumber extends Component {
h: 24px,
f: 12px
),
l: (
w: 108px,
h: 32px,
f: 14px
),
xl: (
w: 132px,
h: 36px,
@ -130,7 +126,7 @@ class WcNumber extends Component {
xxl: (
w: 160px,
h: 44px,
f: 14px
f: 16px
)
);
@ -140,18 +136,21 @@ class WcNumber extends Component {
height: map.get($v, 'h');
font-size: map.get($v, 'f');
.icon {
--wc-icon-size: #{map.get($v, 'f')};
button {
width: map.get($v, 'h') + 2;
}
}
:host([size='#{$s}'][circle]) {
width: map.get($v, 'h');
height: map.get($v, 'h');
}
}
:host([round]) {
border-radius: 99rem;
border-radius: 22px;
button:first-child {
border-radius: 22px 0 0 22px;
}
button:last-child {
border-radius: 0 22px 22px 0;
}
}
`,
// 配色
@ -173,7 +172,7 @@ class WcNumber extends Component {
:host([type='#{$t}']) span {
border-color: var(--color-#{$c}-a);
}
:host([type='#{$t}']) .label {
:host([type='#{$t}']) .container {
border-color: var(--color-#{$c}-2);
}
}
@ -185,14 +184,14 @@ class WcNumber extends Component {
opacity: 0.6;
}
/* --- */
:host([readonly]) .label {
:host([readonly]) .container {
cursor: default;
opacity: 0.8;
span {
cursor: inherit;
}
}
:host([disabled]) .label {
:host([disabled]) .container {
background: var(--color-plain-1);
cursor: not-allowed;
opacity: 0.6;
@ -203,54 +202,66 @@ class WcNumber extends Component {
`
]
created() {
this.stamp = 0
}
#stamp = 0
mounted() {
if (this.autofocus) {
// 需要focus()才能聚焦成功
nextTick(_ => this.$refs.input.focus())
this.$refs.input.focus()
}
this.value = this.clapm(this.value)
this.value = this.#fix(this.$refs.input.value)
this.$refs.input.value = this.value
}
onClick(e) {
if (e.target.classList.contains('disabled')) {
return
}
const { disabled, readOnly } = this
#click(ev) {
let { disabled, readOnly } = this
let { act } = ev.target.dataset
if (disabled || readOnly) {
return
}
const { act } = e.target.dataset
this.updateValue(act)
}
updateValue(act) {
const { max, min, step, value } = this
if (act === '+') {
if (max === null || value + step <= max) {
this.value += step
} else {
this.value = max
}
} else {
if (min === null || value - step >= min) {
this.value -= step
} else {
this.value = min
}
this.#updateValue(act)
}
#fetch(value) {
this.value = value
this.$emit('input')
this.$emit('change')
}
onChange(e) {
this.value = this.clapm(e.target.value)
#updateValue(act) {
let { max, min, step, value } = this
if (act === '+') {
if (value >= max) {
return
}
value += step
} else {
if (value <= min) {
return
}
value -= step
}
this.#fetch(value)
this.$refs.input.value = this.value
}
onKeydown(ev) {
const now = Date.now()
const { lazy, disabled, readOnly } = this
#changed(ev) {
let _value = +ev.target.value
let value = this.#fix(_value)
if (value !== _value) {
ev.target.value = value
}
if (this.value !== value) {
this.#fetch(value)
}
}
#keydown(ev) {
let now = Date.now()
let { lazy, disabled, readOnly } = this
if (disabled || readOnly) {
return
@ -259,62 +270,58 @@ class WcNumber extends Component {
// up: 38, down: 40
if (ev.keyCode === 38 || ev.keyCode === 40) {
ev.preventDefault()
return this.updateValue(ev.keyCode === 38 ? '+' : '-')
return this.#updateValue(ev.keyCode === 38 ? '+' : '-')
}
// 回车触发submit事件
if (ev.keyCode === 13) {
ev.preventDefault()
// 并发拦截
if (lazy && now - this.stamp < lazy) {
if (lazy && now - this.#stamp < lazy) {
return
}
this.stamp = now
this.value = this.clapm(ev.target.value)
this.#stamp = now
this.value = this.#fix(ev.target.value)
this.$refs.input.value = this.value
this.$emit('submit', { value: this.value })
}
}
clapm(val) {
const max = this.max ?? Number.MAX_SAFE_INTEGER
const min = this.min ?? Number.MIN_SAFE_INTEGER
#fix(val) {
let { max, min } = this
return Math.min(max, Math.max(+val, min))
}
render() {
return html`
<div class="label">
<span
<main class="container">
<button
data-act="-"
class=${this.min && this.value - this.step < this.min
? 'disabled'
: ''}
@click=${this.onClick}
>-</span
:disabled=${this.value <= this.min}
@click=${this.#click}
>
-
</button>
<input
ref="input"
value="0"
maxlength="9"
maxlength="10"
disabled=${this.disabled}
readonly=${this.readOnly}
autofocus=${this.autofocus}
:value=${this.value}
@change=${this.onChange}
@keydown=${this.onKeydown}
:readOnly=${this.readOnly}
value=${this.value}
@change=${this.#changed}
@keydown=${this.#keydown}
/>
<span
<button
data-act="+"
class=${this.max && this.value + this.step > this.max
? 'disabled'
: ''}
@click=${this.onClick}
>+</span
:disabled=${this.value >= this.max}
@click=${this.#click}
>
</div>
+
</button>
</main>
`
}
}
WcNumber.reg('number')
InputNumber.reg('number')