promise-portal 1.0.2 → 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 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
@@ -155,8 +209,21 @@ const onClick = async () => {
155
209
  const output = await portal() // only allow empty parameter
156
210
  ```
157
211
 
158
- ## Link
212
+ you can set a config to definePortal
159
213
 
160
- [@filez/portal](https://github.com/lenovo-filez/portal)
214
+ ```ts
215
+ definePortal(Comp, {
216
+ // set a time gap before portal unmount,
217
+ // in general, it to wait for animation effect
218
+ unmountDelay: 1000,
219
+ // set promise-portal instance explicitly to render this portal
220
+ // not use the active instance internally
221
+ // of course, you can use `setActiveInstance` to set active instance
222
+ instance: promisePortalInstance,
223
+ })
224
+ ```
225
+
226
+ ## Link
161
227
 
162
- [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
+ });
@@ -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.2",
4
- "description": "a vite plugin to load svg icon for element-plus",
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",