Merge branch 'master' of ssh://github.com/bd-js/wcui

master
chenjiajian 2023-04-10 15:27:18 +08:00
commit 8d9c42b019
1 changed files with 44 additions and 151 deletions

View File

@ -4,17 +4,8 @@
* @date 2023/03/06 15:17:25
*/
import {
css,
html,
Component,
bind,
unbind,
nextTick,
styleMap
} from '@bd/core'
import { css, html, Component, bind, styleMap } from '@bd/core'
import '../form/input.js'
import Drag from '../drag/core.js'
let uniqueInstance = null // 缓存当前打开的alert/confirm/prompt类型的弹窗
let toastInstance = null // 缓存toast的实例
@ -23,9 +14,11 @@ const LANG_TITLE = '提示'
const LANG_BTNS = ['取消', '确定']
// 要保证弹层唯一的类型
const UNIQUE_TYPES = ['alert', 'confirm', 'prompt']
const BUILDIN_TYPES = UNIQUE_TYPES.concat(['notify', 'toast'])
const BUILDIN_TYPES = UNIQUE_TYPES.concat(['toast'])
class Layer extends Component {
static animation = {}
static props = {
type: {
type: String,
@ -38,7 +31,8 @@ class Layer extends Component {
right: { type: String, attribute: false },
top: { type: String, attribute: false },
bottom: { type: String, attribute: false },
fixed: false,
background: { type: String, attribute: false },
'mask-color': { type: String, attribute: false },
mask: false,
'mask-close': false,
title: { type: String, default: '', attribute: false },
@ -63,7 +57,6 @@ class Layer extends Component {
display: flex;
}
:host([type='toast']),
:host([type='notify']),
:host([type='common']) {
.layer {
position: absolute;
@ -148,7 +141,9 @@ class Layer extends Component {
text-indent: 8px;
--size: 16px;
color: var(--color-dark-1);
box-shadow: 0 2px 12px rgba(0, 0, 0, 0.1);
}
::slotted(&__toast + &__toast) {
margin-top: 30px;
}
@ -255,19 +250,11 @@ class Layer extends Component {
}
}
}
:host([type='notify']) {
.layer {
width: 300px;
height: 120px;
&__content {
padding: 0 15px;
}
}
}
:host([type='toast']) {
.layer {
box-shadow: none;
background: none;
&__content {
flex-direction: column;
@ -285,7 +272,6 @@ class Layer extends Component {
]
#wrapped = false
#dragIns = null
#resolve = null
#reject = null
@ -301,36 +287,17 @@ class Layer extends Component {
this.promise.host = this
}
#toggleDrag() {
// 这3类弹层不允许拖拽
if (UNIQUE_TYPES.includes(this.type)) {
return
}
if (this.fixed) {
// 如之前有拖拽实例, 先销毁
if (this.#dragIns) {
this.#dragIns.destroy()
this.#dragIns = null
}
return
}
let $title = this.$refs.box.firstElementChild
this.#dragIns = new Drag(this.$refs.box).by($title, {
overflow: !!this.overflow
})
}
#intercept(value) {
if (this.intercept) {
this.intercept(value, _ => {
delete this.intercept
this.#resolve(value)
this.$animate(true)
this.$refs.box.$animate(true).then(_ => this.close())
})
} else {
this.#resolve(value)
this.$animate(true)
this.$refs.box.$animate(true).then(_ => this.close())
}
}
@ -349,21 +316,21 @@ class Layer extends Component {
fill: 'forwards'
}
)
setTimeout(() => {
elem._anim.reverse()
elem._anim.onfinish = _ => {
elem.remove()
}
if (this.children.length === 0) {
this.close()
toastInstance = null
if (this.children.length === 0) {
this.close()
toastInstance = null
}
}
}, 3000)
break
case 'notify':
break
default:
this.$animate()
this.$refs.box.$animate()
break
}
@ -375,6 +342,8 @@ class Layer extends Component {
bind(this.$refs.input, 'submit', ev => {
this.#intercept(ev.target.value)
})
} else if (this.type === 'toast') {
this.style.display = ''
}
// 有遮罩层时
@ -401,7 +370,9 @@ class Layer extends Component {
}
}
this.#toggleDrag()
if (this.background) {
this.$refs.box.style.backgroundColor = this.background
}
this.#play()
}
@ -426,49 +397,25 @@ class Layer extends Component {
/**
* 关闭实例
* @param force {Boolean} 是否强制关闭
*/
close(force) {
close() {
//
if (this.#wrapped) {
this.type = null
this.$emit('close')
} else {
// 有拖拽实例, 先销毁
if (this.#dragIns) {
this.#dragIns.destroy()
}
// 不允许多开的类型, 需要清除
if (UNIQUE_TYPES.includes(this.type)) {
uniqueInstance = null
}
// 离场动画
if (this.from && !force) {
let _style = 'opacity:0;'
for (let k in this.from) {
_style += `${k}:${this.from[k]};`
}
this.$refs.box.style.cssText += _style
this.timer = setTimeout(() => {
this.$emit('close')
this.remove()
}, 200)
} else {
clearTimeout(this.timer)
this.$emit('close')
this.remove()
}
this.$emit('close')
this.remove()
}
}
// 按钮的点击事件
handleBtnClick(ev) {
if (
ev.target.tagName === 'BUTTON' ||
ev.target.className === 'notify-button'
) {
if (ev.target.tagName === 'BUTTON') {
let idx = +ev.target.dataset.idx || 0
switch (this.type) {
@ -480,6 +427,7 @@ class Layer extends Component {
case 'prompt':
if (idx === 0) {
this.#reject()
this.$animate(true)
this.$refs.box.$animate(true).then(_ => this.close())
} else {
let value = this.type === 'prompt' ? this.$refs.input.value : null
@ -517,13 +465,6 @@ class Layer extends Component {
style=${styleMap({ display: !!this.title ? '' : 'none' })}
>
${this.title}
${this.type === 'notify'
? html`<wc-icon
name="close"
class="notify-button"
@click=${this.handleBtnClick}
></wc-icon>`
: ''}
</div>
<div class="layer__content">
<slot></slot>
@ -541,29 +482,19 @@ class Layer extends Component {
}
function layer(opt = {}) {
let layDom = document.createElement('wc-layer')
let { type = 'common', content = '' } = opt
let alreadyInTree = false
let layDom =
type === 'toast'
? toastInstance || document.createElement('wc-layer')
: document.createElement('wc-layer')
let alreadyInTree = type === 'toast' && !!toastInstance
layDom.type = opt.type
if (type === 'toast') {
opt = {
type,
content,
from: { top: 0 },
to: { top: '30px' }
}
if (toastInstance) {
// toastInstance.close(true)
layDom = toastInstance
alreadyInTree = true
} else {
toastInstance = layDom
}
toastInstance = layDom
layDom.top = '20px'
} else {
layDom.mask = opt.mask
if (opt.btns && opt.btns.length) {
layDom.btns = opt.btns
}
@ -573,50 +504,26 @@ function layer(opt = {}) {
}
layDom.mask = opt.mask
layDom['mask-close'] = opt['mask-close']
if (opt.hasOwnProperty('overflow')) {
layDom.overflow = opt.overflow
}
/* 额外样式 */
layDom.radius = opt.radius
layDom.background = opt.background
if (opt.size && typeof opt.size === 'object') {
layDom.size = opt.size
}
layDom.title = opt.title
// 这3种类型, 只允许同时存在1个, 如果之前有弹出则关闭
if (UNIQUE_TYPES.includes(opt.type)) {
if (UNIQUE_TYPES.includes(type)) {
if (uniqueInstance) {
uniqueInstance.close(true)
uniqueInstance.$animate(true).then(_ => {
uniqueInstance.close()
uniqueInstance = layDom
})
} else {
uniqueInstance = layDom
}
uniqueInstance = layDom
}
}
if (opt.to && typeof opt.to === 'object') {
layDom.to = opt.to
if (opt.from && typeof opt.from === 'object') {
layDom.from = opt.from
} else {
layDom.from = opt.to
}
}
layDom.type = opt.type
layDom.title = opt.title
layDom.fixed = !!opt.fixed
if (alreadyInTree) {
let tmp = document.createElement('template')
tmp.innerHTML = opt.content
tmp.innerHTML = content
layDom.appendChild(tmp.content.cloneNode(true))
layDom.updated()
} else {
layDom.innerHTML = content
@ -685,20 +592,6 @@ layer.prompt = function (title = LANG_TITLE, defaultValue = '', intercept) {
})
}
layer.notify = function (content) {
return this({
type: 'notify',
title: '通知',
content,
fixed: true,
mask: false,
top: 0,
right: 0,
from: { right: '-300px', top: 0 },
to: { right: 0 }
})
}
layer.toast = function (txt, type = 'info') {
var ico = type
switch (type) {