mirror of
https://gitee.com/ant-design/ant-design.git
synced 2024-12-02 20:19:44 +08:00
feat: ⌨️ Popconfirm can be closed by pressing ESC (#24420)
* feat: support ESC to close Popconfirm close #15203 * add test case * fix focus in other element inside inner-content * no fit * fix snapshot * refactor it * use util cloneElement * fix test case
This commit is contained in:
parent
4b485d393b
commit
c93400d375
@ -176,4 +176,23 @@ describe('Popconfirm', () => {
|
|||||||
triggerNode.simulate('click');
|
triggerNode.simulate('click');
|
||||||
expect(ref.current.getPopupDomNode()).toBeFalsy();
|
expect(ref.current.getPopupDomNode()).toBeFalsy();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should be closed by pressing ESC', () => {
|
||||||
|
const onVisibleChange = jest.fn();
|
||||||
|
const wrapper = mount(
|
||||||
|
<Popconfirm
|
||||||
|
title="title"
|
||||||
|
mouseEnterDelay={0}
|
||||||
|
mouseLeaveDelay={0}
|
||||||
|
onVisibleChange={onVisibleChange}
|
||||||
|
>
|
||||||
|
<span>Delete</span>
|
||||||
|
</Popconfirm>,
|
||||||
|
);
|
||||||
|
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);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
import * as React from 'react';
|
import * as React from 'react';
|
||||||
import ExclamationCircleFilled from '@ant-design/icons/ExclamationCircleFilled';
|
import ExclamationCircleFilled from '@ant-design/icons/ExclamationCircleFilled';
|
||||||
|
import KeyCode from 'rc-util/lib/KeyCode';
|
||||||
import Tooltip, { AbstractTooltipProps } from '../tooltip';
|
import Tooltip, { AbstractTooltipProps } from '../tooltip';
|
||||||
import Button from '../button';
|
import Button from '../button';
|
||||||
import { LegacyButtonType, NativeButtonProps, convertLegacyProps } from '../button/button';
|
import { LegacyButtonType, NativeButtonProps, convertLegacyProps } from '../button/button';
|
||||||
@ -7,6 +8,7 @@ import LocaleReceiver from '../locale-provider/LocaleReceiver';
|
|||||||
import defaultLocale from '../locale/default';
|
import defaultLocale from '../locale/default';
|
||||||
import { ConfigContext } from '../config-provider';
|
import { ConfigContext } from '../config-provider';
|
||||||
import { getRenderPropValue, RenderFunction } from '../_util/getRenderPropValue';
|
import { getRenderPropValue, RenderFunction } from '../_util/getRenderPropValue';
|
||||||
|
import { cloneElement } from '../_util/reactNode';
|
||||||
|
|
||||||
export interface PopconfirmProps extends AbstractTooltipProps {
|
export interface PopconfirmProps extends AbstractTooltipProps {
|
||||||
title: React.ReactNode | RenderFunction;
|
title: React.ReactNode | RenderFunction;
|
||||||
@ -19,7 +21,10 @@ export interface PopconfirmProps extends AbstractTooltipProps {
|
|||||||
okButtonProps?: NativeButtonProps;
|
okButtonProps?: NativeButtonProps;
|
||||||
cancelButtonProps?: NativeButtonProps;
|
cancelButtonProps?: NativeButtonProps;
|
||||||
icon?: React.ReactNode;
|
icon?: React.ReactNode;
|
||||||
onVisibleChange?: (visible: boolean, e?: React.MouseEvent<HTMLElement>) => void;
|
onVisibleChange?: (
|
||||||
|
visible: boolean,
|
||||||
|
e?: React.MouseEvent<HTMLElement> | React.KeyboardEvent<HTMLDivElement>,
|
||||||
|
) => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface PopconfirmState {
|
export interface PopconfirmState {
|
||||||
@ -46,7 +51,10 @@ const Popconfirm = React.forwardRef<unknown, PopconfirmProps>((props, ref) => {
|
|||||||
}
|
}
|
||||||
}, [props.defaultVisible]);
|
}, [props.defaultVisible]);
|
||||||
|
|
||||||
const settingVisible = (value: boolean, e?: React.MouseEvent<HTMLButtonElement>) => {
|
const settingVisible = (
|
||||||
|
value: boolean,
|
||||||
|
e?: React.MouseEvent<HTMLButtonElement> | React.KeyboardEvent<HTMLDivElement>,
|
||||||
|
) => {
|
||||||
if (!('visible' in props)) {
|
if (!('visible' in props)) {
|
||||||
setVisible(value);
|
setVisible(value);
|
||||||
}
|
}
|
||||||
@ -72,6 +80,12 @@ const Popconfirm = React.forwardRef<unknown, PopconfirmProps>((props, ref) => {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const onKeyDown = (e: React.KeyboardEvent<HTMLDivElement>) => {
|
||||||
|
if (e.keyCode === KeyCode.ESC && visible) {
|
||||||
|
settingVisible(false, e);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
const onVisibleChange = (value: boolean) => {
|
const onVisibleChange = (value: boolean) => {
|
||||||
const { disabled } = props;
|
const { disabled } = props;
|
||||||
if (disabled) {
|
if (disabled) {
|
||||||
@ -107,7 +121,7 @@ const Popconfirm = React.forwardRef<unknown, PopconfirmProps>((props, ref) => {
|
|||||||
|
|
||||||
const { getPrefixCls } = React.useContext(ConfigContext);
|
const { getPrefixCls } = React.useContext(ConfigContext);
|
||||||
|
|
||||||
const { prefixCls: customizePrefixCls, placement, ...restProps } = props;
|
const { prefixCls: customizePrefixCls, placement, children, ...restProps } = props;
|
||||||
const prefixCls = getPrefixCls('popover', customizePrefixCls);
|
const prefixCls = getPrefixCls('popover', customizePrefixCls);
|
||||||
|
|
||||||
const overlay = (
|
const overlay = (
|
||||||
@ -125,7 +139,14 @@ const Popconfirm = React.forwardRef<unknown, PopconfirmProps>((props, ref) => {
|
|||||||
visible={visible}
|
visible={visible}
|
||||||
overlay={overlay}
|
overlay={overlay}
|
||||||
ref={ref as any}
|
ref={ref as any}
|
||||||
/>
|
>
|
||||||
|
{cloneElement(children, {
|
||||||
|
onKeyDown: (e: React.KeyboardEvent<any>) => {
|
||||||
|
children?.props.onKeyDown?.(e);
|
||||||
|
onKeyDown(e);
|
||||||
|
},
|
||||||
|
})}
|
||||||
|
</Tooltip>
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user