UNPKG

@nutui/nutui-react

Version:

京东风格的轻量级移动端 React 组件库,支持一套代码生成 H5 和小程序

225 lines (224 loc) 9.46 kB
import { _ as __rest, a as __awaiter } from "./tslib.es6.js"; import React__default, { forwardRef, useState } from "react"; import classNames from "classnames"; import { Close } from "@nutui/icons-react"; import Button__default from "./Button.js"; import { r as render, u as unmount } from "./render.js"; import { CSSTransition } from "react-transition-group"; import { d as defaultOverlayProps } from "./overlay2.js"; import { C as ComponentDefaults } from "./typings.js"; import Overlay__default from "./Overlay.js"; import { useConfig } from "./ConfigProvider.js"; import { m as mergeProps } from "./merge-props.js"; function ConfirmDialog(props) { return React__default.createElement(Dialog, Object.assign({}, props), props.content); } const normalizeConfig = (config) => { if (config.isNotice) { let { icon } = config; if (!icon && icon !== null) { switch (config.noticeType) { case "alert": icon = ""; break; } } config.hideCancelButton = true; } return config; }; const confirm = (config, renderFunc) => { const div = document.createElement("div"); document.body.appendChild(div); let dialogConfig = Object.assign(Object.assign({}, config), { visible: false }); const render$1 = (props, callback) => { render(React__default.createElement(ConfirmDialog, Object.assign({}, props, { onCancel: () => onCancel() })), div); callback && callback(); }; const renderFunction = render$1; const onConfirm = () => { const _onConfirm = config.onConfirm || config.onConfirm; const ret = _onConfirm === null || _onConfirm === void 0 ? void 0 : _onConfirm(); if (ret && ret.then) { renderFunction(dialogConfig); return ret.then(() => { onCancel(true); }, (e) => { console.error(e); renderFunction(dialogConfig); }); } if (!ret) { onCancel(true); } }; dialogConfig.onConfirm = onConfirm; dialogConfig = normalizeConfig(dialogConfig); dialogConfig.visible = true; renderFunction(dialogConfig); const destroy = () => { unmount(div); if (div === null || div === void 0 ? void 0 : div.parentNode) { div.parentNode.removeChild(div); } }; const onCancel = (confirm2) => { !confirm2 && config.onCancel && config.onCancel(); dialogConfig.visible = false; dialogConfig.onClose = () => { config.onClose && config.onClose(); }; renderFunction(dialogConfig, () => { destroy(); }); }; const update = (newConfig) => { dialogConfig = Object.assign(Object.assign(Object.assign({}, dialogConfig), { title: config.title }), newConfig); dialogConfig = normalizeConfig(dialogConfig); renderFunction(dialogConfig); }; const close = () => { dialogConfig.visible = false; dialogConfig.onClose = () => { config.onClose && config.onClose(); destroy(); }; renderFunction(dialogConfig); }; return { close, update }; }; const Content = (props) => { const { visible, title, header, footer, close, footerDirection, onClick, children } = props; const classPrefix = "nut-dialog"; const renderHeader = () => { return title ? React__default.createElement("div", { className: `${classPrefix}-header` }, title) : null; }; const renderFooter = () => { return footer ? React__default.createElement("div", { className: classNames(`${classPrefix}-footer`, { [footerDirection]: footerDirection }) }, footer) : null; }; const handleClick = (e) => { onClick && onClick(e); }; return React__default.createElement( "div", { className: classNames(`${classPrefix}-outer`, props.className), style: props.style, onClick: (e) => handleClick(e) }, close, header, React__default.createElement( "div", { className: classPrefix, style: { display: visible ? "flex" : "none" } }, renderHeader(), React__default.createElement( "div", { className: `${classPrefix}-content` }, React__default.createElement(React__default.Fragment, null, children) ), renderFooter() ) ); }; Content.displayName = "NutContent"; Object.assign(Object.assign(Object.assign({}, ComponentDefaults), { overlay: true, overlayStyle: {}, overlayClassName: "", onCancel: () => { }, onClose: () => { }, onOverlayClick: (e) => true }), defaultOverlayProps); const DialogWrap = (props) => { const { visible, overlay, overlayStyle, overlayClassName, closeOnOverlayClick, lockScroll, onClose, onCancel, onOverlayClick } = props; const onHandleClickOverlay = (e) => { if (closeOnOverlayClick && visible && e.target === e.currentTarget) { const closed = onOverlayClick && onOverlayClick(e); closed && (onClose === null || onClose === void 0 ? void 0 : onClose()); closed && (onCancel === null || onCancel === void 0 ? void 0 : onCancel()); } }; return React__default.createElement( React__default.Fragment, null, overlay ? React__default.createElement(Overlay__default, { style: overlayStyle, className: classNames("nut-dialog-overlay", overlayClassName), visible, closeOnOverlayClick, lockScroll, onClick: onHandleClickOverlay }) : null, React__default.createElement( CSSTransition, { in: visible, timeout: 300, classNames: "fadeDialog", unmountOnExit: true, appear: true }, React__default.createElement(Content, Object.assign({}, props, { visible })) ) ); }; DialogWrap.displayName = "NutDialogWrap"; const defaultProps = Object.assign(Object.assign({}, ComponentDefaults), { confirmText: "", cancelText: "", overlay: true, closeOnOverlayClick: true, hideConfirmButton: false, hideCancelButton: false, disableConfirmButton: false, footerDirection: "horizontal", lockScroll: true, closeIconPosition: "bottom", closeIcon: false, beforeCancel: () => true, beforeClose: () => true }); const BaseDialog = (props, ref) => { const { locale } = useConfig(); const _a = mergeProps(defaultProps, props), { visible, footer, hideConfirmButton, hideCancelButton, lockScroll, disableConfirmButton, closeOnOverlayClick, confirmText, cancelText, closeIconPosition, closeIcon, onClose, onCancel, onConfirm, beforeCancel, beforeClose } = _a; __rest(_a, ["visible", "footer", "hideConfirmButton", "hideCancelButton", "lockScroll", "disableConfirmButton", "closeOnOverlayClick", "confirmText", "cancelText", "closeIconPosition", "closeIcon", "onClose", "onCancel", "onConfirm", "beforeCancel", "beforeClose"]); const classPrefix = "nut-dialog"; const [loading, setLoading] = useState(false); const renderFooter = () => { if (footer === null) return ""; const handleCancel = (e) => { e.stopPropagation(); if (!(beforeCancel === null || beforeCancel === void 0 ? void 0 : beforeCancel())) return; if (!(beforeClose === null || beforeClose === void 0 ? void 0 : beforeClose())) return; onClose === null || onClose === void 0 ? void 0 : onClose(); onCancel === null || onCancel === void 0 ? void 0 : onCancel(); }; const handleOk = (e) => __awaiter(void 0, void 0, void 0, function* () { e.stopPropagation(); setLoading(true); try { yield onConfirm === null || onConfirm === void 0 ? void 0 : onConfirm(e); setLoading(false); onClose === null || onClose === void 0 ? void 0 : onClose(); } catch (_a2) { setLoading(false); } }); return footer || React__default.createElement( React__default.Fragment, null, !hideCancelButton && React__default.createElement(Button__default, { type: "default", className: `${classPrefix}-footer-cancel`, onClick: (e) => handleCancel(e) }, cancelText || locale.cancel), !hideConfirmButton && React__default.createElement(Button__default, { type: "primary", className: classNames(`${classPrefix}-footer-ok`, { disabled: disableConfirmButton }), disabled: disableConfirmButton, onClick: (e) => handleOk(e), loading }, confirmText || locale.confirm) ); }; const renderCloseIcon = () => { if (!closeIcon) return null; const handleCancel = () => { if (!(beforeCancel === null || beforeCancel === void 0 ? void 0 : beforeCancel())) return; if (!(beforeClose === null || beforeClose === void 0 ? void 0 : beforeClose())) return; onClose === null || onClose === void 0 ? void 0 : onClose(); onCancel === null || onCancel === void 0 ? void 0 : onCancel(); }; const closeClasses = classNames({ [`${classPrefix}-close`]: true, [`${classPrefix}-close-${closeIconPosition}`]: true }); return React__default.createElement("div", { className: closeClasses, onClick: handleCancel }, React__default.isValidElement(closeIcon) ? closeIcon : React__default.createElement(Close, null)); }; return React__default.createElement( "div", { style: { display: visible ? "block" : "none" } }, React__default.createElement(DialogWrap, Object.assign({}, props, { visible, lockScroll, footer: renderFooter(), close: renderCloseIcon(), onClose, onCancel })) ); }; const Dialog = forwardRef(BaseDialog); Dialog.confirm = (props) => { return confirm(props); }; ["alert"].forEach((type) => { Dialog[type] = (props) => { return confirm(Object.assign(Object.assign({}, props), { isNotice: false, noticeType: type })); }; }); Dialog.displayName = "NutDialog"; export { Dialog as default };