Merge branch 'master' of ssh://github.com/bd-js/wcui
commit
8d9c42b019
|
@ -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
|
||||
}
|
||||
}
|
||||
}, 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()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 按钮的点击事件
|
||||
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
|
||||
}
|
||||
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
|
||||
}
|
||||
}
|
||||
|
||||
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) {
|
||||
|
|
Loading…
Reference in New Issue