1. import * as React from 'react';
    2. import classNames from 'classnames';
    3. import { Tooltip, PopconfirmProps, Button, } from 'antd';
    4. import useMergedState from 'rc-util/lib/hooks/useMergedState'
    5. import { convertLegacyProps } from 'antd/lib/button/button'
    6. import { ExclamationCircleFilled } from '@ant-design/icons';
    7. import KeyCode from 'rc-util/lib/KeyCode';
    8. import { ConfigContext } from 'antd/lib/config-provider';
    9. import { cloneElement } from 'antd/lib/_util/reactNode'
    10. import { MouseEventHandler } from 'react';
    11. import { CSSProperties } from 'react';
    12. /**
    13. * 把按钮重定义为链接的Ant Desing Popconfirm组件
    14. *
    15. * @param
    16. */
    17. export interface PopConfirmProps extends PopconfirmProps {
    18. buttonStyle?: string,
    19. okLinkStyle?: CSSProperties;
    20. cancelLinkStyle?: CSSProperties;
    21. }
    22. const PopConfirm = React.forwardRef<unknown, PopConfirmProps> ((props, ref) => {
    23. const { buttonStyle='link', okLinkStyle={}, cancelLinkStyle={} } = props;
    24. const [visible, setVisible] = useMergedState(false, {
    25. value: props.visible,
    26. defaultValue: props.defaultVisible,
    27. });
    28. const settingVisible = (
    29. value: boolean,
    30. e?: React.MouseEvent<HTMLAnchorElement> | React.KeyboardEvent<HTMLDivElement>,
    31. ) => {
    32. setVisible(value);
    33. props.onVisibleChange?.(value, e);
    34. };
    35. const onConfirm:MouseEventHandler<HTMLAnchorElement> = (e: React.MouseEvent<HTMLAnchorElement>) => {
    36. settingVisible(false, e);
    37. props.onConfirm?.call(this, e);
    38. };
    39. const onCancel:MouseEventHandler<HTMLAnchorElement> = (e: React.MouseEvent<HTMLAnchorElement>) => {
    40. settingVisible(false, e);
    41. props.onCancel?.call(this, e);
    42. };
    43. const onKeyDown = (e: React.KeyboardEvent<HTMLDivElement>) => {
    44. if (e.keyCode === KeyCode.ESC && visible) {
    45. settingVisible(false, e);
    46. }
    47. };
    48. const onVisibleChange = (value: boolean) => {
    49. const { disabled } = props;
    50. if (disabled) {
    51. return;
    52. }
    53. settingVisible(value);
    54. };
    55. const renderOverlay = (prefixCls: string) => {
    56. const { okButtonProps, cancelButtonProps, title, cancelText, okText, okType, icon } = props;
    57. return (
    58. <div className={`${prefixCls}-inner-content`}>
    59. <div className={`${prefixCls}-message`}>
    60. {icon}
    61. <div className={`${prefixCls}-message-title`}>{title}</div>
    62. </div>
    63. { buttonStyle === 'link' &&
    64. <div className={`${prefixCls}-buttons`}>
    65. <a onClick={onCancel} style={{...cancelLinkStyle}}>
    66. {cancelText}
    67. </a>
    68. <a onClick={onConfirm} {...okType} style={{marginLeft: '7px',marginRight: '7px',color: 'darkred',...okLinkStyle}}>
    69. {okText}
    70. </a>
    71. </div>}
    72. {
    73. buttonStyle !== 'link' &&
    74. <div className={`${prefixCls}-buttons`}>
    75. <Button onClick={onCancel} size="small" {...cancelButtonProps}>
    76. {cancelText}
    77. </Button>
    78. <Button
    79. onClick={onConfirm}
    80. {...convertLegacyProps(okType)}
    81. size="small"
    82. {...okButtonProps}
    83. >
    84. {okText}
    85. </Button>
    86. </div>
    87. }
    88. </div>
    89. );
    90. };
    91. const { getPrefixCls } = React.useContext(ConfigContext);
    92. const {
    93. prefixCls: customizePrefixCls,
    94. placement,
    95. children,
    96. overlayClassName,
    97. ...restProps
    98. } = props;
    99. const prefixCls = getPrefixCls('popover', customizePrefixCls);
    100. const prefixClsConfirm = getPrefixCls('popconfirm', customizePrefixCls);
    101. const overlayClassNames = classNames(prefixClsConfirm, overlayClassName);
    102. return (
    103. <Tooltip
    104. {...restProps}
    105. prefixCls={prefixCls}
    106. placement={placement}
    107. ref={ref as any}
    108. visible={visible}
    109. overlay={ () => renderOverlay(prefixCls)}
    110. overlayClassName={overlayClassNames}
    111. onVisibleChange={onVisibleChange}
    112. >
    113. { cloneElement(children, {
    114. onKeyDown: (e: React.KeyboardEvent<any>) => {
    115. if (React.isValidElement(children)) {
    116. children?.props.onKeyDown?.(e);
    117. }
    118. onKeyDown(e);
    119. },
    120. })}
    121. </Tooltip>
    122. );
    123. });
    124. PopConfirm.defaultProps = {
    125. placement: 'top' as PopConfirmProps['placement'],
    126. trigger: 'click' as PopConfirmProps['trigger'],
    127. okType: 'primary' as PopConfirmProps['okType'],
    128. icon: <ExclamationCircleFilled />,
    129. disabled: false,
    130. };
    131. export default PopConfirm;