@e1himself/react-promise-modal 3.0.0 → 3.0.1
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/dist/ModalTransitions.d.ts +22 -0
- package/dist/ModalTransitions.js +124 -0
- package/dist/deferred.d.ts +14 -0
- package/dist/deferred.js +44 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +4 -0
- package/dist/lib.d.ts +6 -0
- package/dist/lib.js +25 -0
- package/dist/useIsMounted.d.ts +7 -0
- package/dist/useIsMounted.js +23 -0
- package/dist/useLatest.d.ts +13 -0
- package/dist/useLatest.js +22 -0
- package/dist/useNextFrameEffect.d.ts +3 -0
- package/dist/useNextFrameEffect.js +21 -0
- package/dist/usePromiseModal.d.ts +24 -0
- package/dist/usePromiseModal.js +172 -0
- package/package.json +1 -1
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
export type Milliseconds = number;
|
|
3
|
+
type Props = {
|
|
4
|
+
isOpen: boolean;
|
|
5
|
+
onClosed?: () => void;
|
|
6
|
+
transitionDuration: Milliseconds;
|
|
7
|
+
render: (props: RenderProps) => React.ReactElement | null;
|
|
8
|
+
};
|
|
9
|
+
type RenderProps = {
|
|
10
|
+
isOpen: boolean;
|
|
11
|
+
onClose: () => void;
|
|
12
|
+
};
|
|
13
|
+
export declare enum Stage {
|
|
14
|
+
UNMOUNTED = "unmounted",
|
|
15
|
+
STANDBY = "standby",// same as "closed", but before "opening"
|
|
16
|
+
OPEN = "open",
|
|
17
|
+
OPENING = "opening",
|
|
18
|
+
CLOSING = "closing",
|
|
19
|
+
CLOSED = "closed"
|
|
20
|
+
}
|
|
21
|
+
export declare function ModalTransitions({ isOpen: shouldOpen, onClosed, transitionDuration, render }: Props): React.ReactElement<unknown, string | React.JSXElementConstructor<any>> | null;
|
|
22
|
+
export {};
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
var _react = require("react");
|
|
4
|
+
var React = _react;
|
|
5
|
+
var _lib = require("./lib");
|
|
6
|
+
var delay = _lib.delay;
|
|
7
|
+
var _useLatest = require("./useLatest");
|
|
8
|
+
var useLatest = _useLatest.useLatest;
|
|
9
|
+
var _useNextFrameEffect = require("./useNextFrameEffect");
|
|
10
|
+
var useNextFrameEffect = _useNextFrameEffect.useNextFrameEffect;
|
|
11
|
+
function _slicedToArray(r, e) { return _arrayWithHoles(r) || _iterableToArrayLimit(r, e) || _unsupportedIterableToArray(r, e) || _nonIterableRest(); }
|
|
12
|
+
function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
|
|
13
|
+
function _unsupportedIterableToArray(r, a) { if (r) { if ("string" == typeof r) return _arrayLikeToArray(r, a); var t = {}.toString.call(r).slice(8, -1); return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0; } }
|
|
14
|
+
function _arrayLikeToArray(r, a) { (null == a || a > r.length) && (a = r.length); for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e]; return n; }
|
|
15
|
+
function _iterableToArrayLimit(r, l) { var t = null == r ? null : "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (null != t) { var e, n, i, u, a = [], f = !0, o = !1; try { if (i = (t = t.call(r)).next, 0 === l) { if (Object(t) !== t) return; f = !1; } else for (; !(f = (e = i.call(t)).done) && (a.push(e.value), a.length !== l); f = !0); } catch (r) { o = !0, n = r; } finally { try { if (!f && null != t["return"] && (u = t["return"](), Object(u) !== u)) return; } finally { if (o) throw n; } } return a; } }
|
|
16
|
+
function _arrayWithHoles(r) { if (Array.isArray(r)) return r; }
|
|
17
|
+
var Stage = /*#__PURE__*/exports.Stage = function (Stage) {
|
|
18
|
+
Stage["UNMOUNTED"] = "unmounted";
|
|
19
|
+
Stage["STANDBY"] = "standby";
|
|
20
|
+
// same as "closed", but before "opening"
|
|
21
|
+
Stage["OPEN"] = "open";
|
|
22
|
+
Stage["OPENING"] = "opening";
|
|
23
|
+
Stage["CLOSING"] = "closing";
|
|
24
|
+
Stage["CLOSED"] = "closed"; // same as "standby", but after "closing"
|
|
25
|
+
return Stage;
|
|
26
|
+
}({});
|
|
27
|
+
function ModalTransitions(_ref) {
|
|
28
|
+
var shouldOpen = _ref.isOpen,
|
|
29
|
+
onClosed = _ref.onClosed,
|
|
30
|
+
transitionDuration = _ref.transitionDuration,
|
|
31
|
+
render = _ref.render;
|
|
32
|
+
var _React$useState = React.useState(Stage.UNMOUNTED),
|
|
33
|
+
_React$useState2 = _slicedToArray(_React$useState, 2),
|
|
34
|
+
stage = _React$useState2[0],
|
|
35
|
+
setStage = _React$useState2[1];
|
|
36
|
+
var refs = useLatest({
|
|
37
|
+
stage: stage,
|
|
38
|
+
onClosed: onClosed,
|
|
39
|
+
transitionDuration: transitionDuration
|
|
40
|
+
});
|
|
41
|
+
var onOpen = React.useCallback(function () {
|
|
42
|
+
setStage(function (stage) {
|
|
43
|
+
// If it's UNMOUNTED or CLOSED: switch to STANDBY to prepare for OPENING.
|
|
44
|
+
if (stage === Stage.UNMOUNTED || stage === Stage.CLOSED) {
|
|
45
|
+
setStage(Stage.STANDBY);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
// If it's CLOSING: override and start OPENING.
|
|
49
|
+
if (stage === Stage.CLOSING) {
|
|
50
|
+
setStage(Stage.OPENING);
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
// If opening is requested while it's STANDBY, OPENING or already OPEN: do nothing.
|
|
54
|
+
// The `useLayoutEffect()` hook below will do the rest.
|
|
55
|
+
return stage;
|
|
56
|
+
});
|
|
57
|
+
}, []);
|
|
58
|
+
var onClose = React.useCallback(function () {
|
|
59
|
+
setStage(function (stage) {
|
|
60
|
+
// If it's OPENING or already OPEN: override and start CLOSING.
|
|
61
|
+
if (stage === Stage.OPENING || stage === Stage.OPEN) {
|
|
62
|
+
return Stage.CLOSING;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
// If it was in STANDBY preparing for OPENING: override and mark CLOSED.
|
|
66
|
+
if (stage === Stage.STANDBY) {
|
|
67
|
+
return Stage.CLOSED;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
// If opening is requested while it's UNMOUNTED, CLOSING or already CLOSED: do nothing.
|
|
71
|
+
// The `useLayoutEffect()` hook below will do the rest.
|
|
72
|
+
return stage;
|
|
73
|
+
});
|
|
74
|
+
}, []);
|
|
75
|
+
useNextFrameEffect(function () {
|
|
76
|
+
var cancel = false;
|
|
77
|
+
if (stage === Stage.STANDBY) {
|
|
78
|
+
// If it's in STANDBY (no longer unmounted, prepared for opening): start OPENING.
|
|
79
|
+
setStage(Stage.OPENING);
|
|
80
|
+
}
|
|
81
|
+
if (stage === Stage.OPENING) {
|
|
82
|
+
// Allow the transitions to happen and then switch to OPEN.
|
|
83
|
+
delay(refs.current.transitionDuration).then(function () {
|
|
84
|
+
// If the OPENING sequence was not canceled with later calls, mark it OPEN.
|
|
85
|
+
if (!cancel) {
|
|
86
|
+
setStage(Stage.OPEN);
|
|
87
|
+
}
|
|
88
|
+
});
|
|
89
|
+
}
|
|
90
|
+
if (stage === Stage.CLOSING) {
|
|
91
|
+
delay(refs.current.transitionDuration).then(function () {
|
|
92
|
+
// If the CLOSING sequence was not canceled with later calls, mark it CLOSED.
|
|
93
|
+
if (!cancel) {
|
|
94
|
+
setStage(Stage.CLOSED);
|
|
95
|
+
}
|
|
96
|
+
});
|
|
97
|
+
}
|
|
98
|
+
if (stage === Stage.CLOSED) {
|
|
99
|
+
var _refs$current$onClose, _refs$current;
|
|
100
|
+
// Once the CLOSED state is rendered, trigger the onClosed callback and immediately switch to UNMOUNTED
|
|
101
|
+
(_refs$current$onClose = (_refs$current = refs.current).onClosed) === null || _refs$current$onClose === void 0 || _refs$current$onClose.call(_refs$current);
|
|
102
|
+
setStage(Stage.UNMOUNTED);
|
|
103
|
+
}
|
|
104
|
+
return function () {
|
|
105
|
+
cancel = true;
|
|
106
|
+
};
|
|
107
|
+
}, [stage]);
|
|
108
|
+
React.useEffect(function () {
|
|
109
|
+
if (shouldOpen) {
|
|
110
|
+
return onOpen();
|
|
111
|
+
} else {
|
|
112
|
+
return onClose();
|
|
113
|
+
}
|
|
114
|
+
}, [shouldOpen]);
|
|
115
|
+
if (stage === Stage.UNMOUNTED) {
|
|
116
|
+
// Do not render anything in "unmounted" stage
|
|
117
|
+
return null;
|
|
118
|
+
}
|
|
119
|
+
return render({
|
|
120
|
+
isOpen: stage === Stage.OPEN || stage === Stage.OPENING,
|
|
121
|
+
onClose: onClose
|
|
122
|
+
});
|
|
123
|
+
}
|
|
124
|
+
exports.ModalTransitions = ModalTransitions;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* This kinda follows the Jquery.Deferred type idea.
|
|
3
|
+
* @see https://api.jquery.com/jQuery.Deferred/
|
|
4
|
+
*
|
|
5
|
+
* Deferred is mostly a promise, but you can resolve or reject it from outside.
|
|
6
|
+
* This 'Deferred' here is a much more limited version of the JQuery Deferred.
|
|
7
|
+
*/
|
|
8
|
+
export type Deferred<T> = {
|
|
9
|
+
promise: Promise<T>;
|
|
10
|
+
resolve: (value: T) => void;
|
|
11
|
+
reject: (reason: unknown) => void;
|
|
12
|
+
isSettled(): boolean;
|
|
13
|
+
};
|
|
14
|
+
export declare function createDeferred<T>(): Deferred<T>;
|
package/dist/deferred.js
ADDED
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
var _lib = require("./lib");
|
|
4
|
+
var noop = _lib.noop;
|
|
5
|
+
/**
|
|
6
|
+
* This kinda follows the Jquery.Deferred type idea.
|
|
7
|
+
* @see https://api.jquery.com/jQuery.Deferred/
|
|
8
|
+
*
|
|
9
|
+
* Deferred is mostly a promise, but you can resolve or reject it from outside.
|
|
10
|
+
* This 'Deferred' here is a much more limited version of the JQuery Deferred.
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
function createDeferred() {
|
|
14
|
+
var isSettled = false;
|
|
15
|
+
var resolvePromise = noop;
|
|
16
|
+
var rejectPromise = noop;
|
|
17
|
+
var promise = new Promise(function (resolve, reject) {
|
|
18
|
+
resolvePromise = resolve;
|
|
19
|
+
rejectPromise = reject;
|
|
20
|
+
});
|
|
21
|
+
return {
|
|
22
|
+
promise: promise,
|
|
23
|
+
resolve: function resolve(value) {
|
|
24
|
+
isSettled = true;
|
|
25
|
+
resolvePromise(value);
|
|
26
|
+
},
|
|
27
|
+
reject: function reject(reason) {
|
|
28
|
+
isSettled = true;
|
|
29
|
+
rejectPromise(reason);
|
|
30
|
+
},
|
|
31
|
+
isSettled: function (_isSettled) {
|
|
32
|
+
function isSettled() {
|
|
33
|
+
return _isSettled.apply(this, arguments);
|
|
34
|
+
}
|
|
35
|
+
isSettled.toString = function () {
|
|
36
|
+
return _isSettled.toString();
|
|
37
|
+
};
|
|
38
|
+
return isSettled;
|
|
39
|
+
}(function () {
|
|
40
|
+
return isSettled;
|
|
41
|
+
})
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
exports.createDeferred = createDeferred;
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { usePromiseModal } from "./usePromiseModal";
|
package/dist/index.js
ADDED
package/dist/lib.d.ts
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type * as React from "react";
|
|
2
|
+
export declare function noop(): void;
|
|
3
|
+
export declare function generateId(): string;
|
|
4
|
+
export declare function delay(ms: number): Promise<void>;
|
|
5
|
+
export declare function isEvent(value: unknown): value is Event;
|
|
6
|
+
export declare function isSyntheticEvent(value: unknown | Partial<React.SyntheticEvent>): value is React.SyntheticEvent;
|
package/dist/lib.js
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); }
|
|
4
|
+
function noop() {
|
|
5
|
+
// Nothing
|
|
6
|
+
}
|
|
7
|
+
exports.noop = noop;
|
|
8
|
+
function generateId() {
|
|
9
|
+
return "".concat(new Date().getTime(), "-").concat(Math.random());
|
|
10
|
+
}
|
|
11
|
+
exports.generateId = generateId;
|
|
12
|
+
function delay(ms) {
|
|
13
|
+
return new Promise(function (resolve) {
|
|
14
|
+
setTimeout(resolve, ms);
|
|
15
|
+
});
|
|
16
|
+
}
|
|
17
|
+
exports.delay = delay;
|
|
18
|
+
function isEvent(value) {
|
|
19
|
+
return value instanceof Event;
|
|
20
|
+
}
|
|
21
|
+
exports.isEvent = isEvent;
|
|
22
|
+
function isSyntheticEvent(value) {
|
|
23
|
+
return _typeof(value) === "object" && value !== null && "nativeEvent" in value && "persist" in value && "stopPropagation" in value && "preventDefault" in value;
|
|
24
|
+
}
|
|
25
|
+
exports.isSyntheticEvent = isSyntheticEvent;
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @see https://streamich.github.io/react-use/?path=/story/lifecycle-usemountedstate--docs
|
|
3
|
+
*
|
|
4
|
+
* Lifecycle hook providing ability to check component's mount status.
|
|
5
|
+
* Returns a function that will return true if component mounted and false otherwise.
|
|
6
|
+
*/
|
|
7
|
+
export declare function useIsMounted(): () => boolean;
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
var _react = require("react");
|
|
4
|
+
var React = _react;
|
|
5
|
+
/**
|
|
6
|
+
* @see https://streamich.github.io/react-use/?path=/story/lifecycle-usemountedstate--docs
|
|
7
|
+
*
|
|
8
|
+
* Lifecycle hook providing ability to check component's mount status.
|
|
9
|
+
* Returns a function that will return true if component mounted and false otherwise.
|
|
10
|
+
*/
|
|
11
|
+
function useIsMounted() {
|
|
12
|
+
var isMounted = React.useRef(false);
|
|
13
|
+
React.useEffect(function () {
|
|
14
|
+
isMounted.current = true;
|
|
15
|
+
return function () {
|
|
16
|
+
isMounted.current = false;
|
|
17
|
+
};
|
|
18
|
+
}, []);
|
|
19
|
+
return React.useCallback(function () {
|
|
20
|
+
return isMounted.current;
|
|
21
|
+
}, []);
|
|
22
|
+
}
|
|
23
|
+
exports.useIsMounted = useIsMounted;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @see https://streamich.github.io/react-use/?path=/story/state-uselatest--docs
|
|
3
|
+
*
|
|
4
|
+
* React state hook that returns the latest state as described in the React hooks FAQ.
|
|
5
|
+
* @see https://reactjs.org/docs/hooks-faq.html#why-am-i-seeing-stale-props-or-state-inside-my-function
|
|
6
|
+
*
|
|
7
|
+
* This is mostly useful to get access to the latest value of some props
|
|
8
|
+
* or state inside an asynchronous callback, instead of that value
|
|
9
|
+
* at the time the callback was created from.
|
|
10
|
+
*/
|
|
11
|
+
export declare function useLatest<T>(value: T): {
|
|
12
|
+
readonly current: T;
|
|
13
|
+
};
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
var _react = require("react");
|
|
4
|
+
var React = _react;
|
|
5
|
+
/**
|
|
6
|
+
* @see https://streamich.github.io/react-use/?path=/story/state-uselatest--docs
|
|
7
|
+
*
|
|
8
|
+
* React state hook that returns the latest state as described in the React hooks FAQ.
|
|
9
|
+
* @see https://reactjs.org/docs/hooks-faq.html#why-am-i-seeing-stale-props-or-state-inside-my-function
|
|
10
|
+
*
|
|
11
|
+
* This is mostly useful to get access to the latest value of some props
|
|
12
|
+
* or state inside an asynchronous callback, instead of that value
|
|
13
|
+
* at the time the callback was created from.
|
|
14
|
+
*/
|
|
15
|
+
function useLatest(value) {
|
|
16
|
+
var ref = React.useRef(value);
|
|
17
|
+
React.useLayoutEffect(function () {
|
|
18
|
+
ref.current = value;
|
|
19
|
+
}, [value]);
|
|
20
|
+
return ref;
|
|
21
|
+
}
|
|
22
|
+
exports.useLatest = useLatest;
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
var _react = require("react");
|
|
4
|
+
var useEffect = _react.useEffect;
|
|
5
|
+
var useEffectEvent = _react.useEffectEvent;
|
|
6
|
+
var _lib = require("./lib");
|
|
7
|
+
var noop = _lib.noop;
|
|
8
|
+
function useNextFrameEffect(callback, deps) {
|
|
9
|
+
var stableCallback = useEffectEvent(callback);
|
|
10
|
+
useEffect(function () {
|
|
11
|
+
var cleanup = noop;
|
|
12
|
+
var frame = requestAnimationFrame(function () {
|
|
13
|
+
cleanup = stableCallback();
|
|
14
|
+
});
|
|
15
|
+
return function () {
|
|
16
|
+
cleanup();
|
|
17
|
+
cancelAnimationFrame(frame);
|
|
18
|
+
};
|
|
19
|
+
}, deps);
|
|
20
|
+
}
|
|
21
|
+
exports.useNextFrameEffect = useNextFrameEffect;
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
import { type Milliseconds } from "./ModalTransitions";
|
|
3
|
+
interface Options {
|
|
4
|
+
concurrencyMode?: ConcurrencyMode;
|
|
5
|
+
transitionDuration?: Milliseconds;
|
|
6
|
+
}
|
|
7
|
+
type ConcurrencyMode = "stack" | "replace" | "ignore";
|
|
8
|
+
type RenderFunction<P> = (props: P) => React.ReactElement | null | undefined;
|
|
9
|
+
interface RenderProps<T> {
|
|
10
|
+
show: boolean;
|
|
11
|
+
onDismiss: () => void;
|
|
12
|
+
onSubmit: (value: Exclude<T, undefined>) => void;
|
|
13
|
+
}
|
|
14
|
+
export declare function usePromiseModal<T>(render: RenderFunction<RenderProps<T>>, options?: Options): {
|
|
15
|
+
modal: React.ReactElement;
|
|
16
|
+
invoke: () => Promise<T | undefined>;
|
|
17
|
+
isDisplayed: boolean;
|
|
18
|
+
};
|
|
19
|
+
export declare function usePromiseModal<T, Args>(render: RenderFunction<RenderProps<T> & Omit<Args, keyof RenderProps<T>>>, options?: Options): {
|
|
20
|
+
modal: React.ReactElement;
|
|
21
|
+
invoke: (args: Args) => Promise<T | undefined>;
|
|
22
|
+
isDisplayed: boolean;
|
|
23
|
+
};
|
|
24
|
+
export {};
|
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); }
|
|
4
|
+
var _react = require("react");
|
|
5
|
+
var React = _react;
|
|
6
|
+
var _deferred = require("./deferred");
|
|
7
|
+
var createDeferred = _deferred.createDeferred;
|
|
8
|
+
var _lib = require("./lib");
|
|
9
|
+
var generateId = _lib.generateId;
|
|
10
|
+
var isEvent = _lib.isEvent;
|
|
11
|
+
var isSyntheticEvent = _lib.isSyntheticEvent;
|
|
12
|
+
var _ModalTransitions = require("./ModalTransitions");
|
|
13
|
+
var ModalTransitions = _ModalTransitions.ModalTransitions;
|
|
14
|
+
var _useIsMounted = require("./useIsMounted");
|
|
15
|
+
var useIsMounted = _useIsMounted.useIsMounted;
|
|
16
|
+
var _useLatest = require("./useLatest");
|
|
17
|
+
var useLatest = _useLatest.useLatest;
|
|
18
|
+
function _regenerator() { /*! regenerator-runtime -- Copyright (c) 2014-present, Facebook, Inc. -- license (MIT): https://github.com/babel/babel/blob/main/packages/babel-helpers/LICENSE */ var e, t, r = "function" == typeof Symbol ? Symbol : {}, n = r.iterator || "@@iterator", o = r.toStringTag || "@@toStringTag"; function i(r, n, o, i) { var c = n && n.prototype instanceof Generator ? n : Generator, u = Object.create(c.prototype); return _regeneratorDefine2(u, "_invoke", function (r, n, o) { var i, c, u, f = 0, p = o || [], y = !1, G = { p: 0, n: 0, v: e, a: d, f: d.bind(e, 4), d: function d(t, r) { return i = t, c = 0, u = e, G.n = r, a; } }; function d(r, n) { for (c = r, u = n, t = 0; !y && f && !o && t < p.length; t++) { var o, i = p[t], d = G.p, l = i[2]; r > 3 ? (o = l === n) && (u = i[(c = i[4]) ? 5 : (c = 3, 3)], i[4] = i[5] = e) : i[0] <= d && ((o = r < 2 && d < i[1]) ? (c = 0, G.v = n, G.n = i[1]) : d < l && (o = r < 3 || i[0] > n || n > l) && (i[4] = r, i[5] = n, G.n = l, c = 0)); } if (o || r > 1) return a; throw y = !0, n; } return function (o, p, l) { if (f > 1) throw TypeError("Generator is already running"); for (y && 1 === p && d(p, l), c = p, u = l; (t = c < 2 ? e : u) || !y;) { i || (c ? c < 3 ? (c > 1 && (G.n = -1), d(c, u)) : G.n = u : G.v = u); try { if (f = 2, i) { if (c || (o = "next"), t = i[o]) { if (!(t = t.call(i, u))) throw TypeError("iterator result is not an object"); if (!t.done) return t; u = t.value, c < 2 && (c = 0); } else 1 === c && (t = i["return"]) && t.call(i), c < 2 && (u = TypeError("The iterator does not provide a '" + o + "' method"), c = 1); i = e; } else if ((t = (y = G.n < 0) ? u : r.call(n, G)) !== a) break; } catch (t) { i = e, c = 1, u = t; } finally { f = 1; } } return { value: t, done: y }; }; }(r, o, i), !0), u; } var a = {}; function Generator() {} function GeneratorFunction() {} function GeneratorFunctionPrototype() {} t = Object.getPrototypeOf; var c = [][n] ? t(t([][n]())) : (_regeneratorDefine2(t = {}, n, function () { return this; }), t), u = GeneratorFunctionPrototype.prototype = Generator.prototype = Object.create(c); function f(e) { return Object.setPrototypeOf ? Object.setPrototypeOf(e, GeneratorFunctionPrototype) : (e.__proto__ = GeneratorFunctionPrototype, _regeneratorDefine2(e, o, "GeneratorFunction")), e.prototype = Object.create(u), e; } return GeneratorFunction.prototype = GeneratorFunctionPrototype, _regeneratorDefine2(u, "constructor", GeneratorFunctionPrototype), _regeneratorDefine2(GeneratorFunctionPrototype, "constructor", GeneratorFunction), GeneratorFunction.displayName = "GeneratorFunction", _regeneratorDefine2(GeneratorFunctionPrototype, o, "GeneratorFunction"), _regeneratorDefine2(u), _regeneratorDefine2(u, o, "Generator"), _regeneratorDefine2(u, n, function () { return this; }), _regeneratorDefine2(u, "toString", function () { return "[object Generator]"; }), (_regenerator = function _regenerator() { return { w: i, m: f }; })(); }
|
|
19
|
+
function _regeneratorDefine2(e, r, n, t) { var i = Object.defineProperty; try { i({}, "", {}); } catch (e) { i = 0; } _regeneratorDefine2 = function _regeneratorDefine(e, r, n, t) { function o(r, n) { _regeneratorDefine2(e, r, function (e) { return this._invoke(r, n, e); }); } r ? i ? i(e, r, { value: n, enumerable: !t, configurable: !t, writable: !t }) : e[r] = n : (o("next", 0), o("throw", 1), o("return", 2)); }, _regeneratorDefine2(e, r, n, t); }
|
|
20
|
+
function _toConsumableArray(r) { return _arrayWithoutHoles(r) || _iterableToArray(r) || _unsupportedIterableToArray(r) || _nonIterableSpread(); }
|
|
21
|
+
function _nonIterableSpread() { throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
|
|
22
|
+
function _iterableToArray(r) { if ("undefined" != typeof Symbol && null != r[Symbol.iterator] || null != r["@@iterator"]) return Array.from(r); }
|
|
23
|
+
function _arrayWithoutHoles(r) { if (Array.isArray(r)) return _arrayLikeToArray(r); }
|
|
24
|
+
function asyncGeneratorStep(n, t, e, r, o, a, c) { try { var i = n[a](c), u = i.value; } catch (n) { return void e(n); } i.done ? t(u) : Promise.resolve(u).then(r, o); }
|
|
25
|
+
function _asyncToGenerator(n) { return function () { var t = this, e = arguments; return new Promise(function (r, o) { var a = n.apply(t, e); function _next(n) { asyncGeneratorStep(a, r, o, _next, _throw, "next", n); } function _throw(n) { asyncGeneratorStep(a, r, o, _next, _throw, "throw", n); } _next(void 0); }); }; }
|
|
26
|
+
function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
|
|
27
|
+
function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
|
|
28
|
+
function _defineProperty(e, r, t) { return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: !0, configurable: !0, writable: !0 }) : e[r] = t, e; }
|
|
29
|
+
function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == _typeof(i) ? i : i + ""; }
|
|
30
|
+
function _toPrimitive(t, r) { if ("object" != _typeof(t) || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != _typeof(i)) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
|
|
31
|
+
function _slicedToArray(r, e) { return _arrayWithHoles(r) || _iterableToArrayLimit(r, e) || _unsupportedIterableToArray(r, e) || _nonIterableRest(); }
|
|
32
|
+
function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
|
|
33
|
+
function _unsupportedIterableToArray(r, a) { if (r) { if ("string" == typeof r) return _arrayLikeToArray(r, a); var t = {}.toString.call(r).slice(8, -1); return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0; } }
|
|
34
|
+
function _arrayLikeToArray(r, a) { (null == a || a > r.length) && (a = r.length); for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e]; return n; }
|
|
35
|
+
function _iterableToArrayLimit(r, l) { var t = null == r ? null : "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (null != t) { var e, n, i, u, a = [], f = !0, o = !1; try { if (i = (t = t.call(r)).next, 0 === l) { if (Object(t) !== t) return; f = !1; } else for (; !(f = (e = i.call(t)).done) && (a.push(e.value), a.length !== l); f = !0); } catch (r) { o = !0, n = r; } finally { try { if (!f && null != t["return"] && (u = t["return"](), Object(u) !== u)) return; } finally { if (o) throw n; } } return a; } }
|
|
36
|
+
function _arrayWithHoles(r) { if (Array.isArray(r)) return r; }
|
|
37
|
+
var DEFAULT_CONCURRENCY_MODE = "replace";
|
|
38
|
+
var DEFAULT_TRANSITION_DURATION = 300;
|
|
39
|
+
function usePromiseModal(render) {
|
|
40
|
+
var _ref = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {},
|
|
41
|
+
_ref$concurrencyMode = _ref.concurrencyMode,
|
|
42
|
+
concurrencyMode = _ref$concurrencyMode === void 0 ? DEFAULT_CONCURRENCY_MODE : _ref$concurrencyMode,
|
|
43
|
+
_ref$transitionDurati = _ref.transitionDuration,
|
|
44
|
+
transitionDuration = _ref$transitionDurati === void 0 ? DEFAULT_TRANSITION_DURATION : _ref$transitionDurati;
|
|
45
|
+
var isMounted = useIsMounted();
|
|
46
|
+
var _React$useState = React.useState([]),
|
|
47
|
+
_React$useState2 = _slicedToArray(_React$useState, 2),
|
|
48
|
+
invoked = _React$useState2[0],
|
|
49
|
+
setInvoked = _React$useState2[1];
|
|
50
|
+
var refs = useLatest({
|
|
51
|
+
invoked: invoked
|
|
52
|
+
});
|
|
53
|
+
var isDisplayed = invoked.length > 0;
|
|
54
|
+
var modal = /*#__PURE__*/React.createElement(React.Fragment, null, invoked.map(function (invocation, index) {
|
|
55
|
+
var id = invocation.id,
|
|
56
|
+
args = invocation.args,
|
|
57
|
+
deferred = invocation.deferred;
|
|
58
|
+
return /*#__PURE__*/React.createElement(ModalTransitions, {
|
|
59
|
+
key: "react-promise-modal-".concat(id)
|
|
60
|
+
/* only show the latest invoked modal */,
|
|
61
|
+
isOpen: index === invoked.length - 1,
|
|
62
|
+
onClosed: function onClosed() {
|
|
63
|
+
if (isMounted()) {
|
|
64
|
+
// Remove the invocation when the modal is closed
|
|
65
|
+
setInvoked(function (prev) {
|
|
66
|
+
return prev.filter(function (x) {
|
|
67
|
+
return x.id !== invocation.id;
|
|
68
|
+
});
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
},
|
|
72
|
+
transitionDuration: transitionDuration,
|
|
73
|
+
render: function (_render2) {
|
|
74
|
+
function render(_x) {
|
|
75
|
+
return _render2.apply(this, arguments);
|
|
76
|
+
}
|
|
77
|
+
render.toString = function () {
|
|
78
|
+
return _render2.toString();
|
|
79
|
+
};
|
|
80
|
+
return render;
|
|
81
|
+
}(function (_ref2) {
|
|
82
|
+
var _render;
|
|
83
|
+
var isOpen = _ref2.isOpen,
|
|
84
|
+
onClose = _ref2.onClose;
|
|
85
|
+
return (_render = render(_objectSpread(_objectSpread({}, args), {}, {
|
|
86
|
+
show: isOpen,
|
|
87
|
+
onDismiss: function onDismiss() {
|
|
88
|
+
deferred.resolve(undefined);
|
|
89
|
+
onClose();
|
|
90
|
+
},
|
|
91
|
+
onSubmit: function onSubmit(value) {
|
|
92
|
+
deferred.resolve(value);
|
|
93
|
+
onClose();
|
|
94
|
+
}
|
|
95
|
+
}))) !== null && _render !== void 0 ? _render : null;
|
|
96
|
+
})
|
|
97
|
+
});
|
|
98
|
+
}));
|
|
99
|
+
var invoke = React.useCallback(/*#__PURE__*/function () {
|
|
100
|
+
var _ref3 = _asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee(incomingArgs) {
|
|
101
|
+
var id, deferred, args, invocation, _t;
|
|
102
|
+
return _regenerator().w(function (_context) {
|
|
103
|
+
while (1) switch (_context.n) {
|
|
104
|
+
case 0:
|
|
105
|
+
id = generateId();
|
|
106
|
+
deferred = createDeferred();
|
|
107
|
+
args =
|
|
108
|
+
// Note: Do not spread the incoming args object, if it's a DOM Event or a React SyntheticEvent,
|
|
109
|
+
// which is a super common scenario. Modal `invoke()` functions are passed to onClick handlers all the time.
|
|
110
|
+
// Also, an event should never be used as a props object to spread anyway.
|
|
111
|
+
// @see https://github.com/prezly/prezly/pull/12020#discussion_r1101325932
|
|
112
|
+
isEvent(incomingArgs) || isSyntheticEvent(incomingArgs) ? {} : incomingArgs;
|
|
113
|
+
invocation = {
|
|
114
|
+
id: id,
|
|
115
|
+
args: args,
|
|
116
|
+
deferred: deferred
|
|
117
|
+
};
|
|
118
|
+
_t = concurrencyMode;
|
|
119
|
+
_context.n = _t === "ignore" ? 1 : _t === "stack" ? 2 : _t === "replace" ? 3 : 3;
|
|
120
|
+
break;
|
|
121
|
+
case 1:
|
|
122
|
+
setInvoked(function (prev) {
|
|
123
|
+
if (prev.length > 0) {
|
|
124
|
+
// auto-dismiss the current call
|
|
125
|
+
deferred.resolve(undefined);
|
|
126
|
+
return prev;
|
|
127
|
+
}
|
|
128
|
+
return [invocation];
|
|
129
|
+
});
|
|
130
|
+
return _context.a(3, 4);
|
|
131
|
+
case 2:
|
|
132
|
+
setInvoked(function (prev) {
|
|
133
|
+
return [].concat(_toConsumableArray(prev), [invocation]);
|
|
134
|
+
});
|
|
135
|
+
return _context.a(3, 4);
|
|
136
|
+
case 3:
|
|
137
|
+
setInvoked(function (prev) {
|
|
138
|
+
// auto-dismiss all previous calls
|
|
139
|
+
prev.forEach(function (_ref4) {
|
|
140
|
+
var deferred = _ref4.deferred;
|
|
141
|
+
return deferred.resolve(undefined);
|
|
142
|
+
});
|
|
143
|
+
return [invocation];
|
|
144
|
+
});
|
|
145
|
+
return _context.a(3, 4);
|
|
146
|
+
case 4:
|
|
147
|
+
return _context.a(2, deferred.promise);
|
|
148
|
+
}
|
|
149
|
+
}, _callee);
|
|
150
|
+
}));
|
|
151
|
+
return function (_x2) {
|
|
152
|
+
return _ref3.apply(this, arguments);
|
|
153
|
+
};
|
|
154
|
+
}(), [concurrencyMode]);
|
|
155
|
+
React.useEffect(function () {
|
|
156
|
+
// Auto-dismiss all open modals on unmount
|
|
157
|
+
return function () {
|
|
158
|
+
refs.current.invoked.forEach(function (_ref5) {
|
|
159
|
+
var deferred = _ref5.deferred;
|
|
160
|
+
if (!deferred.isSettled()) {
|
|
161
|
+
deferred.resolve(undefined);
|
|
162
|
+
}
|
|
163
|
+
});
|
|
164
|
+
};
|
|
165
|
+
}, []);
|
|
166
|
+
return {
|
|
167
|
+
modal: modal,
|
|
168
|
+
invoke: invoke,
|
|
169
|
+
isDisplayed: isDisplayed
|
|
170
|
+
};
|
|
171
|
+
}
|
|
172
|
+
exports.usePromiseModal = usePromiseModal;
|