diff --git a/src/layer/index.js b/src/layer/index.js index 53b3273..2bf54ba 100644 --- a/src/layer/index.js +++ b/src/layer/index.js @@ -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`` - : ''}
@@ -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) {