@prezly/react-promise-modal
Version:
The proper (and easy) way of doing modals in React. With Promises.
101 lines (100 loc) • 4.19 kB
JavaScript
;
var _react = require("react");
var React = _react;
var _lib = require("./lib");
var noop = _lib.noop;
var _useIsMounted = require("./useIsMounted");
var useIsMounted = _useIsMounted.useIsMounted;
var _useLatest = require("./useLatest");
var useLatest = _useLatest.useLatest;
function _slicedToArray(r, e) { return _arrayWithHoles(r) || _iterableToArrayLimit(r, e) || _unsupportedIterableToArray(r, e) || _nonIterableRest(); }
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."); }
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; } }
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; }
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; } }
function _arrayWithHoles(r) { if (Array.isArray(r)) return r; }
var Stage = /*#__PURE__*/exports.Stage = function (Stage) {
Stage["OPEN"] = "open";
Stage["OPENING"] = "opening";
Stage["CLOSING"] = "closing";
Stage["CLOSED"] = "closed";
return Stage;
}({});
function ModalTransitions(_ref) {
var shouldOpen = _ref.isOpen,
onClosed = _ref.onClosed,
transitionDuration = _ref.transitionDuration,
render = _ref.render;
var isMounted = useIsMounted();
var _React$useState = React.useState(Stage.CLOSED),
_React$useState2 = _slicedToArray(_React$useState, 2),
stage = _React$useState2[0],
setStage = _React$useState2[1];
var refs = useLatest({
stage: stage,
onClosed: onClosed,
transitionDuration: transitionDuration
});
var onOpen = React.useCallback(function () {
if (!isMounted()) {
return noop;
}
if (refs.current.stage === Stage.OPENING || refs.current.stage === Stage.OPEN) {
return noop; // Nothing to do
}
var cancel = false;
setStage(Stage.OPENING);
delay(refs.current.transitionDuration).then(function () {
if (cancel || !isMounted()) {
return;
}
setStage(Stage.OPEN);
});
return function () {
cancel = true;
};
}, []);
var onClose = React.useCallback(function () {
if (!isMounted()) {
return noop;
}
if (refs.current.stage === Stage.CLOSING || refs.current.stage === Stage.CLOSED) {
return noop; // Nothing to do
}
var cancel = false;
setStage(Stage.CLOSING);
delay(refs.current.transitionDuration).then(function () {
var _refs$current$onClose, _refs$current;
if (cancel || !isMounted()) {
return;
}
setStage(Stage.CLOSED);
(_refs$current$onClose = (_refs$current = refs.current).onClosed) === null || _refs$current$onClose === void 0 || _refs$current$onClose.call(_refs$current);
});
return function () {
cancel = true;
};
}, []);
React.useEffect(function () {
if (shouldOpen) {
return onOpen();
} else {
return onClose();
}
}, [open]);
if (stage === Stage.CLOSED) {
// Do not render anything in "closed" stage
return null;
}
return render({
stage: stage,
isOpen: stage === Stage.OPEN || stage === Stage.OPENING,
onClose: onClose
});
}
exports.ModalTransitions = ModalTransitions;
function delay(ms) {
return new Promise(function (resolve) {
setTimeout(resolve, ms);
});
}