ui/src/form/link.js

156 lines
3.4 KiB
JavaScript
Raw Normal View History

2023-03-16 18:03:07 +08:00
/**
* {}
* @author yutent<yutent.io@gmail.com>
* @date 2023/03/16 17:40:50
*/
2023-03-17 18:29:47 +08:00
import { css, html, Component, bind, unbind, nextTick } from '@bd/core'
2023-03-16 18:03:07 +08:00
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() {
this.stamp = 0
if (this.autofocus) {
2023-03-17 18:29:47 +08:00
this.$refs.a.setAttribute('autofocus', '')
2023-03-16 18:03:07 +08:00
// 需要focus()才能聚焦成功
2023-03-17 18:29:47 +08:00
nextTick(_ => this.$refs.a.focus())
2023-03-16 18:03:07 +08:00
}
this._clickFn = bind(
2023-03-17 18:29:47 +08:00
this.$refs.a,
2023-03-16 18:03:07 +08:00
'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() {
2023-03-17 18:29:47 +08:00
unbind(this.$refs.a, 'click', this._clickFn)
2023-03-16 18:03:07 +08:00
}
render() {
return html`
2023-03-17 18:29:47 +08:00
<a tabindex="0" ref="a" class="link" href=${this.to || 'javascript:;'}>
2023-03-16 18:03:07 +08:00
<slot />
</a>
`
}
}
customElements.define('wc-link', Link)