Merge branch 'master' of github.com:9th-js/wcui
						commit
						5a2428af15
					
				|  | @ -343,7 +343,7 @@ class Input extends Component { | ||||||
|   renderClose() { |   renderClose() { | ||||||
|     return html`<wc-icon
 |     return html`<wc-icon
 | ||||||
|       class="close" |       class="close" | ||||||
|       is="close" |       name="close" | ||||||
|       @click=${this.onClickClose} |       @click=${this.onClickClose} | ||||||
|     />` |     />` | ||||||
|   } |   } | ||||||
|  | @ -365,7 +365,7 @@ class Input extends Component { | ||||||
|         /> |         /> | ||||||
|         ${this.closeable && this.value ? this.renderClose() : ''} |         ${this.closeable && this.value ? this.renderClose() : ''} | ||||||
|         ${this.icon |         ${this.icon | ||||||
|           ? html`<wc-icon class="icon" is=${this.icon} />` |           ? html`<wc-icon class="icon" name=${this.icon} />` | ||||||
|           : html`<slot class="append" name="append" />`} |           : html`<slot class="append" name="append" />`} | ||||||
|       </div> |       </div> | ||||||
|     ` |     ` | ||||||
|  | @ -385,4 +385,4 @@ class Input extends Component { | ||||||
|   } |   } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| customElements.define('wc-input', Input) | Input.reg('input') | ||||||
|  |  | ||||||
|  | @ -0,0 +1,330 @@ | ||||||
|  | /** | ||||||
|  |  * {数字文本框组件} | ||||||
|  |  * @author yutent<yutent.io@gmail.com> | ||||||
|  |  * @date 2023/03/06 15:17:25 | ||||||
|  |  */ | ||||||
|  | 
 | ||||||
|  | import { css, html, Component, nextTick } from '@bd/core' | ||||||
|  | 
 | ||||||
|  | class WcNumber extends Component { | ||||||
|  |   static props = { | ||||||
|  |     type: 'primary', | ||||||
|  |     size: 'l', | ||||||
|  |     max: null, | ||||||
|  |     min: null, | ||||||
|  |     step: 1, | ||||||
|  |     value: { | ||||||
|  |       type: Number, | ||||||
|  |       default: 0, | ||||||
|  |       attribute: false | ||||||
|  |     }, | ||||||
|  |     readonly: false, | ||||||
|  |     autofocus: false, | ||||||
|  |     disabled: false, | ||||||
|  |     lazy: 1000 // 并发拦截时间, 单位毫秒
 | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   static styles = [ | ||||||
|  |     // 基础样式
 | ||||||
|  |     css` | ||||||
|  |       :host { | ||||||
|  |         overflow: hidden; | ||||||
|  |         display: inline-flex; | ||||||
|  |         min-width: 128px; | ||||||
|  |         height: 36px; | ||||||
|  |         user-select: none; | ||||||
|  |         -moz-user-select: none; | ||||||
|  |         color: var(--color-dark-1); | ||||||
|  |         border-radius: 3px; | ||||||
|  |         cursor: text; | ||||||
|  |         transition: box-shadow 0.15s linear; | ||||||
|  |       } | ||||||
|  | 
 | ||||||
|  |       :host(:focus-within) { | ||||||
|  |         box-shadow: 0 0 0 2px var(--color-plain-a); | ||||||
|  |       } | ||||||
|  |       .label { | ||||||
|  |         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); | ||||||
|  |         color: inherit; | ||||||
|  |         cursor: text; | ||||||
|  | 
 | ||||||
|  |         span { | ||||||
|  |           display: flex; | ||||||
|  |           justify-content: center; | ||||||
|  |           align-items: center; | ||||||
|  |           width: 34px; | ||||||
|  |           height: 100%; | ||||||
|  |           font-size: 18px; | ||||||
|  |           cursor: pointer; | ||||||
|  | 
 | ||||||
|  |           &:first-child { | ||||||
|  |             border-radius: 3px 0 0 3px; | ||||||
|  |             border-right: 1px solid var(--color-grey-a); | ||||||
|  |           } | ||||||
|  |           &:last-child { | ||||||
|  |             border-radius: 0 3px 3px 0; | ||||||
|  |             border-left: 1px solid var(--color-grey-a); | ||||||
|  |           } | ||||||
|  | 
 | ||||||
|  |           &.disabled { | ||||||
|  |             cursor: not-allowed; | ||||||
|  |             opacity: 0.6; | ||||||
|  |           } | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         input { | ||||||
|  |           flex: 1; | ||||||
|  |           min-width: 32px; | ||||||
|  |           width: 0; | ||||||
|  |           height: 100%; | ||||||
|  |           padding: 0 6px; | ||||||
|  |           border: 0; | ||||||
|  |           border-radius: inherit; | ||||||
|  |           color: inherit; | ||||||
|  |           font: inherit; | ||||||
|  |           text-align: center; | ||||||
|  |           background: none; | ||||||
|  |           outline: none; | ||||||
|  |           box-shadow: none; | ||||||
|  |           cursor: inherit; | ||||||
|  | 
 | ||||||
|  |           &::placeholder { | ||||||
|  |             color: var(--color-grey-1); | ||||||
|  |           } | ||||||
|  |         } | ||||||
|  |         /* ----- */ | ||||||
|  |       } | ||||||
|  |     `,
 | ||||||
|  |     // 尺寸
 | ||||||
|  |     css` | ||||||
|  |       @use 'sass:map'; | ||||||
|  |       $sizes: ( | ||||||
|  |         s: ( | ||||||
|  |           w: 52px, | ||||||
|  |           h: 20px, | ||||||
|  |           f: 12px | ||||||
|  |         ), | ||||||
|  |         m: ( | ||||||
|  |           w: 72px, | ||||||
|  |           h: 24px, | ||||||
|  |           f: 12px | ||||||
|  |         ), | ||||||
|  |         l: ( | ||||||
|  |           w: 108px, | ||||||
|  |           h: 32px, | ||||||
|  |           f: 14px | ||||||
|  |         ), | ||||||
|  |         xl: ( | ||||||
|  |           w: 132px, | ||||||
|  |           h: 36px, | ||||||
|  |           f: 14px | ||||||
|  |         ), | ||||||
|  |         xxl: ( | ||||||
|  |           w: 160px, | ||||||
|  |           h: 44px, | ||||||
|  |           f: 14px | ||||||
|  |         ), | ||||||
|  |         xxxl: ( | ||||||
|  |           w: 192px, | ||||||
|  |           h: 52px, | ||||||
|  |           f: 16px | ||||||
|  |         ), | ||||||
|  |         xxxxl: ( | ||||||
|  |           w: 212px, | ||||||
|  |           h: 64px, | ||||||
|  |           f: 18px | ||||||
|  |         ) | ||||||
|  |       ); | ||||||
|  | 
 | ||||||
|  |       @loop $s, $v in $sizes { | ||||||
|  |         :host([size='#{$s}']) { | ||||||
|  |           min-width: map.get($v, 'w'); | ||||||
|  |           height: map.get($v, 'h'); | ||||||
|  |           font-size: map.get($v, 'f'); | ||||||
|  | 
 | ||||||
|  |           .icon { | ||||||
|  |             --size: #{map.get($v, 'f')}; | ||||||
|  |           } | ||||||
|  |         } | ||||||
|  |         :host([size='#{$s}'][circle]) { | ||||||
|  |           width: map.get($v, 'h'); | ||||||
|  |           height: map.get($v, 'h'); | ||||||
|  |         } | ||||||
|  |       } | ||||||
|  | 
 | ||||||
|  |       :host([round]) { | ||||||
|  |         border-radius: 99rem; | ||||||
|  |       } | ||||||
|  |     `,
 | ||||||
|  |     // 配色
 | ||||||
|  |     css` | ||||||
|  |       $colors: ( | ||||||
|  |         primary: 'teal', | ||||||
|  |         info: 'blue', | ||||||
|  |         success: 'green', | ||||||
|  |         warning: 'orange', | ||||||
|  |         danger: 'red', | ||||||
|  |         secondary: 'dark', | ||||||
|  |         help: 'grey' | ||||||
|  |       ); | ||||||
|  | 
 | ||||||
|  |       @loop $t, $c in $colors { | ||||||
|  |         :host([type='#{$t}']:focus-within) { | ||||||
|  |           box-shadow: 0 0 0 2px var(--color-#{$c}-a); | ||||||
|  |         } | ||||||
|  |         :host([type='#{$t}']) span { | ||||||
|  |           border-color: var(--color-#{$c}-a); | ||||||
|  |         } | ||||||
|  |         :host([type='#{$t}']) .label { | ||||||
|  |           border-color: var(--color-#{$c}-2); | ||||||
|  |         } | ||||||
|  |       } | ||||||
|  |     `,
 | ||||||
|  |     // 状态
 | ||||||
|  |     css` | ||||||
|  |       :host([disabled]) { | ||||||
|  |         cursor: not-allowed; | ||||||
|  |         opacity: 0.6; | ||||||
|  |       } | ||||||
|  |       /* --- */ | ||||||
|  |       :host([readonly]) .label { | ||||||
|  |         cursor: default; | ||||||
|  |         opacity: 0.8; | ||||||
|  |         span { | ||||||
|  |           cursor: inherit; | ||||||
|  |         } | ||||||
|  |       } | ||||||
|  |       :host([disabled]) .label { | ||||||
|  |         background: var(--color-plain-1); | ||||||
|  |         cursor: not-allowed; | ||||||
|  |         opacity: 0.6; | ||||||
|  |         span { | ||||||
|  |           cursor: inherit; | ||||||
|  |         } | ||||||
|  |       } | ||||||
|  |     ` | ||||||
|  |   ] | ||||||
|  | 
 | ||||||
|  |   created() { | ||||||
|  |     this.stamp = 0 | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   mounted() { | ||||||
|  |     if (this.autofocus) { | ||||||
|  |       // 需要focus()才能聚焦成功
 | ||||||
|  |       nextTick(_ => this.$refs.input.focus()) | ||||||
|  |     } | ||||||
|  |     this.value = this.clapm(this.value) | ||||||
|  |     this.$refs.input.value = this.value | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   onClick(e) { | ||||||
|  |     if (e.target.classList.contains('disabled')) { | ||||||
|  |       return | ||||||
|  |     } | ||||||
|  |     const { disabled, readOnly } = this | ||||||
|  |     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.$emit('input') | ||||||
|  |   } | ||||||
|  |   onChange(e) { | ||||||
|  |     this.value = this.clapm(e.target.value) | ||||||
|  |     this.$refs.input.value = this.value | ||||||
|  |   } | ||||||
|  |   onKeydown(ev) { | ||||||
|  |     const now = Date.now() | ||||||
|  |     const { lazy, disabled, readOnly } = this | ||||||
|  | 
 | ||||||
|  |     if (disabled || readOnly) { | ||||||
|  |       return | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     // up: 38, down: 40
 | ||||||
|  |     if (ev.keyCode === 38 || ev.keyCode === 40) { | ||||||
|  |       ev.preventDefault() | ||||||
|  |       return this.updateValue(ev.keyCode === 38 ? '+' : '-') | ||||||
|  |     } | ||||||
|  |     // 回车触发submit事件
 | ||||||
|  |     if (ev.keyCode === 13) { | ||||||
|  |       ev.preventDefault() | ||||||
|  | 
 | ||||||
|  |       // 并发拦截
 | ||||||
|  |       if (lazy && now - this.stamp < lazy) { | ||||||
|  |         return | ||||||
|  |       } | ||||||
|  | 
 | ||||||
|  |       this.stamp = now | ||||||
|  |       this.value = this.clapm(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 | ||||||
|  |     return Math.min(max, Math.max(+val, min)) | ||||||
|  |   } | ||||||
|  |   render() { | ||||||
|  |     return html` | ||||||
|  |       <div class="label"> | ||||||
|  |         <span | ||||||
|  |           data-act="-" | ||||||
|  |           class=${this.min && this.value - this.step < this.min | ||||||
|  |             ? 'disabled' | ||||||
|  |             : ''} | ||||||
|  |           @click=${this.onClick} | ||||||
|  |           >-</span | ||||||
|  |         > | ||||||
|  |         <input | ||||||
|  |           ref="input" | ||||||
|  |           value="0" | ||||||
|  |           maxlength="9" | ||||||
|  |           disabled=${this.disabled} | ||||||
|  |           readonly=${this.readOnly} | ||||||
|  |           autofocus=${this.autofocus} | ||||||
|  |           :value=${this.value} | ||||||
|  |           @change=${this.onChange} | ||||||
|  |           @keydown=${this.onKeydown} | ||||||
|  |         /> | ||||||
|  |         <span | ||||||
|  |           data-act="+" | ||||||
|  |           class=${this.max && this.value + this.step > this.max | ||||||
|  |             ? 'disabled' | ||||||
|  |             : ''} | ||||||
|  |           @click=${this.onClick} | ||||||
|  |           >+</span | ||||||
|  |         > | ||||||
|  |       </div> | ||||||
|  |     ` | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | WcNumber.reg('number') | ||||||
|  | @ -217,4 +217,4 @@ class TextArea extends Component { | ||||||
|   } |   } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| customElements.define('wc-textarea', TextArea) | TextArea.reg('textarea') | ||||||
|  |  | ||||||
|  | @ -8,13 +8,7 @@ import { css, bind, html, unbind, Component } from '@bd/core' | ||||||
| 
 | 
 | ||||||
| class Scroll extends Component { | class Scroll extends Component { | ||||||
|   static props = { |   static props = { | ||||||
|     axis: { |     axis: 'xy', | ||||||
|       type: String, |  | ||||||
|       default: 'xy', |  | ||||||
|       observer(val) { |  | ||||||
|         this.onAxisChange(val) |  | ||||||
|       } |  | ||||||
|     }, |  | ||||||
|     distance: 0 |     distance: 0 | ||||||
|   } |   } | ||||||
|   dragging = false |   dragging = false | ||||||
|  | @ -23,7 +17,7 @@ class Scroll extends Component { | ||||||
|     css` |     css` | ||||||
|       :host { |       :host { | ||||||
|         position: relative; |         position: relative; | ||||||
|         overflow: hidden; |         overflow: auto; | ||||||
|         display: block; |         display: block; | ||||||
|         &::-webkit-scrollbar { |         &::-webkit-scrollbar { | ||||||
|           display: none; |           display: none; | ||||||
|  | @ -34,7 +28,6 @@ class Scroll extends Component { | ||||||
|         position: relative; |         position: relative; | ||||||
|       } |       } | ||||||
|       .scroll-bar { |       .scroll-bar { | ||||||
|         display: none; |  | ||||||
|         position: absolute; |         position: absolute; | ||||||
|         background: #909399; |         background: #909399; | ||||||
|         width: 0; |         width: 0; | ||||||
|  | @ -64,16 +57,22 @@ class Scroll extends Component { | ||||||
|           visibility: hidden; |           visibility: hidden; | ||||||
|         } |         } | ||||||
|       } |       } | ||||||
|  |       :host([axis='x']) { | ||||||
|  |         overflow-x: auto; | ||||||
|  |         overflow-y: hidden; | ||||||
|  |         .vertical { | ||||||
|  |           display: none; | ||||||
|  |         } | ||||||
|  |       } | ||||||
|  |       :host([axis='y']) { | ||||||
|  |         overflow-y: auto; | ||||||
|  |         overflow-x: hidden; | ||||||
|  |         .horizon { | ||||||
|  |           display: none; | ||||||
|  |         } | ||||||
|  |       } | ||||||
|     ` |     ` | ||||||
|   ] |   ] | ||||||
|   onAxisChange(val) { |  | ||||||
|     this.style.overflow = 'hidden' |  | ||||||
|     if (val === 'xy') { |  | ||||||
|       this.style.overflow = 'auto' |  | ||||||
|     } else { |  | ||||||
|       this.style[`overflow-${val}`] = 'auto' |  | ||||||
|     } |  | ||||||
|   } |  | ||||||
| 
 | 
 | ||||||
|   render() { |   render() { | ||||||
|     return html` |     return html` | ||||||
|  | @ -193,12 +192,10 @@ class Scroll extends Component { | ||||||
|       this.horizonWidth = 0 |       this.horizonWidth = 0 | ||||||
|     } |     } | ||||||
|     if (axis.includes('x')) { |     if (axis.includes('x')) { | ||||||
|       horizon.style.display = 'block' |  | ||||||
|       horizon.style.width = this.horizonWidth + 'px' |       horizon.style.width = this.horizonWidth + 'px' | ||||||
|       bind(horizon, 'mousedown', this.onmousedown.bind(this)) |       bind(horizon, 'mousedown', this.onmousedown.bind(this)) | ||||||
|     } |     } | ||||||
|     if (axis.includes('y')) { |     if (axis.includes('y')) { | ||||||
|       vertical.style.display = 'block' |  | ||||||
|       vertical.style.height = this.verticalHeight + 'px' |       vertical.style.height = this.verticalHeight + 'px' | ||||||
|       bind(vertical, 'mousedown', this.onmousedown.bind(this)) |       bind(vertical, 'mousedown', this.onmousedown.bind(this)) | ||||||
|     } |     } | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue