UNPKG

element-plus

Version:

A Component Library for Vue 3

1 lines 9.58 kB
{"version":3,"file":"messageBox.mjs","names":["MessageBoxConstructor"],"sources":["../../../../../../packages/components/message-box/src/messageBox.ts"],"sourcesContent":["import { createVNode, isVNode, markRaw, render } from 'vue'\nimport {\n debugWarn,\n hasOwn,\n isClient,\n isElement,\n isFunction,\n isObject,\n isString,\n isUndefined,\n} from '@element-plus/utils'\nimport MessageBoxConstructor from './index.vue'\n\nimport type { AppContext, ComponentPublicInstance, VNode } from 'vue'\nimport type {\n Action,\n Callback,\n CloseFn,\n ElMessageBoxOptions,\n ElMessageBoxShortcutMethod,\n IElMessageBox,\n MessageBoxData,\n MessageBoxState,\n} from './message-box.type'\n\n// component default merge props & data\n\nconst messageInstance = new Map<\n ComponentPublicInstance<{ doClose: CloseFn }>, // marking doClose as function\n {\n options: any\n callback: Callback | undefined\n resolve: (res: any) => void\n reject: (reason?: any) => void\n }\n>()\n\nconst getAppendToElement = (props: any): HTMLElement => {\n let appendTo: HTMLElement | null = document.body\n if (props.appendTo) {\n if (isString(props.appendTo)) {\n appendTo = document.querySelector<HTMLElement>(props.appendTo)\n }\n if (isElement(props.appendTo)) {\n appendTo = props.appendTo\n }\n\n // should fallback to default value with a warning\n if (!isElement(appendTo)) {\n debugWarn(\n 'ElMessageBox',\n 'the appendTo option is not an HTMLElement. Falling back to document.body.'\n )\n appendTo = document.body\n }\n }\n return appendTo\n}\n\nconst handleAction = (vnode: VNode, action: Action) => {\n const vm = vnode.component?.proxy as ComponentPublicInstance<{\n handleAction: (action: Action) => void\n }>\n return () => vm.handleAction(action)\n}\n\nconst initInstance = (\n props: any,\n container: HTMLElement,\n appContext: AppContext | null = null\n) => {\n const vnode = createVNode(\n MessageBoxConstructor,\n props,\n isFunction(props.message) || isVNode(props.message)\n ? {\n default: isFunction(props.message)\n ? () =>\n props.message({\n confirm: handleAction(vnode, 'confirm'),\n cancel: handleAction(vnode, 'cancel'),\n close: handleAction(vnode, 'close'),\n })\n : () => props.message,\n }\n : null\n )\n vnode.appContext = appContext\n render(vnode, container)\n getAppendToElement(props).appendChild(container.firstElementChild!)\n return vnode.component\n}\n\nconst genContainer = () => {\n return document.createElement('div')\n}\n\nconst showMessage = (options: any, appContext?: AppContext | null) => {\n const container = genContainer()\n // Adding destruct method.\n // when transition leaves emitting `vanish` evt. so that we can do the clean job.\n options.onVanish = () => {\n // not sure if this causes mem leak, need proof to verify that.\n // maybe calling out like 1000 msg-box then close them all.\n render(null, container)\n messageInstance.delete(vm) // Remove vm to avoid mem leak.\n // here we were suppose to call document.body.removeChild(container.firstElementChild)\n // but render(null, container) did that job for us. so that we do not call that directly\n }\n\n options.onAction = (action: Action) => {\n const currentMsg = messageInstance.get(vm)!\n let resolve: Action | { value: string; action: Action }\n if (options.showInput) {\n resolve = { value: vm.inputValue, action }\n } else {\n resolve = action\n }\n if (options.callback) {\n options.callback(resolve, instance.proxy)\n } else {\n if (action === 'cancel' || action === 'close') {\n if (options.distinguishCancelAndClose && action !== 'cancel') {\n currentMsg.reject('close')\n } else {\n currentMsg.reject('cancel')\n }\n } else {\n currentMsg.resolve(resolve)\n }\n }\n }\n\n const instance = initInstance(options, container, appContext)!\n\n // This is how we use message box programmatically.\n // Maybe consider releasing a template version?\n // get component instance like v2.\n const vm = instance.proxy as ComponentPublicInstance<\n {\n visible: boolean\n doClose: CloseFn\n } & MessageBoxState\n >\n\n for (const prop in options) {\n if (hasOwn(options, prop) && !hasOwn(vm.$props, prop)) {\n if (prop === 'closeIcon' && isObject(options[prop])) {\n vm[prop as keyof ComponentPublicInstance] = markRaw(options[prop])\n } else {\n vm[prop as keyof ComponentPublicInstance] = options[prop]\n }\n }\n }\n\n // change visibility after everything is settled\n vm.visible = true\n return vm\n}\n\nasync function MessageBox(\n options: ElMessageBoxOptions,\n appContext?: AppContext | null\n): Promise<MessageBoxData>\nfunction MessageBox(\n options: ElMessageBoxOptions | string | VNode,\n appContext: AppContext | null = null\n): Promise<MessageBoxData> {\n if (!isClient) return Promise.reject()\n let callback: Callback | undefined\n if (isString(options) || isVNode(options)) {\n options = {\n message: options,\n }\n } else {\n callback = options.callback\n }\n\n return new Promise((resolve, reject) => {\n const vm = showMessage(\n options,\n appContext ?? (MessageBox as IElMessageBox)._context\n )\n // collect this vm in order to handle upcoming events.\n messageInstance.set(vm, {\n options,\n callback,\n resolve,\n reject,\n })\n })\n}\n\nconst MESSAGE_BOX_VARIANTS = ['alert', 'confirm', 'prompt'] as const\nconst MESSAGE_BOX_DEFAULT_OPTS: Record<\n (typeof MESSAGE_BOX_VARIANTS)[number],\n Partial<ElMessageBoxOptions>\n> = {\n alert: { closeOnPressEscape: false, closeOnClickModal: false },\n confirm: { showCancelButton: true },\n prompt: { showCancelButton: true, showInput: true },\n}\n\nMESSAGE_BOX_VARIANTS.forEach((boxType) => {\n ;(MessageBox as IElMessageBox)[boxType] = messageBoxFactory(\n boxType\n ) as ElMessageBoxShortcutMethod\n})\n\nfunction messageBoxFactory(boxType: (typeof MESSAGE_BOX_VARIANTS)[number]) {\n return (\n message: string | VNode,\n title: string | ElMessageBoxOptions,\n options?: ElMessageBoxOptions,\n appContext?: AppContext | null\n ) => {\n let titleOrOpts = ''\n if (isObject(title)) {\n options = title as ElMessageBoxOptions\n titleOrOpts = ''\n } else if (isUndefined(title)) {\n titleOrOpts = ''\n } else {\n titleOrOpts = title as string\n }\n\n return MessageBox(\n Object.assign(\n {\n title: titleOrOpts,\n message,\n type: '',\n ...MESSAGE_BOX_DEFAULT_OPTS[boxType],\n },\n options,\n {\n boxType,\n }\n ),\n appContext\n )\n }\n}\n\nMessageBox.close = () => {\n // instance.setupInstall.doClose()\n // instance.setupInstall.state.visible = false\n\n messageInstance.forEach((_, vm) => {\n vm.doClose()\n })\n\n messageInstance.clear()\n}\n;(MessageBox as IElMessageBox)._context = null\n\nexport default MessageBox as IElMessageBox\n"],"mappings":"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"}