UNPKG

@orca-fe/hooks

Version:

React Hooks Collections

261 lines (258 loc) 10.4 kB
"use strict"; var _interopRequireWildcard = require("@babel/runtime/helpers/interopRequireWildcard").default; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault").default; Object.defineProperty(exports, "__esModule", { value: true }); exports.PromisifyModalContext = void 0; exports.default = usePromisifyModal; exports.usePromisifyDrawer = void 0; var _objectSpread3 = _interopRequireDefault(require("@babel/runtime/helpers/objectSpread2")); var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty")); var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray")); var _react = _interopRequireWildcard(require("react")); var _ahooks = require("ahooks"); var _useMemorizedFn = _interopRequireDefault(require("./useMemorizedFn")); var emptyFn = function emptyFn() { return undefined; }; var PromisifyModalContext = exports.PromisifyModalContext = /*#__PURE__*/_react.default.createContext({ ok: emptyFn, cancel: emptyFn, destroy: emptyFn, minimize: emptyFn, resume: emptyFn, resolve: emptyFn, update: emptyFn }); var readyVisible = 'data-promisify-modal-ready'; /** * 帮助你管理维护弹框的 open 状态,适用于 antd-modal 及基于 modal 封装的自定义弹框 * 通过 show 方法,直接弹出 modal 即可。工具会自动接管 onOk 和 onCancel 事件,并更新 open * @param options */ function usePromisifyModal() { var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; var _options$openField = options.openField, openField = _options$openField === void 0 ? 'open' : _options$openField, _options$onOkField = options.onOkField, onOkField = _options$onOkField === void 0 ? 'onOk' : _options$onOkField, _options$onCloseField = options.onCloseField, onCloseField = _options$onCloseField === void 0 ? 'onCancel' : _options$onCloseField, _options$confirmLoadi = options.confirmLoadingPropName, confirmLoadingPropName = _options$confirmLoadi === void 0 ? 'confirmLoading' : _options$confirmLoadi, _options$destroyDelay = options.destroyDelay, destroyDelay = _options$destroyDelay === void 0 ? 300 : _options$destroyDelay, rejectOnClose = options.rejectOnClose; var _useState = (0, _react.useState)(null), _useState2 = (0, _slicedToArray2.default)(_useState, 2), instance = _useState2[0], setInstance = _useState2[1]; (0, _react.useEffect)(function () { if (instance !== null && instance !== void 0 && instance.props[readyVisible]) { setInstance( /*#__PURE__*/_react.default.cloneElement(instance, (0, _defineProperty2.default)((0, _defineProperty2.default)({}, openField, true), readyVisible, false))); } }, [instance]); var destroyAfterClose = (0, _ahooks.useDebounceFn)(function () { setInstance(null); }, { wait: destroyDelay }); var _useState3 = (0, _react.useState)({ ok: function () {}, cancel: function () {}, resolveFn: function () {}, // 原始的 onOk 事件 originOnOk: function () {}, // 原始的 onCancel 事件 originOnCancel: function () {} }), _useState4 = (0, _slicedToArray2.default)(_useState3, 1), _this = _useState4[0]; /** * 更新当前弹框实例的属性 */ var update = (0, _useMemorizedFn.default)(function (props) { var newProps = (0, _objectSpread3.default)({}, props); // 特殊处理,onOk 和 onCancel 已经被代理,不得通过 update 直接设置到组件实例 if (onOkField && typeof newProps[onOkField] === 'function') { _this.originOnOk = newProps[onOkField]; // eslint-disable-next-line @typescript-eslint/no-dynamic-delete delete newProps[onOkField]; } if (onCloseField && typeof newProps[onCloseField] === 'function') { _this.originOnCancel = newProps[onCloseField]; // eslint-disable-next-line @typescript-eslint/no-dynamic-delete delete newProps[onCloseField]; } setInstance(function (instance) { return instance ? /*#__PURE__*/_react.default.cloneElement(instance, newProps) : null; }); }); var clearThis = function clearThis() { _this.ok = undefined; _this.cancel = undefined; _this.resolveFn = undefined; _this.originOnOk = undefined; _this.originOnCancel = undefined; }; var destroy = (0, _useMemorizedFn.default)(function () { clearThis(); update((0, _defineProperty2.default)({}, openField, false)); destroyAfterClose.run(); }); var minimize = (0, _useMemorizedFn.default)(function () { update((0, _defineProperty2.default)({}, openField, false)); }); var resume = (0, _useMemorizedFn.default)(function () { update((0, _defineProperty2.default)({}, openField, true)); }); var open = (0, _useMemorizedFn.default)(function () { var element = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : instance; var ok = function ok() {}; var cancel = function cancel() {}; var resolveFn = function resolveFn() {}; clearThis(); var extendHandler = function extendHandler() { return { hide: destroy, destroy: destroy, ok: ok, cancel: cancel, resolve: resolveFn }; }; if (!element) { // 未传入组件实例 var p = Promise.reject(new Error('Empty show')); Object.assign(p, extendHandler()); return p; } destroyAfterClose.cancel(); var key = new Date().getTime(); // 在 open 时,记录下原始的 element 的 onOk 和 onCancel 事件,用于回调 if (onOkField && typeof element.props[onOkField] === 'function') { _this.originOnOk = element.props[onOkField]; } if (onCloseField && typeof element.props[onCloseField] === 'function') { _this.originOnCancel = element.props[onCloseField]; } var handler = new Promise(function (resolve, reject) { var onOkHandler = function onOkHandler() { for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) { args[_key] = arguments[_key]; } if (typeof _this.originOnOk === 'function') { var res = _this.originOnOk.apply(null, args); if (res instanceof Promise) { if (confirmLoadingPropName) { update((0, _defineProperty2.default)({}, confirmLoadingPropName, true)); } return res.then(function (r) { destroy(); if (r !== undefined) { resolve(r); } else { resolve(args[0]); } return r; }).catch(function () { if (confirmLoadingPropName) { update((0, _defineProperty2.default)({}, confirmLoadingPropName, false)); } }); } else if (res === false) { return undefined; } destroy(); resolve(args[0]); return res; } destroy(); resolve(args[0]); return undefined; }; // 代理 onCancel 事件 var onCancelHandler = function onCancelHandler() { var _this$originOnCancel; destroy(); if (rejectOnClose) { reject(new Error('close')); } for (var _len2 = arguments.length, args = new Array(_len2), _key2 = 0; _key2 < _len2; _key2++) { args[_key2] = arguments[_key2]; } (_this$originOnCancel = _this.originOnCancel) === null || _this$originOnCancel === void 0 || _this$originOnCancel.apply(null, args); return undefined; }; ok = onOkHandler; cancel = onCancelHandler; resolveFn = resolve; var newElement = /*#__PURE__*/_react.default.cloneElement(element, (0, _objectSpread3.default)((0, _objectSpread3.default)((0, _defineProperty2.default)((0, _defineProperty2.default)({ key: key }, openField, false), readyVisible, true), onOkField ? (0, _defineProperty2.default)({}, onOkField, onOkHandler) : {}), onCloseField ? (0, _defineProperty2.default)({}, onCloseField, onCancelHandler) : {})); setInstance(newElement); }); Object.assign(handler, extendHandler()); _this.ok = ok; _this.cancel = cancel; _this.resolveFn = resolveFn; return handler; }); var ok = (0, _ahooks.useMemoizedFn)(function () { var _this$ok; for (var _len3 = arguments.length, args = new Array(_len3), _key3 = 0; _key3 < _len3; _key3++) { args[_key3] = arguments[_key3]; } (_this$ok = _this.ok) === null || _this$ok === void 0 || _this$ok.call.apply(_this$ok, [_this].concat(args)); }); var cancel = (0, _ahooks.useMemoizedFn)(function () { var _this$cancel; for (var _len4 = arguments.length, args = new Array(_len4), _key4 = 0; _key4 < _len4; _key4++) { args[_key4] = arguments[_key4]; } (_this$cancel = _this.cancel) === null || _this$cancel === void 0 || _this$cancel.call.apply(_this$cancel, [_this].concat(args)); }); var resolve = (0, _ahooks.useMemoizedFn)(function () { var _this$resolveFn; for (var _len5 = arguments.length, args = new Array(_len5), _key5 = 0; _key5 < _len5; _key5++) { args[_key5] = arguments[_key5]; } (_this$resolveFn = _this.resolveFn) === null || _this$resolveFn === void 0 || _this$resolveFn.call.apply(_this$resolveFn, [_this].concat(args)); }); var instanceWithContext = /*#__PURE__*/_react.default.createElement(PromisifyModalContext.Provider, { value: (0, _react.useMemo)(function () { return { cancel: cancel, destroy: destroy, minimize: minimize, resume: resume, ok: ok, resolve: resolve, update: update }; }, []) }, instance); return { show: open, open: open, hide: destroy, destroy: destroy, instance: instanceWithContext, resume: resume, minimize: minimize, ok: ok, cancel: cancel, resolve: resolve, update: update, isOpen: Boolean(instance) }; } var usePromisifyDrawer = exports.usePromisifyDrawer = function usePromisifyDrawer() { var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; return usePromisifyModal((0, _objectSpread3.default)({ onCloseField: 'onClose', onOkField: '', confirmLoadingPropName: '' }, options)); };