diff --git a/components/modal/ConfirmDialog.tsx b/components/modal/ConfirmDialog.tsx index ca9dd2f7db..a7f8106249 100644 --- a/components/modal/ConfirmDialog.tsx +++ b/components/modal/ConfirmDialog.tsx @@ -1,19 +1,23 @@ +import * as React from 'react'; import CheckCircleFilled from '@ant-design/icons/CheckCircleFilled'; import CloseCircleFilled from '@ant-design/icons/CloseCircleFilled'; import ExclamationCircleFilled from '@ant-design/icons/ExclamationCircleFilled'; import InfoCircleFilled from '@ant-design/icons/InfoCircleFilled'; import classNames from 'classnames'; -import * as React from 'react'; -import ActionButton from '../_util/ActionButton'; + import { getTransitionName } from '../_util/motion'; import warning from '../_util/warning'; import type { ThemeConfig } from '../config-provider'; import ConfigProvider from '../config-provider'; import { useLocale } from '../locale'; -import Dialog from './Modal'; +import CancelBtn from './components/ConfirmCancelBtn'; +import OkBtn from './components/ConfirmOkBtn'; +import type { ModalContextProps } from './context'; +import { ModalContextProvider } from './context'; import type { ModalFuncProps, ModalLocale } from './interface'; +import Dialog from './Modal'; -interface ConfirmDialogProps extends ModalFuncProps { +export interface ConfirmDialogProps extends ModalFuncProps { afterClose?: () => void; close?: (...args: any[]) => void; /** @@ -23,7 +27,7 @@ interface ConfirmDialogProps extends ModalFuncProps { */ onConfirm?: (confirmed: boolean) => void; autoFocusButton?: null | 'ok' | 'cancel'; - rootPrefixCls: string; + rootPrefixCls?: string; iconPrefixCls?: string; theme?: ThemeConfig; @@ -43,22 +47,15 @@ export function ConfirmContent( ) { const { icon, - onCancel, - onOk, - close, - onConfirm, - isSilent, okText, - okButtonProps, cancelText, - cancelButtonProps, confirmPrefixCls, - rootPrefixCls, type, okCancel, footer, // Legacy for static function usage locale: staticLocale, + ...resetProps } = props; warning( @@ -90,7 +87,6 @@ export function ConfirmContent( } } - const okType = props.okType || 'primary'; // 默认为 true,保持向下兼容 const mergedOkCancel = okCancel ?? type === 'confirm'; @@ -100,20 +96,26 @@ export function ConfirmContent( const mergedLocale = staticLocale || locale; - const cancelButton = mergedOkCancel && ( - { - close?.(...args); - onConfirm?.(false); - }} - autoFocus={autoFocusButton === 'cancel'} - buttonProps={cancelButtonProps} - prefixCls={`${rootPrefixCls}-btn`} - > - {cancelText || mergedLocale?.cancelText} - + // ================== Locale Text ================== + const okTextLocale = okText || (mergedOkCancel ? mergedLocale?.okText : mergedLocale?.justOkText); + const cancelTextLocale = cancelText || mergedLocale?.cancelText; + + // ================= Context Value ================= + const btnCtxValue: ModalContextProps = { + autoFocusButton, + cancelTextLocale, + okTextLocale, + mergedOkCancel, + ...resetProps, + }; + const btnCtxValueMemo = React.useMemo(() => btnCtxValue, [...Object.values(btnCtxValue)]); + + // ====================== Footer Origin Node ====================== + const footerOriginNode = ( + <> + + + ); return ( @@ -125,24 +127,18 @@ export function ConfirmContent( )}
{props.content}
- {footer === undefined ? ( -
- {cancelButton} - { - close?.(...args); - onConfirm?.(true); - }} - autoFocus={autoFocusButton === 'ok'} - buttonProps={okButtonProps} - prefixCls={`${rootPrefixCls}-btn`} - > - {okText || (mergedOkCancel ? mergedLocale?.okText : mergedLocale?.justOkText)} - -
+ + {footer === undefined || typeof footer === 'function' ? ( + +
+ {typeof footer === 'function' + ? footer(footerOriginNode, { + OkBtn, + CancelBtn, + }) + : footerOriginNode} +
+
) : ( footer )} @@ -215,8 +211,12 @@ const ConfirmDialog: React.FC = (props) => { open={open} title="" footer={null} - transitionName={getTransitionName(rootPrefixCls, 'zoom', props.transitionName)} - maskTransitionName={getTransitionName(rootPrefixCls, 'fade', props.maskTransitionName)} + transitionName={getTransitionName(rootPrefixCls || '', 'zoom', props.transitionName)} + maskTransitionName={getTransitionName( + rootPrefixCls || '', + 'fade', + props.maskTransitionName, + )} mask={mask} maskClosable={maskClosable} maskStyle={maskStyle} diff --git a/components/modal/Modal.tsx b/components/modal/Modal.tsx index 7a5138ab5f..6bb5ad1ef7 100644 --- a/components/modal/Modal.tsx +++ b/components/modal/Modal.tsx @@ -1,7 +1,8 @@ +import * as React from 'react'; import CloseOutlined from '@ant-design/icons/CloseOutlined'; import classNames from 'classnames'; import Dialog from 'rc-dialog'; -import * as React from 'react'; + import useClosable from '../_util/hooks/useClosable'; import { getTransitionName } from '../_util/motion'; import { canUseDocElement } from '../_util/styleChecker'; @@ -9,10 +10,10 @@ import warning from '../_util/warning'; import { ConfigContext } from '../config-provider'; import { NoFormStyle } from '../form/context'; import { NoCompactStyle } from '../space/Compact'; +import { usePanelRef } from '../watermark/context'; import type { ModalProps, MousePosition } from './interface'; import { Footer, renderCloseIcon } from './shared'; import useStyle from './style'; -import { usePanelRef } from '../watermark/context'; let mousePosition: MousePosition; @@ -93,9 +94,9 @@ const Modal: React.FC = (props) => { warning(!('visible' in props), 'Modal', '`visible` is deprecated, please use `open` instead.'); } - const dialogFooter = - footer === undefined ?