ui/src/form/link.js

151 lines
3.2 KiB
JavaScript

/**
* {}
* @author yutent<yutent.io@gmail.com>
* @date 2023/03/16 17:40:50
*/
import { css, html, Component, bind, unbind, nextTick } from 'wkit'
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) {
nextTick(_ => this.$refs.a.focus())
}
this._clickFn = bind(
this.$refs.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
)
}
render() {
return html`
<a tabindex="0" ref="a" class="link" href=${this.to || 'javascript:;'}>
<slot />
</a>
`
}
}
Link.reg('link')
百搭WCUI组件库, 基于web components开发。面向下一代的UI组件库
JavaScript 98.9%
CSS 1.1%