Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix for vue 3 #817

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 7 additions & 1 deletion dist/index.js

Large diffs are not rendered by default.

8 changes: 7 additions & 1 deletion dist/index.nocss.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion dist/ssr.index.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion dist/ssr.nocss.js

Large diffs are not rendered by default.

8 changes: 5 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,9 @@
"browserslist": "> 0.25%, not dead",
"devDependencies": {
"@babel/core": "^7.2.0",
"@babel/preset-env": "^7.2.0",
"@babel/plugin-proposal-object-rest-spread": "^7.20.7",
"@babel/plugin-proposal-optional-chaining": "^7.10.3",
"@babel/preset-env": "^7.2.0",
"@vue/eslint-config-prettier": "^6.0.0",
"@vue/test-utils": "1.0.0-beta.31",
"babel-jest": "^23.6.0",
Expand All @@ -60,7 +61,7 @@
"jest": "^23.6.0",
"jest-serializer-vue": "^2.0.2",
"mini-css-extract-plugin": "^0.4.5",
"node-sass": "^4.13.1",
"node-sass": "^9.0.0",
"optimize-css-assets-webpack-plugin": "^5.0.1",
"sass-loader": "^7.1.0",
"ts-loader": "^6.2.2",
Expand All @@ -81,6 +82,7 @@
"vue": "^2.6.11"
},
"dependencies": {
"resize-observer-polyfill": "^1.5.1"
"resize-observer-polyfill": "^1.5.1",
"tiny-emitter": "^2.1.0"
}
}
32 changes: 12 additions & 20 deletions src/Plugin.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,45 +3,37 @@ 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(options)

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

app.mixin({
mounted() {
if (this.$root === this) {
if (!plugin.context.root) {
plugin.setDynamicModalContainer(root)
plugin.setDynamicModalContainer(this)
}
}

return 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);
const componentName = options.dialogComponentName || 'VDialog'
app.component(componentName, Dialog)
}
}
}
Expand Down
50 changes: 39 additions & 11 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 All @@ -18,13 +28,19 @@ const PluginCore = (Vue, options = {}) => {
component,
componentProps,
componentSlots,
modalProps = {},
modalProps = componentSlots || {},
modalEvents
) => {
const container = context.root?.__modalContainer
const defaults = options.dynamicDefaults || {}

container?.add(
if (!container) {
console.warn(
'Modal container not found. Make sure the dynamic modal container is set.'
)
return
}
container.add(
component,
componentProps,
componentSlots,
Expand All @@ -37,16 +53,28 @@ const PluginCore = (Vue, options = {}) => {
* Creates a container for modals in the root Vue component.
*
* @param {Vue} parent
* @param {Vue} app
*/
const setDynamicModalContainer = parent => {
context.root = parent
const setDynamicModalContainer = (root) => {
context.root = root

if (!root) {
console.warn(
'Root component is undefined. Make sure the root instance is passed correctly.'
)
return
}

const element = createDivInBody()

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

try {
return render(vnode, element)
} catch (error) {
console.error('Error rendering vnode:', error)
}
}

const show = (...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
3 changes: 2 additions & 1 deletion src/components/ModalsContainer.vue
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
<component
:is="modal.component"
v-bind="modal.componentAttrs"
v-on="$listeners"
v-on="modal.componentListeners"
@close="$modal.hide(modal.modalAttrs.name, $event)"
>
<template v-for="(slot, key) in modal.componentSlots" #[key]="scope">
Expand Down 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
Loading