diff --git a/Readme.md b/Readme.md index 93faafc..b9086cf 100644 --- a/Readme.md +++ b/Readme.md @@ -22,7 +22,7 @@ - [ ] `wc-badge`徽标组件 - [ ] `wc-counter`倒计时组件 - [ ] `wc-drag`拖拽组件 -- [ ] `wc-button`表单组件-按钮 +- [x] `wc-button`表单组件-按钮 - [ ] `wc-checkbox`表单组件-复选框 - [ ] `wc-input`表单组件-文本输入框 - [ ] `wc-number`表单组件-步进数字输入 diff --git a/src/form/button.js b/src/form/button.js index 651175b..ec63169 100644 --- a/src/form/button.js +++ b/src/form/button.js @@ -25,7 +25,6 @@ class Button extends Component { } } }, - list: Array, disabled: false, lazy: 0 // 并发拦截时间, 单位毫秒 } @@ -227,7 +226,7 @@ class Button extends Component { created() { this.stamp = 0 - this.$on( + this._clickFn = this.$on( 'click', ev => { let { loading, disabled, lazy } = this @@ -255,12 +254,15 @@ class Button extends Component { } } + unmounted() { + this.$off('click', this._clickFn) + } + render() { return html` ` } diff --git a/src/form/link.js b/src/form/link.js new file mode 100644 index 0000000..3e25971 --- /dev/null +++ b/src/form/link.js @@ -0,0 +1,156 @@ +/** + * {} + * @author yutent + * @date 2023/03/16 17:40:50 + */ + +import { css, html, Component, bind, unbind, $, nextTick } from '@bd/core' +class Link extends Component { + static props = { + type: 'primary', + to: '', + autofocus: false, + disabled: false, + lazy: 0 // 并发拦截时间, 单位毫秒 + } + + static styles = [ + // 基础样式 + css` + :host { + position: relative; + display: inline-flex; + border-radius: 2px; + user-select: none; + -moz-user-select: none; + font-size: inherit; + cursor: pointer; + transition: box-shadow 0.15s linear; + + .link { + display: flex; + justify-content: center; + align-items: center; + width: 100%; + padding: var(--padding, 0 2px); + line-height: 1; + font-size: inherit; + font-family: inherit; + outline: none; + color: inherit; + cursor: inherit; + text-decoration: none; + transition: color 0.15s linear; + + &::-moz-focus-inner { + border: none; + } + } + + &::after { + position: absolute; + bottom: -2px; + left: 0; + width: 100%; + height: 1px; + border-bottom: 1px dashed transparent; + content: ''; + opacity: 0; + transition: opacity 0.15s linear; + } + } + `, + // 配色 + css` + $colors: ( + primary: 'teal', + info: 'blue', + success: 'green', + warning: 'orange', + danger: 'red', + secondary: 'dark', + help: 'grey' + ); + + @loop $t, $c in $colors { + :host([type='#{$t}']) { + color: var(--color-#{$c}-2); + &::after { + border-color: var(--color-#{$c}-1); + } + } + :host([type='#{$t}']:not([disabled]):hover) { + color: var(--color-#{$c}-1); + } + :host([type='#{$t}']:not([disabled]):active) { + color: var(--color-#{$c}-3); + } + :host([type='#{$t}']:not([disabled]):focus-within) { + box-shadow: 0 0 0 2px var(--color-#{$c}-a); + } + } + `, + // 状态 + css` + :host(:not([disabled]):hover), + :host([underline]) { + &::after { + opacity: 1; + } + } + :host([disabled]) { + cursor: not-allowed; + opacity: 0.6; + } + ` + ] + + mounted() { + let $a = $('.link', this.root) + this.stamp = 0 + + if (this.autofocus) { + $a.setAttribute('autofocus', '') + // 需要focus()才能聚焦成功 + nextTick(_ => $a.focus()) + } + + this._clickFn = bind( + $a, + 'click', + ev => { + let { disabled, lazy } = this + let now = Date.now() + + // 除了事件冒泡之外, a标签的默认事件也要阻止 + if (disabled) { + ev.preventDefault() + ev.stopPropagation() + return + } + // 并发拦截 + if (lazy > 0 && now - this.stamp < lazy) { + ev.preventDefault() + ev.stopPropagation() + return + } + this.stamp = now + }, + true + ) + } + + unmounted() { + unbind($('.link', this.root), 'click', this._clickFn) + } + + render() { + return html` + + + + ` + } +} + +customElements.define('wc-link', Link)