promise-portal 1.0.3 → 1.0.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +56 -3
- package/dist/index.cjs +97 -0
- package/dist/index.d.ts +24 -0
- package/dist/index.js +68 -0
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -15,6 +15,60 @@ npm install promise-portal -D
|
|
|
15
15
|
yarn add promise-portal --D
|
|
16
16
|
```
|
|
17
17
|
|
|
18
|
+
## Relative Resourece
|
|
19
|
+
|
|
20
|
+
- [react protal](https://reactjs.org/docs/portals.html)
|
|
21
|
+
- [vue teleport](https://vuejs.org/guide/built-ins/teleport.html)
|
|
22
|
+
|
|
23
|
+
## Why
|
|
24
|
+
|
|
25
|
+
like element-plus, the modal is a vue component
|
|
26
|
+
|
|
27
|
+
in development, we want use modal like a function
|
|
28
|
+
|
|
29
|
+
no `show` property to control show/hide, gettting result is more explicit
|
|
30
|
+
|
|
31
|
+
easier to control workflow, and easier to handle life-cycles
|
|
32
|
+
|
|
33
|
+
### Before
|
|
34
|
+
|
|
35
|
+
use as acomponent, with ref value to control visibility and life-cycles
|
|
36
|
+
|
|
37
|
+
```ts
|
|
38
|
+
<script setup lang="ts">
|
|
39
|
+
import Comp from './components/name.vue'
|
|
40
|
+
const show = ref(false)
|
|
41
|
+
const onClick = () => {
|
|
42
|
+
show.value = true
|
|
43
|
+
}
|
|
44
|
+
const onClosed = () => {
|
|
45
|
+
show.value = false
|
|
46
|
+
}
|
|
47
|
+
</script>
|
|
48
|
+
<template>
|
|
49
|
+
<el-button @click="onClick"> click to open the Dialog </el-button>
|
|
50
|
+
<Comp v-model="show" @closed="onClosed"> a dialog content </Comp>
|
|
51
|
+
</template>
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
### After
|
|
55
|
+
|
|
56
|
+
use as a normal promise-style function, so happy to develop
|
|
57
|
+
|
|
58
|
+
```ts
|
|
59
|
+
<script setup lang="ts">
|
|
60
|
+
import Comp, { Input, Output } from './components/name.vue'
|
|
61
|
+
const func = definePortal<Output, Input>(Comp)
|
|
62
|
+
const onClick = async () => {
|
|
63
|
+
const data = await func()
|
|
64
|
+
console.log(data)
|
|
65
|
+
}
|
|
66
|
+
</script>
|
|
67
|
+
<template>
|
|
68
|
+
<el-button @click="onClick"> click to open the Dialog </el-button>
|
|
69
|
+
</template>
|
|
70
|
+
```
|
|
71
|
+
|
|
18
72
|
## Use
|
|
19
73
|
|
|
20
74
|
### install in the entry file
|
|
@@ -171,6 +225,5 @@ const onClick = async () => {
|
|
|
171
225
|
|
|
172
226
|
## Link
|
|
173
227
|
|
|
174
|
-
[@filez/portal](https://github.com/lenovo-filez/portal)
|
|
175
|
-
|
|
176
|
-
[promise-modal](https://github.com/liruifengv/promise-modal)
|
|
228
|
+
- [@filez/portal](https://github.com/lenovo-filez/portal)
|
|
229
|
+
- [promise-modal](https://github.com/liruifengv/promise-modal)
|
package/dist/index.cjs
ADDED
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
|
|
20
|
+
// src/index.ts
|
|
21
|
+
var src_exports = {};
|
|
22
|
+
__export(src_exports, {
|
|
23
|
+
createPromisePortal: () => createPromisePortal,
|
|
24
|
+
definePortal: () => definePortal,
|
|
25
|
+
getActiveInstance: () => getActiveInstance,
|
|
26
|
+
setActiveInstance: () => setActiveInstance,
|
|
27
|
+
usePortalContext: () => usePortalContext
|
|
28
|
+
});
|
|
29
|
+
module.exports = __toCommonJS(src_exports);
|
|
30
|
+
var import_vue = require("vue");
|
|
31
|
+
var promisePortalSymbol = process.env.NODE_ENV !== "production" ? Symbol("promise-portal") : Symbol();
|
|
32
|
+
var activeInstance;
|
|
33
|
+
var getActiveInstance = () => activeInstance;
|
|
34
|
+
var setActiveInstance = (instance) => activeInstance = instance;
|
|
35
|
+
var createPromisePortal = () => {
|
|
36
|
+
const instance = {
|
|
37
|
+
app: void 0,
|
|
38
|
+
map: /* @__PURE__ */ new WeakMap(),
|
|
39
|
+
install(app) {
|
|
40
|
+
instance.app = app;
|
|
41
|
+
setActiveInstance(instance);
|
|
42
|
+
app.provide(promisePortalSymbol, instance);
|
|
43
|
+
}
|
|
44
|
+
};
|
|
45
|
+
return instance;
|
|
46
|
+
};
|
|
47
|
+
var usePortalContext = () => {
|
|
48
|
+
const instance = (0, import_vue.inject)(promisePortalSymbol);
|
|
49
|
+
if (!instance) {
|
|
50
|
+
throw new Error("[promise-portal]: no instance found.");
|
|
51
|
+
}
|
|
52
|
+
const ins = (0, import_vue.getCurrentInstance)();
|
|
53
|
+
if (!ins?.vnode) {
|
|
54
|
+
throw new Error("[promise-portal]: no vnode found.");
|
|
55
|
+
}
|
|
56
|
+
const data = instance.map.get(ins.vnode);
|
|
57
|
+
if (!data) {
|
|
58
|
+
throw new Error("[promise-portal]: no inject data found.");
|
|
59
|
+
}
|
|
60
|
+
return data;
|
|
61
|
+
};
|
|
62
|
+
var definePortal = (component, { instance, unmountDelay = 0 } = {}) => {
|
|
63
|
+
const _instance = instance || (0, import_vue.getCurrentInstance)() && (0, import_vue.inject)(promisePortalSymbol) || activeInstance;
|
|
64
|
+
if (!_instance) {
|
|
65
|
+
throw new Error("[promise-portal]: no instance found. Do you forget install promise-portal?");
|
|
66
|
+
}
|
|
67
|
+
return (props, children) => {
|
|
68
|
+
let el = document.createElement("div");
|
|
69
|
+
document.body.appendChild(el);
|
|
70
|
+
let vNode;
|
|
71
|
+
const p = new Promise((resolve, reject) => {
|
|
72
|
+
vNode = (0, import_vue.createVNode)(component, props, children);
|
|
73
|
+
_instance.map.set(vNode, { resolve, reject, el, vNode });
|
|
74
|
+
vNode.appContext = _instance.app._context;
|
|
75
|
+
(0, import_vue.render)(vNode, el);
|
|
76
|
+
});
|
|
77
|
+
p.finally(() => {
|
|
78
|
+
setTimeout(() => {
|
|
79
|
+
if (el) {
|
|
80
|
+
(0, import_vue.render)(null, el);
|
|
81
|
+
document.body.removeChild(el);
|
|
82
|
+
}
|
|
83
|
+
el = null;
|
|
84
|
+
vNode = null;
|
|
85
|
+
}, unmountDelay);
|
|
86
|
+
});
|
|
87
|
+
return p;
|
|
88
|
+
};
|
|
89
|
+
};
|
|
90
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
91
|
+
0 && (module.exports = {
|
|
92
|
+
createPromisePortal,
|
|
93
|
+
definePortal,
|
|
94
|
+
getActiveInstance,
|
|
95
|
+
setActiveInstance,
|
|
96
|
+
usePortalContext
|
|
97
|
+
});
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { VNode, App, Component } from 'vue';
|
|
2
|
+
|
|
3
|
+
interface PortalContext<R> {
|
|
4
|
+
resolve: (value: R | PromiseLike<R>) => void;
|
|
5
|
+
reject: (reason?: any) => void;
|
|
6
|
+
el: HTMLDivElement;
|
|
7
|
+
vNode: VNode;
|
|
8
|
+
}
|
|
9
|
+
interface PromisePortal<R = any> {
|
|
10
|
+
app: App;
|
|
11
|
+
map: WeakMap<VNode, PortalContext<R>>;
|
|
12
|
+
install: (app: App) => void;
|
|
13
|
+
}
|
|
14
|
+
interface PortalOptions<R> {
|
|
15
|
+
instance?: PromisePortal<R>;
|
|
16
|
+
unmountDelay?: number;
|
|
17
|
+
}
|
|
18
|
+
declare const getActiveInstance: () => PromisePortal<any>;
|
|
19
|
+
declare const setActiveInstance: (instance: PromisePortal) => PromisePortal<any>;
|
|
20
|
+
declare const createPromisePortal: () => PromisePortal<any>;
|
|
21
|
+
declare const usePortalContext: <TOutput = any>() => PortalContext<TOutput>;
|
|
22
|
+
declare const definePortal: <TOutput = any, TProps = any>(component: Component, { instance, unmountDelay }?: PortalOptions<TOutput>) => (props?: TProps | undefined, children?: unknown) => Promise<TOutput>;
|
|
23
|
+
|
|
24
|
+
export { PortalContext, PortalOptions, PromisePortal, createPromisePortal, definePortal, getActiveInstance, setActiveInstance, usePortalContext };
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
// src/index.ts
|
|
2
|
+
import { createVNode, render, inject, getCurrentInstance } from "vue";
|
|
3
|
+
var promisePortalSymbol = process.env.NODE_ENV !== "production" ? Symbol("promise-portal") : Symbol();
|
|
4
|
+
var activeInstance;
|
|
5
|
+
var getActiveInstance = () => activeInstance;
|
|
6
|
+
var setActiveInstance = (instance) => activeInstance = instance;
|
|
7
|
+
var createPromisePortal = () => {
|
|
8
|
+
const instance = {
|
|
9
|
+
app: void 0,
|
|
10
|
+
map: /* @__PURE__ */ new WeakMap(),
|
|
11
|
+
install(app) {
|
|
12
|
+
instance.app = app;
|
|
13
|
+
setActiveInstance(instance);
|
|
14
|
+
app.provide(promisePortalSymbol, instance);
|
|
15
|
+
}
|
|
16
|
+
};
|
|
17
|
+
return instance;
|
|
18
|
+
};
|
|
19
|
+
var usePortalContext = () => {
|
|
20
|
+
const instance = inject(promisePortalSymbol);
|
|
21
|
+
if (!instance) {
|
|
22
|
+
throw new Error("[promise-portal]: no instance found.");
|
|
23
|
+
}
|
|
24
|
+
const ins = getCurrentInstance();
|
|
25
|
+
if (!ins?.vnode) {
|
|
26
|
+
throw new Error("[promise-portal]: no vnode found.");
|
|
27
|
+
}
|
|
28
|
+
const data = instance.map.get(ins.vnode);
|
|
29
|
+
if (!data) {
|
|
30
|
+
throw new Error("[promise-portal]: no inject data found.");
|
|
31
|
+
}
|
|
32
|
+
return data;
|
|
33
|
+
};
|
|
34
|
+
var definePortal = (component, { instance, unmountDelay = 0 } = {}) => {
|
|
35
|
+
const _instance = instance || getCurrentInstance() && inject(promisePortalSymbol) || activeInstance;
|
|
36
|
+
if (!_instance) {
|
|
37
|
+
throw new Error("[promise-portal]: no instance found. Do you forget install promise-portal?");
|
|
38
|
+
}
|
|
39
|
+
return (props, children) => {
|
|
40
|
+
let el = document.createElement("div");
|
|
41
|
+
document.body.appendChild(el);
|
|
42
|
+
let vNode;
|
|
43
|
+
const p = new Promise((resolve, reject) => {
|
|
44
|
+
vNode = createVNode(component, props, children);
|
|
45
|
+
_instance.map.set(vNode, { resolve, reject, el, vNode });
|
|
46
|
+
vNode.appContext = _instance.app._context;
|
|
47
|
+
render(vNode, el);
|
|
48
|
+
});
|
|
49
|
+
p.finally(() => {
|
|
50
|
+
setTimeout(() => {
|
|
51
|
+
if (el) {
|
|
52
|
+
render(null, el);
|
|
53
|
+
document.body.removeChild(el);
|
|
54
|
+
}
|
|
55
|
+
el = null;
|
|
56
|
+
vNode = null;
|
|
57
|
+
}, unmountDelay);
|
|
58
|
+
});
|
|
59
|
+
return p;
|
|
60
|
+
};
|
|
61
|
+
};
|
|
62
|
+
export {
|
|
63
|
+
createPromisePortal,
|
|
64
|
+
definePortal,
|
|
65
|
+
getActiveInstance,
|
|
66
|
+
setActiveInstance,
|
|
67
|
+
usePortalContext
|
|
68
|
+
};
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "promise-portal",
|
|
3
|
-
"version": "1.0.
|
|
4
|
-
"description": "
|
|
3
|
+
"version": "1.0.4",
|
|
4
|
+
"description": "let you use react portal in vue, and with promise",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.cjs",
|
|
7
7
|
"module": "dist/index.js",
|