refactor: move popconfirm content out (#36530)

* refactor: move popconfirm content out

* fix: lint
This commit is contained in:
二货机器人 2022-07-15 11:11:50 +08:00 committed by GitHub
parent 2255dbada6
commit 006c055cf8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 102 additions and 64 deletions

View File

@ -7,7 +7,7 @@ import { convertLegacyProps } from '../button/button';
export interface ActionButtonProps {
type?: LegacyButtonType;
actionFn?: (...args: any[]) => any | PromiseLike<any>;
close: Function;
close?: Function;
autoFocus?: boolean;
prefixCls: string;
buttonProps?: ButtonProps;
@ -24,6 +24,10 @@ const ActionButton: React.FC<ActionButtonProps> = props => {
const clickedRef = React.useRef<boolean>(false);
const ref = React.useRef<any>();
const [loading, setLoading] = useState<ButtonProps['loading']>(false);
const { close } = props;
const onInternalClose = (...args: any[]) => {
close?.(...args);
};
React.useEffect(() => {
let timeoutId: any;
@ -39,7 +43,6 @@ const ActionButton: React.FC<ActionButtonProps> = props => {
}, []);
const handlePromiseOnOk = (returnValueOfOnOk?: PromiseLike<any>) => {
const { close } = props;
if (!isThenable(returnValueOfOnOk)) {
return;
}
@ -47,7 +50,7 @@ const ActionButton: React.FC<ActionButtonProps> = props => {
returnValueOfOnOk!.then(
(...args: any[]) => {
setLoading(false, true);
close(...args);
onInternalClose(...args);
clickedRef.current = false;
},
(e: Error) => {
@ -62,13 +65,13 @@ const ActionButton: React.FC<ActionButtonProps> = props => {
};
const onClick = (e: React.MouseEvent<HTMLButtonElement>) => {
const { actionFn, close } = props;
const { actionFn } = props;
if (clickedRef.current) {
return;
}
clickedRef.current = true;
if (!actionFn) {
close();
onInternalClose();
return;
}
let returnValueOfOnOk;
@ -76,7 +79,7 @@ const ActionButton: React.FC<ActionButtonProps> = props => {
returnValueOfOnOk = actionFn(e);
if (props.quitOnNullishReturnValue && !isThenable(returnValueOfOnOk)) {
clickedRef.current = false;
close(e);
onInternalClose(e);
return;
}
} else if (actionFn.length) {
@ -86,7 +89,7 @@ const ActionButton: React.FC<ActionButtonProps> = props => {
} else {
returnValueOfOnOk = actionFn();
if (!returnValueOfOnOk) {
close();
onInternalClose();
return;
}
}

View File

@ -8,7 +8,7 @@ import type { TransferLocale as TransferLocaleForEmpty } from '../empty';
import type { ModalLocale } from '../modal/locale';
import { changeConfirmLocale } from '../modal/locale';
import type { PaginationLocale } from '../pagination/Pagination';
import type { PopconfirmLocale } from '../popconfirm';
import type { PopconfirmLocale } from '../popconfirm/PurePanel';
import type { TableLocale } from '../table/interface';
import type { TransferLocale } from '../transfer';
import type { UploadLocale } from '../upload/interface';

View File

@ -0,0 +1,81 @@
import * as React from 'react';
import type { PopconfirmProps } from '.';
import Button from '../button';
import { convertLegacyProps } from '../button/button';
import ActionButton from '../_util/ActionButton';
import LocaleReceiver from '../locale-provider/LocaleReceiver';
import defaultLocale from '../locale/default';
import { getRenderPropValue } from '../_util/getRenderPropValue';
import { ConfigContext } from '../config-provider';
export interface PopconfirmLocale {
okText: string;
cancelText: string;
}
export interface OverlayProps
extends Pick<
PopconfirmProps,
| 'icon'
| 'okButtonProps'
| 'cancelButtonProps'
| 'cancelText'
| 'okText'
| 'okType'
| 'showCancel'
| 'title'
> {
prefixCls: string;
close?: Function;
onConfirm?: React.MouseEventHandler<HTMLButtonElement>;
onCancel?: React.MouseEventHandler<HTMLButtonElement>;
}
export function Overlay(props: OverlayProps) {
const {
prefixCls,
okButtonProps,
cancelButtonProps,
title,
cancelText,
okText,
okType,
icon,
showCancel = true,
close,
onConfirm,
onCancel,
} = props;
const { getPrefixCls } = React.useContext(ConfigContext);
return (
<LocaleReceiver componentName="Popconfirm" defaultLocale={defaultLocale.Popconfirm}>
{(popconfirmLocale: PopconfirmLocale) => (
<div className={`${prefixCls}-inner-content`}>
<div className={`${prefixCls}-message`}>
{icon}
<div className={`${prefixCls}-message-title`}>{getRenderPropValue(title)}</div>
</div>
<div className={`${prefixCls}-buttons`}>
{showCancel && (
<Button onClick={onCancel} size="small" {...cancelButtonProps}>
{cancelText || popconfirmLocale.cancelText}
</Button>
)}
<ActionButton
buttonProps={{ size: 'small', ...convertLegacyProps(okType), ...okButtonProps }}
actionFn={onConfirm}
close={close}
prefixCls={getPrefixCls('btn')}
quitOnNullishReturnValue
emitEvent
>
{okText || popconfirmLocale.okText}
</ActionButton>
</div>
</div>
)}
</LocaleReceiver>
);
}

View File

@ -3,18 +3,13 @@ import classNames from 'classnames';
import useMergedState from 'rc-util/lib/hooks/useMergedState';
import KeyCode from 'rc-util/lib/KeyCode';
import * as React from 'react';
import Button from '../button';
import type { ButtonProps, LegacyButtonType } from '../button/button';
import { convertLegacyProps } from '../button/button';
import { ConfigContext } from '../config-provider';
import LocaleReceiver from '../locale-provider/LocaleReceiver';
import defaultLocale from '../locale/default';
import Popover from '../popover';
import type { AbstractTooltipProps } from '../tooltip';
import ActionButton from '../_util/ActionButton';
import type { RenderFunction } from '../_util/getRenderPropValue';
import { getRenderPropValue } from '../_util/getRenderPropValue';
import { cloneElement } from '../_util/reactNode';
import { Overlay } from './PurePanel';
export interface PopconfirmProps extends AbstractTooltipProps {
title: React.ReactNode | RenderFunction;
@ -38,11 +33,6 @@ export interface PopconfirmState {
visible?: boolean;
}
export interface PopconfirmLocale {
okText: string;
cancelText: string;
}
const Popconfirm = React.forwardRef<unknown, PopconfirmProps>((props, ref) => {
const { getPrefixCls } = React.useContext(ConfigContext);
const [visible, setVisible] = useMergedState(false, {
@ -85,44 +75,6 @@ const Popconfirm = React.forwardRef<unknown, PopconfirmProps>((props, ref) => {
settingVisible(value);
};
const renderOverlay = (prefixCls: string, popconfirmLocale: PopconfirmLocale) => {
const {
okButtonProps,
cancelButtonProps,
title,
cancelText,
okText,
okType,
icon,
showCancel = true,
} = props;
return (
<div className={`${prefixCls}-inner-content`}>
<div className={`${prefixCls}-message`}>
{icon}
<div className={`${prefixCls}-message-title`}>{getRenderPropValue(title)}</div>
</div>
<div className={`${prefixCls}-buttons`}>
{showCancel && (
<Button onClick={onCancel} size="small" {...cancelButtonProps}>
{cancelText || popconfirmLocale.cancelText}
</Button>
)}
<ActionButton
buttonProps={{ size: 'small', ...convertLegacyProps(okType), ...okButtonProps }}
actionFn={onConfirm}
close={close}
prefixCls={getPrefixCls('btn')}
quitOnNullishReturnValue
emitEvent
>
{okText || popconfirmLocale.okText}
</ActionButton>
</div>
</div>
);
};
const {
prefixCls: customizePrefixCls,
placement,
@ -134,12 +86,6 @@ const Popconfirm = React.forwardRef<unknown, PopconfirmProps>((props, ref) => {
const prefixClsConfirm = getPrefixCls('popconfirm', customizePrefixCls);
const overlayClassNames = classNames(prefixClsConfirm, overlayClassName);
const overlay = (
<LocaleReceiver componentName="Popconfirm" defaultLocale={defaultLocale.Popconfirm}>
{(popconfirmLocale: PopconfirmLocale) => renderOverlay(prefixCls, popconfirmLocale)}
</LocaleReceiver>
);
return (
<Popover
{...restProps}
@ -147,7 +93,15 @@ const Popconfirm = React.forwardRef<unknown, PopconfirmProps>((props, ref) => {
placement={placement}
onVisibleChange={onVisibleChange}
visible={visible}
_overlay={overlay}
_overlay={
<Overlay
{...props}
prefixCls={prefixCls}
close={close}
onConfirm={onConfirm}
onCancel={onCancel}
/>
}
overlayClassName={overlayClassNames}
ref={ref as any}
>