quasar
Version:
Build high-performance VueJS user interfaces (SPA, PWA, SSR, Mobile and Desktop) in record time
179 lines (151 loc) • 4.22 kB
JavaScript
import { h, ref, nextTick } from 'vue'
import { createChildApp } from '../../install-quasar.js'
import { createGlobalNode, removeGlobalNode } from '../private.config/nodes.js'
const ssrAPI = {
onOk: () => ssrAPI,
onCancel: () => ssrAPI,
onDismiss: () => ssrAPI,
hide: () => ssrAPI,
update: () => ssrAPI
}
export function merge(target, source) {
for (const key in source) {
if (key !== 'spinner' && Object(source[key]) === source[key]) {
target[key] =
Object(target[key]) !== target[key] ? {} : { ...target[key] }
merge(target[key], source[key])
} else {
target[key] = source[key]
}
}
}
export default function createDialog(
DefaultComponent,
supportsCustomComponent,
parentApp
) {
return pluginProps => {
if (__QUASAR_SSR_SERVER__) {
return ssrAPI
}
let DialogComponent, props
const isCustom =
supportsCustomComponent === true && pluginProps.component !== void 0
if (isCustom === true) {
const { component, componentProps } = pluginProps
DialogComponent =
typeof component === 'string'
? parentApp.component(component)
: component
props = componentProps || {}
} else {
const { class: klass, style, ...otherProps } = pluginProps
DialogComponent = DefaultComponent
props = otherProps
if (klass !== void 0) otherProps.cardClass = klass
if (style !== void 0) otherProps.cardStyle = style
}
let vm,
emittedOK = false
const dialogRef = ref(null)
const el = createGlobalNode(false, 'dialog')
const applyState = cmd => {
if (dialogRef.value?.[cmd] !== void 0) {
dialogRef.value[cmd]()
return
}
const target = vm.$.subTree
if (target?.component) {
// account for "script setup" way of declaring component
if (target.component.proxy && target.component.proxy[cmd]) {
target.component.proxy[cmd]()
return
}
// account for "script setup" + async component way of declaring component
if (
target.component.subTree &&
target.component.subTree.component &&
target.component.subTree.component.proxy &&
target.component.subTree.component.proxy[cmd]
) {
target.component.subTree.component.proxy[cmd]()
return
}
}
console.error('[Quasar] Incorrectly defined Dialog component')
}
const okFns = [],
cancelFns = [],
API = {
onOk(fn) {
okFns.push(fn)
return API
},
onCancel(fn) {
cancelFns.push(fn)
return API
},
onDismiss(fn) {
okFns.push(fn)
cancelFns.push(fn)
return API
},
hide() {
applyState('hide')
return API
},
update(componentProps) {
if (vm !== null) {
if (isCustom === true) {
Object.assign(props, componentProps)
} else {
const { class: klass, style, ...cfg } = componentProps
if (klass !== void 0) cfg.cardClass = klass
if (style !== void 0) cfg.cardStyle = style
merge(props, cfg)
}
vm.$forceUpdate()
}
return API
}
}
const onOk = data => {
emittedOK = true
okFns.forEach(fn => {
fn(data)
})
}
const onHide = () => {
app.unmount(el)
removeGlobalNode(el)
app = null
vm = null
if (emittedOK !== true) {
cancelFns.forEach(fn => {
fn()
})
}
}
let app = createChildApp(
{
name: 'QGlobalDialog',
setup: () => () =>
h(DialogComponent, {
...props,
ref: dialogRef,
onOk,
onHide,
onVnodeMounted(...args) {
if (typeof props.onVnodeMounted === 'function') {
props.onVnodeMounted(...args)
}
nextTick(() => applyState('show'))
}
})
},
parentApp
)
vm = app.mount(el)
return API
}
}