Skip to content

Commit f6f6e8d

Browse files
committed
Fix for vue 3
1 parent 2dcc679 commit f6f6e8d

File tree

11 files changed

+12821
-42
lines changed

11 files changed

+12821
-42
lines changed

dist/index.js

Lines changed: 7 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

dist/index.nocss.js

Lines changed: 7 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

dist/ssr.index.js

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

dist/ssr.nocss.js

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -45,8 +45,9 @@
4545
"browserslist": "> 0.25%, not dead",
4646
"devDependencies": {
4747
"@babel/core": "^7.2.0",
48-
"@babel/preset-env": "^7.2.0",
48+
"@babel/plugin-proposal-object-rest-spread": "^7.20.7",
4949
"@babel/plugin-proposal-optional-chaining": "^7.10.3",
50+
"@babel/preset-env": "^7.2.0",
5051
"@vue/eslint-config-prettier": "^6.0.0",
5152
"@vue/test-utils": "1.0.0-beta.31",
5253
"babel-jest": "^23.6.0",
@@ -60,7 +61,7 @@
6061
"jest": "^23.6.0",
6162
"jest-serializer-vue": "^2.0.2",
6263
"mini-css-extract-plugin": "^0.4.5",
63-
"node-sass": "^4.13.1",
64+
"node-sass": "^9.0.0",
6465
"optimize-css-assets-webpack-plugin": "^5.0.1",
6566
"sass-loader": "^7.1.0",
6667
"ts-loader": "^6.2.2",
@@ -81,6 +82,7 @@
8182
"vue": "^2.6.11"
8283
},
8384
"dependencies": {
84-
"resize-observer-polyfill": "^1.5.1"
85+
"resize-observer-polyfill": "^1.5.1",
86+
"tiny-emitter": "^2.1.0"
8587
}
8688
}

src/Plugin.js

Lines changed: 12 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -3,45 +3,37 @@ import Dialog from './components/Dialog.vue'
33
import PluginCore from './PluginCore'
44

55
const Plugin = {
6-
install(Vue, options = {}) {
7-
if (Vue.prototype.$modal) {
6+
install(app, options = {}) {
7+
if (app.config.globalProperties.$modal) {
88
return
99
}
1010

11-
const plugin = new PluginCore(Vue, options)
11+
const plugin = PluginCore(options)
1212

13-
Object.defineProperty(Vue.prototype, '$modal', {
14-
get: function() {
15-
/**
16-
* The "this" scope is the scope of the component that calls this.$modal
17-
*/
18-
const caller = this
19-
/**
20-
* The this.$modal can be called only from inside the vue components so this check is not really needed...
21-
*/
22-
if (caller instanceof Vue) {
23-
const root = caller.$root
13+
app.config.globalProperties.$modal = plugin
14+
app.provide('$modal', plugin)
2415

16+
app.mixin({
17+
mounted() {
18+
if (this.$root === this) {
2519
if (!plugin.context.root) {
26-
plugin.setDynamicModalContainer(root)
20+
plugin.setDynamicModalContainer(this)
2721
}
2822
}
29-
30-
return plugin
3123
}
3224
})
3325

3426
/**
3527
* Sets custom component name (if provided)
3628
*/
37-
Vue.component(plugin.context.componentName, Modal)
29+
app.component(plugin.context.componentName, Modal)
3830

3931
/**
4032
* Registration of <Dialog/> component
4133
*/
4234
if (options.dialog) {
43-
const componentName = options.dialogComponentName || 'VDialog';
44-
Vue.component(componentName, Dialog);
35+
const componentName = options.dialogComponentName || 'VDialog'
36+
app.component(componentName, Dialog)
4537
}
4638
}
4739
}

src/PluginCore.js

Lines changed: 39 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,24 @@
11
import { UNSUPPORTED_ARGUMENT_ERROR } from './utils/errors'
22
import { createDivInBody } from './utils'
33
import ModalsContainer from './components/ModalsContainer.vue'
4-
5-
const PluginCore = (Vue, options = {}) => {
6-
const subscription = new Vue()
4+
import emitter from 'tiny-emitter/instance'
5+
import { createVNode, render } from 'vue'
6+
7+
const PluginCore = (app, options = {}) => {
8+
const subscription = {
9+
$on: (...args) => emitter.on(...args),
10+
$once: (...args) => emitter.once(...args),
11+
$off: (...args) => emitter.off(...args),
12+
$emit: (...args) => emitter.emit(...args)
13+
}
714

815
const context = {
916
root: null,
1017
componentName: options.componentName || 'Modal'
1118
}
19+
subscription.$on('set-modal-container', (container) => {
20+
context.root.__modalContainer = container
21+
})
1222

1323
const showStaticModal = (name, params) => {
1424
subscription.$emit('toggle', name, true, params)
@@ -18,13 +28,19 @@ const PluginCore = (Vue, options = {}) => {
1828
component,
1929
componentProps,
2030
componentSlots,
21-
modalProps = {},
31+
modalProps = componentSlots || {},
2232
modalEvents
2333
) => {
2434
const container = context.root?.__modalContainer
2535
const defaults = options.dynamicDefaults || {}
2636

27-
container?.add(
37+
if (!container) {
38+
console.warn(
39+
'Modal container not found. Make sure the dynamic modal container is set.'
40+
)
41+
return
42+
}
43+
container.add(
2844
component,
2945
componentProps,
3046
componentSlots,
@@ -37,16 +53,28 @@ const PluginCore = (Vue, options = {}) => {
3753
* Creates a container for modals in the root Vue component.
3854
*
3955
* @param {Vue} parent
56+
* @param {Vue} app
4057
*/
41-
const setDynamicModalContainer = parent => {
42-
context.root = parent
58+
const setDynamicModalContainer = (root) => {
59+
context.root = root
60+
61+
if (!root) {
62+
console.warn(
63+
'Root component is undefined. Make sure the root instance is passed correctly.'
64+
)
65+
return
66+
}
4367

4468
const element = createDivInBody()
4569

46-
new Vue({
47-
parent,
48-
render: h => h(ModalsContainer)
49-
}).$mount(element)
70+
const vnode = createVNode(ModalsContainer)
71+
vnode.appContext = root.$.appContext
72+
73+
try {
74+
return render(vnode, element)
75+
} catch (error) {
76+
console.error('Error rendering vnode:', error)
77+
}
5078
}
5179

5280
const show = (...args) => {

src/components/Dialog.vue

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@
3131
:key="index"
3232
v-html="button.title"
3333
@click.stop="click(index, $event)"
34-
>{{ button.title }}</button>
34+
/>
3535
</div>
3636
<div v-else class="vue-dialog-buttons-none" />
3737
</component>
@@ -52,6 +52,7 @@ export default {
5252
type: String
5353
}
5454
},
55+
inject: ['$modal'],
5556
data() {
5657
return {
5758
params: {}

src/components/Modal.vue

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,7 @@ const TransitionState = {
7777
7878
export default {
7979
name: 'VueJsModal',
80+
inject: ['$modal'],
8081
props: {
8182
name: {
8283
required: true,
@@ -263,7 +264,7 @@ export default {
263264
/**
264265
* Removes global listeners
265266
*/
266-
beforeDestroy() {
267+
beforeUnmount() {
267268
this.$modal.subscription.$off('toggle', this.onToggle)
268269
269270
window.removeEventListener('resize', this.onWindowResize)
@@ -498,7 +499,9 @@ export default {
498499
499500
beforeModalTransitionLeave() {
500501
this.modalTransitionState = TransitionState.Leaving
501-
this.resizeObserver.unobserve(this.$refs.modal)
502+
if (this.$refs.modal) {
503+
this.resizeObserver.unobserve(this.$refs.modal)
504+
}
502505
503506
if (this.$focusTrap.enabled()) {
504507
this.$focusTrap.disable()

src/components/ModalsContainer.vue

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
<component
1111
:is="modal.component"
1212
v-bind="modal.componentAttrs"
13-
v-on="$listeners"
13+
v-on="modal.componentListeners"
1414
@close="$modal.hide(modal.modalAttrs.name, $event)"
1515
>
1616
<template v-for="(slot, key) in modal.componentSlots" #[key]="scope">
@@ -40,6 +40,7 @@ export default {
4040
* Register ModalContainer so that it was availiable inside the plugin
4141
*/
4242
this.$root.__modalContainer = this
43+
this.$modal.subscription.$emit('set-modal-container', this)
4344
},
4445
mounted() {
4546
this.$modal.subscription.$on('hide-all', () => {

0 commit comments

Comments
 (0)