import * as React from 'react';
import classNames from 'classnames';
import { Tooltip, PopconfirmProps, Button, } from 'antd';
import useMergedState from 'rc-util/lib/hooks/useMergedState'
import { convertLegacyProps } from 'antd/lib/button/button'
import { ExclamationCircleFilled } from '@ant-design/icons';
import KeyCode from 'rc-util/lib/KeyCode';
import { ConfigContext } from 'antd/lib/config-provider';
import { cloneElement } from 'antd/lib/_util/reactNode'
import { MouseEventHandler } from 'react';
import { CSSProperties } from 'react';
/**
* 把按钮重定义为链接的Ant Desing Popconfirm组件
*
* @param
*/
export interface PopConfirmProps extends PopconfirmProps {
buttonStyle?: string,
okLinkStyle?: CSSProperties;
cancelLinkStyle?: CSSProperties;
}
const PopConfirm = React.forwardRef<unknown, PopConfirmProps> ((props, ref) => {
const { buttonStyle='link', okLinkStyle={}, cancelLinkStyle={} } = props;
const [visible, setVisible] = useMergedState(false, {
value: props.visible,
defaultValue: props.defaultVisible,
});
const settingVisible = (
value: boolean,
e?: React.MouseEvent<HTMLAnchorElement> | React.KeyboardEvent<HTMLDivElement>,
) => {
setVisible(value);
props.onVisibleChange?.(value, e);
};
const onConfirm:MouseEventHandler<HTMLAnchorElement> = (e: React.MouseEvent<HTMLAnchorElement>) => {
settingVisible(false, e);
props.onConfirm?.call(this, e);
};
const onCancel:MouseEventHandler<HTMLAnchorElement> = (e: React.MouseEvent<HTMLAnchorElement>) => {
settingVisible(false, e);
props.onCancel?.call(this, e);
};
const onKeyDown = (e: React.KeyboardEvent<HTMLDivElement>) => {
if (e.keyCode === KeyCode.ESC && visible) {
settingVisible(false, e);
}
};
const onVisibleChange = (value: boolean) => {
const { disabled } = props;
if (disabled) {
return;
}
settingVisible(value);
};
const renderOverlay = (prefixCls: string) => {
const { okButtonProps, cancelButtonProps, title, cancelText, okText, okType, icon } = props;
return (
<div className={`${prefixCls}-inner-content`}>
<div className={`${prefixCls}-message`}>
{icon}
<div className={`${prefixCls}-message-title`}>{title}</div>
</div>
{ buttonStyle === 'link' &&
<div className={`${prefixCls}-buttons`}>
<a onClick={onCancel} style={{...cancelLinkStyle}}>
{cancelText}
</a>
<a onClick={onConfirm} {...okType} style={{marginLeft: '7px',marginRight: '7px',color: 'darkred',...okLinkStyle}}>
{okText}
</a>
</div>}
{
buttonStyle !== 'link' &&
<div className={`${prefixCls}-buttons`}>
<Button onClick={onCancel} size="small" {...cancelButtonProps}>
{cancelText}
</Button>
<Button
onClick={onConfirm}
{...convertLegacyProps(okType)}
size="small"
{...okButtonProps}
>
{okText}
</Button>
</div>
}
</div>
);
};
const { getPrefixCls } = React.useContext(ConfigContext);
const {
prefixCls: customizePrefixCls,
placement,
children,
overlayClassName,
...restProps
} = props;
const prefixCls = getPrefixCls('popover', customizePrefixCls);
const prefixClsConfirm = getPrefixCls('popconfirm', customizePrefixCls);
const overlayClassNames = classNames(prefixClsConfirm, overlayClassName);
return (
<Tooltip
{...restProps}
prefixCls={prefixCls}
placement={placement}
ref={ref as any}
visible={visible}
overlay={ () => renderOverlay(prefixCls)}
overlayClassName={overlayClassNames}
onVisibleChange={onVisibleChange}
>
{ cloneElement(children, {
onKeyDown: (e: React.KeyboardEvent<any>) => {
if (React.isValidElement(children)) {
children?.props.onKeyDown?.(e);
}
onKeyDown(e);
},
})}
</Tooltip>
);
});
PopConfirm.defaultProps = {
placement: 'top' as PopConfirmProps['placement'],
trigger: 'click' as PopConfirmProps['trigger'],
okType: 'primary' as PopConfirmProps['okType'],
icon: <ExclamationCircleFilled />,
disabled: false,
};
export default PopConfirm;