diff --git a/components/popconfirm/__tests__/index.test.js b/components/popconfirm/__tests__/index.test.js
index 4e930a12c0..78ce927c12 100644
--- a/components/popconfirm/__tests__/index.test.js
+++ b/components/popconfirm/__tests__/index.test.js
@@ -176,4 +176,23 @@ describe('Popconfirm', () => {
triggerNode.simulate('click');
expect(ref.current.getPopupDomNode()).toBeFalsy();
});
+
+ it('should be closed by pressing ESC', () => {
+ const onVisibleChange = jest.fn();
+ const wrapper = mount(
+
+ Delete
+ ,
+ );
+ const triggerNode = wrapper.find('span').at(0);
+ triggerNode.simulate('click');
+ expect(onVisibleChange).toHaveBeenLastCalledWith(true, undefined);
+ triggerNode.simulate('keydown', { key: 'Escape', keyCode: 27 });
+ expect(onVisibleChange).toHaveBeenLastCalledWith(false, eventObject);
+ });
});
diff --git a/components/popconfirm/index.tsx b/components/popconfirm/index.tsx
index 673d470f22..1462d1e133 100644
--- a/components/popconfirm/index.tsx
+++ b/components/popconfirm/index.tsx
@@ -1,5 +1,6 @@
import * as React from 'react';
import ExclamationCircleFilled from '@ant-design/icons/ExclamationCircleFilled';
+import KeyCode from 'rc-util/lib/KeyCode';
import Tooltip, { AbstractTooltipProps } from '../tooltip';
import Button from '../button';
import { LegacyButtonType, NativeButtonProps, convertLegacyProps } from '../button/button';
@@ -7,6 +8,7 @@ import LocaleReceiver from '../locale-provider/LocaleReceiver';
import defaultLocale from '../locale/default';
import { ConfigContext } from '../config-provider';
import { getRenderPropValue, RenderFunction } from '../_util/getRenderPropValue';
+import { cloneElement } from '../_util/reactNode';
export interface PopconfirmProps extends AbstractTooltipProps {
title: React.ReactNode | RenderFunction;
@@ -19,7 +21,10 @@ export interface PopconfirmProps extends AbstractTooltipProps {
okButtonProps?: NativeButtonProps;
cancelButtonProps?: NativeButtonProps;
icon?: React.ReactNode;
- onVisibleChange?: (visible: boolean, e?: React.MouseEvent) => void;
+ onVisibleChange?: (
+ visible: boolean,
+ e?: React.MouseEvent | React.KeyboardEvent,
+ ) => void;
}
export interface PopconfirmState {
@@ -46,7 +51,10 @@ const Popconfirm = React.forwardRef((props, ref) => {
}
}, [props.defaultVisible]);
- const settingVisible = (value: boolean, e?: React.MouseEvent) => {
+ const settingVisible = (
+ value: boolean,
+ e?: React.MouseEvent | React.KeyboardEvent,
+ ) => {
if (!('visible' in props)) {
setVisible(value);
}
@@ -72,6 +80,12 @@ const Popconfirm = React.forwardRef((props, ref) => {
}
};
+ const onKeyDown = (e: React.KeyboardEvent) => {
+ if (e.keyCode === KeyCode.ESC && visible) {
+ settingVisible(false, e);
+ }
+ };
+
const onVisibleChange = (value: boolean) => {
const { disabled } = props;
if (disabled) {
@@ -107,7 +121,7 @@ const Popconfirm = React.forwardRef((props, ref) => {
const { getPrefixCls } = React.useContext(ConfigContext);
- const { prefixCls: customizePrefixCls, placement, ...restProps } = props;
+ const { prefixCls: customizePrefixCls, placement, children, ...restProps } = props;
const prefixCls = getPrefixCls('popover', customizePrefixCls);
const overlay = (
@@ -125,7 +139,14 @@ const Popconfirm = React.forwardRef((props, ref) => {
visible={visible}
overlay={overlay}
ref={ref as any}
- />
+ >
+ {cloneElement(children, {
+ onKeyDown: (e: React.KeyboardEvent) => {
+ children?.props.onKeyDown?.(e);
+ onKeyDown(e);
+ },
+ })}
+
);
});