Skip to content

Commit

Permalink
Patch from euvl#814
Browse files Browse the repository at this point in the history
  • Loading branch information
kalnado committed May 23, 2024
1 parent 2dcc679 commit 7b99e6a
Show file tree
Hide file tree
Showing 5 changed files with 37 additions and 21 deletions.
19 changes: 10 additions & 9 deletions src/Plugin.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,14 @@ import Dialog from './components/Dialog.vue'
import PluginCore from './PluginCore'

const Plugin = {
install(Vue, options = {}) {
if (Vue.prototype.$modal) {
install(app, options = {}) {
if (app.config.globalProperties.$modal) {
return
}

const plugin = new PluginCore(Vue, options)
const plugin = PluginCore(app, options)

Object.defineProperty(Vue.prototype, '$modal', {
Object.defineProperty(app.config.globalProperties, '$modal', {
get: function() {
/**
* The "this" scope is the scope of the component that calls this.$modal
Expand All @@ -19,29 +19,30 @@ const Plugin = {
/**
* The this.$modal can be called only from inside the vue components so this check is not really needed...
*/
if (caller instanceof Vue) {
// if (caller instanceof app) {
const root = caller.$root

if (!plugin.context.root) {
plugin.setDynamicModalContainer(root)
plugin.setDynamicModalContainer(root, app)
}
}
// }

return plugin
}
})
app.provide('$modal', plugin)

/**
* Sets custom component name (if provided)
*/
Vue.component(plugin.context.componentName, Modal)
app.component(plugin.context.componentName, Modal)

/**
* Registration of <Dialog/> component
*/
if (options.dialog) {
const componentName = options.dialogComponentName || 'VDialog';
Vue.component(componentName, Dialog);
app.component(componentName, Dialog);
}
}
}
Expand Down
28 changes: 19 additions & 9 deletions src/PluginCore.js
Original file line number Diff line number Diff line change
@@ -1,14 +1,24 @@
import { UNSUPPORTED_ARGUMENT_ERROR } from './utils/errors'
import { createDivInBody } from './utils'
import ModalsContainer from './components/ModalsContainer.vue'

const PluginCore = (Vue, options = {}) => {
const subscription = new Vue()
import emitter from 'tiny-emitter/instance'
import {createVNode, render} from 'vue'

const PluginCore = (app, options = {}) => {
const subscription = {
$on: (...args) => emitter.on(...args),
$once: (...args) => emitter.once(...args),
$off: (...args) => emitter.off(...args),
$emit: (...args) => emitter.emit(...args),
}

const context = {
root: null,
componentName: options.componentName || 'Modal'
}
subscription.$on('set-modal-container', container => {
context.root.__modalContainer = container
})

const showStaticModal = (name, params) => {
subscription.$emit('toggle', name, true, params)
Expand Down Expand Up @@ -37,17 +47,17 @@ const PluginCore = (Vue, options = {}) => {
* Creates a container for modals in the root Vue component.
*
* @param {Vue} parent
* @param {Vue} app
*/
const setDynamicModalContainer = parent => {
const setDynamicModalContainer = ((parent, app) => {
context.root = parent

const element = createDivInBody()

new Vue({
parent,
render: h => h(ModalsContainer)
}).$mount(element)
}
const vnode = createVNode(ModalsContainer)
vnode.appContext = app._context
render(vnode, element)
})

const show = (...args) => {
const [modal] = args
Expand Down
3 changes: 2 additions & 1 deletion src/components/Dialog.vue
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@
:key="index"
v-html="button.title"
@click.stop="click(index, $event)"
>{{ button.title }}</button>
/>
</div>
<div v-else class="vue-dialog-buttons-none" />
</component>
Expand All @@ -52,6 +52,7 @@ export default {
type: String
}
},
inject: ['$modal'],
data() {
return {
params: {}
Expand Down
7 changes: 5 additions & 2 deletions src/components/Modal.vue
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ const TransitionState = {
export default {
name: 'VueJsModal',
inject: ['$modal'],
props: {
name: {
required: true,
Expand Down Expand Up @@ -263,7 +264,7 @@ export default {
/**
* Removes global listeners
*/
beforeDestroy() {
beforeUnmount() {
this.$modal.subscription.$off('toggle', this.onToggle)
window.removeEventListener('resize', this.onWindowResize)
Expand Down Expand Up @@ -498,7 +499,9 @@ export default {
beforeModalTransitionLeave() {
this.modalTransitionState = TransitionState.Leaving
this.resizeObserver.unobserve(this.$refs.modal)
if (this.$refs.modal) {
this.resizeObserver.unobserve(this.$refs.modal)
}
if (this.$focusTrap.enabled()) {
this.$focusTrap.disable()
Expand Down
1 change: 1 addition & 0 deletions src/components/ModalsContainer.vue
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ export default {
* Register ModalContainer so that it was availiable inside the plugin
*/
this.$root.__modalContainer = this
this.$modal.subscription.$emit('set-modal-container', this)
},
mounted() {
this.$modal.subscription.$on('hide-all', () => {
Expand Down

0 comments on commit 7b99e6a

Please sign in to comment.