From 7eda33eb442cf7d98d8cee58ceacae77fde5ad87 Mon Sep 17 00:00:00 2001 From: neverland Date: Thu, 21 Mar 2019 10:08:26 +0800 Subject: [PATCH] [improvement] popup mixin ts (#3022) --- packages/mixins/popup/context.js | 9 ---- packages/mixins/popup/context.ts | 17 +++++++ packages/mixins/popup/index.js | 10 ++-- packages/mixins/popup/manager.js | 77 ------------------------------- packages/mixins/popup/overlay.ts | 78 ++++++++++++++++++++++++++++++++ 5 files changed, 100 insertions(+), 91 deletions(-) delete mode 100644 packages/mixins/popup/context.js create mode 100644 packages/mixins/popup/context.ts delete mode 100644 packages/mixins/popup/manager.js create mode 100644 packages/mixins/popup/overlay.ts diff --git a/packages/mixins/popup/context.js b/packages/mixins/popup/context.js deleted file mode 100644 index 16a625206..000000000 --- a/packages/mixins/popup/context.js +++ /dev/null @@ -1,9 +0,0 @@ -export default { - zIndex: 2000, - stack: [], - lockCount: 0, - - get top() { - return this.stack[this.stack.length - 1]; - } -}; diff --git a/packages/mixins/popup/context.ts b/packages/mixins/popup/context.ts new file mode 100644 index 000000000..3da90ea7d --- /dev/null +++ b/packages/mixins/popup/context.ts @@ -0,0 +1,17 @@ +import { OverlayConfig } from './overlay'; + +export type StackItem = { + vm: any; + target: HTMLElement; + config: OverlayConfig; +}; + +export const context = { + zIndex: 2000, + lockCount: 0, + stack: [] as StackItem[], + + get top(): StackItem { + return this.stack[this.stack.length - 1]; + } +}; diff --git a/packages/mixins/popup/index.js b/packages/mixins/popup/index.js index ab922a21e..912432a4d 100644 --- a/packages/mixins/popup/index.js +++ b/packages/mixins/popup/index.js @@ -1,7 +1,7 @@ -import manager from './manager'; -import context from './context'; +import { context } from './context'; import { TouchMixin } from '../touch'; import { on, off } from '../../utils/event'; +import { openOverlay, closeOverlay } from './overlay'; import { getScrollEventTarget } from '../../utils/scroll'; export const PopupMixin = { @@ -134,7 +134,7 @@ export const PopupMixin = { } this.opened = false; - manager.close(this); + closeOverlay(this); this.$emit('input', false); }, @@ -187,13 +187,13 @@ export const PopupMixin = { renderOverlay() { if (this.overlay) { - manager.open(this, { + openOverlay(this, { zIndex: context.zIndex++, className: this.overlayClass, customStyle: this.overlayStyle }); } else { - manager.close(this); + closeOverlay(this); } this.$nextTick(() => { diff --git a/packages/mixins/popup/manager.js b/packages/mixins/popup/manager.js deleted file mode 100644 index b731d5ae2..000000000 --- a/packages/mixins/popup/manager.js +++ /dev/null @@ -1,77 +0,0 @@ -import context from './context'; -import Overlay from '../../overlay'; -import { mount } from '../../utils/functional'; - -const defaultConfig = { - className: '', - customStyle: {} -}; - -export default { - open(vm, config) { - /* istanbul ignore next */ - if (!context.stack.some(item => item.vm === vm)) { - const el = vm.$el; - const target = el && el.parentNode ? el.parentNode : document.body; - context.stack.push({ vm, config, target }); - this.update(); - } - }, - - close(vm) { - const { stack } = context; - - if (stack.length) { - if (context.top.vm === vm) { - stack.pop(); - this.update(); - } else { - context.stack = stack.filter(item => item.vm !== vm); - } - } - }, - - update() { - let { modal } = context; - - if (!modal) { - modal = mount(Overlay, { - on: { - click: this.onClick - } - }); - - context.modal = modal; - } - - if (modal.$el.parentNode) { - modal.visible = false; - } - - if (context.top) { - const { target, config } = context.top; - - target.appendChild(modal.$el); - Object.assign(modal, defaultConfig, config, { - visible: true - }); - } - }, - - // close popup when click modal && closeOnClickOverlay is true - onClick() { - /* istanbul ignore else */ - if (context.top) { - const { vm } = context.top; - vm.$emit('click-overlay'); - - if (vm.closeOnClickOverlay) { - if (vm.onClickOverlay) { - vm.onClickOverlay(); - } else { - vm.close(); - } - } - } - } -}; diff --git a/packages/mixins/popup/overlay.ts b/packages/mixins/popup/overlay.ts new file mode 100644 index 000000000..9ea07a128 --- /dev/null +++ b/packages/mixins/popup/overlay.ts @@ -0,0 +1,78 @@ +import Overlay from '../../overlay'; +import { context } from './context'; +import { mount } from '../../utils/functional'; + +export type OverlayConfig = { + zIndex?: number; + className?: string; + customStyle?: object[] | object; +}; + +const defaultConfig: OverlayConfig = { + className: '', + customStyle: {} +}; + +let overlay: any; + +// close popup when click overlay && closeOnClickOverlay is true +function onClickOverlay(): void { + if (context.top) { + const { vm } = context.top; + vm.$emit('click-overlay'); + + if (vm.closeOnClickOverlay) { + if (vm.onClickOverlay) { + vm.onClickOverlay(); + } else { + vm.close(); + } + } + } +} + +function updateOverlay(): void { + if (!overlay) { + overlay = mount(Overlay, { + on: { + click: onClickOverlay + } + }); + } + + if (overlay.$el.parentNode) { + overlay.visible = false; + } + + if (context.top) { + const { target, config } = context.top; + + target.appendChild(overlay.$el); + Object.assign(overlay, defaultConfig, config, { + visible: true + }); + } +} + +export function openOverlay(vm: any, config: OverlayConfig): void { + /* istanbul ignore next */ + if (!context.stack.some(item => item.vm === vm)) { + const el = vm.$el; + const target = el && el.parentNode ? el.parentNode : document.body; + context.stack.push({ vm, config, target }); + updateOverlay(); + } +} + +export function closeOverlay(vm: any): void { + const { stack } = context; + + if (stack.length) { + if (context.top.vm === vm) { + stack.pop(); + updateOverlay(); + } else { + context.stack = stack.filter(item => item.vm !== vm); + } + } +}