diff --git a/components/alert/__tests__/index.test.tsx b/components/alert/__tests__/index.test.tsx index c5edc6376c..55c0e3e57c 100644 --- a/components/alert/__tests__/index.test.tsx +++ b/components/alert/__tests__/index.test.tsx @@ -90,9 +90,10 @@ describe('Alert', () => { }); it('could be used with Popconfirm', async () => { + const ref = React.createRef(); jest.useRealTimers(); const wrapper = mount( - + { ); wrapper.find('.ant-alert').simulate('click'); await sleep(0); - expect(wrapper.find(Popconfirm).instance().getPopupDomNode()).toBeTruthy(); + expect(ref.current.getPopupDomNode()).toBeTruthy(); jest.useFakeTimers(); }); }); diff --git a/components/popconfirm/__tests__/index.test.js b/components/popconfirm/__tests__/index.test.js index 8928beeb78..4e930a12c0 100644 --- a/components/popconfirm/__tests__/index.test.js +++ b/components/popconfirm/__tests__/index.test.js @@ -40,18 +40,19 @@ describe('Popconfirm', () => { }); it('should show overlay when trigger is clicked', async () => { + const ref = React.createRef(); const popconfirm = mount( - + show me your code , ); - expect(popconfirm.instance().getPopupDomNode()).toBe(null); + expect(ref.current.getPopupDomNode()).toBe(null); popconfirm.find('span').simulate('click'); await sleep(100); - const popup = popconfirm.instance().getPopupDomNode(); + const popup = ref.current.getPopupDomNode(); expect(popup).not.toBe(null); expect(popup.className).toContain('ant-popover-placement-top'); expect(popup.innerHTML).toMatchSnapshot(); @@ -60,36 +61,39 @@ describe('Popconfirm', () => { it('shows content for render functions', async () => { const makeRenderFunction = content => () => content; + const ref = React.createRef(); const popconfirm = mount( - + show me your code , ); - expect(popconfirm.instance().getPopupDomNode()).toBe(null); + expect(ref.current.getPopupDomNode()).toBe(null); popconfirm.find('span').simulate('click'); await sleep(100); - const popup = popconfirm.instance().getPopupDomNode(); + const popup = ref.current.getPopupDomNode(); expect(popup).not.toBe(null); expect(popup.innerHTML).toContain('some-title'); expect(popup.innerHTML).toMatchSnapshot(); }); it('should be controlled by visible', () => { + const ref = React.createRef(); jest.useFakeTimers(); const popconfirm = mount( - + show me your code , ); - expect(popconfirm.instance().getPopupDomNode()).toBeFalsy(); + expect(ref.current.getPopupDomNode()).toBeFalsy(); popconfirm.setProps({ visible: true }); - expect(popconfirm.instance().getPopupDomNode()).toBeTruthy(); - expect(popconfirm.instance().getPopupDomNode().className).not.toContain('ant-popover-hidden'); + expect(ref.current.getPopupDomNode()).toBeTruthy(); + expect(ref.current.getPopupDomNode().className).not.toContain('ant-popover-hidden'); popconfirm.setProps({ visible: false }); + popconfirm.update(); // https://github.com/enzymejs/enzyme/issues/2305 jest.runAllTimers(); expect(popconfirm.find('Trigger').props().popupVisible).toBe(false); jest.useRealTimers(); @@ -115,10 +119,7 @@ describe('Popconfirm', () => { expect(confirm).toHaveBeenCalled(); expect(onVisibleChange).toHaveBeenLastCalledWith(false, eventObject); triggerNode.simulate('click'); - popconfirm - .find('.ant-btn') - .at(0) - .simulate('click'); + popconfirm.find('.ant-btn').at(0).simulate('click'); expect(cancel).toHaveBeenCalled(); expect(onVisibleChange).toHaveBeenLastCalledWith(false, eventObject); }); @@ -154,22 +155,25 @@ describe('Popconfirm', () => { }); it('should support defaultVisible', () => { - const popconfirm = mount( - + const ref = React.createRef(); + mount( + show me your code , ); - expect(popconfirm.instance().getPopupDomNode()).toBeTruthy(); + expect(ref.current.getPopupDomNode()).toBeTruthy(); }); it('should not open in disabled', () => { + const ref = React.createRef(); + const popconfirm = mount( - + click me , ); const triggerNode = popconfirm.find('span').at(0); triggerNode.simulate('click'); - expect(popconfirm.instance().getPopupDomNode()).toBeFalsy(); + expect(ref.current.getPopupDomNode()).toBeFalsy(); }); }); diff --git a/components/popconfirm/index.tsx b/components/popconfirm/index.tsx index 2941d35d14..88210dac96 100644 --- a/components/popconfirm/index.tsx +++ b/components/popconfirm/index.tsx @@ -5,7 +5,7 @@ import Button from '../button'; import { ButtonType, NativeButtonProps } from '../button/button'; import LocaleReceiver from '../locale-provider/LocaleReceiver'; import defaultLocale from '../locale/default'; -import { ConfigConsumer, ConfigConsumerProps } from '../config-provider'; +import { ConfigContext } from '../config-provider'; import { getRenderPropValue, RenderFunction } from '../_util/getRenderPropValue'; export interface PopconfirmProps extends AbstractTooltipProps { @@ -31,92 +31,57 @@ export interface PopconfirmLocale { cancelText: string; } -class Popconfirm extends React.Component { - static defaultProps = { - transitionName: 'zoom-big', - placement: 'top' as PopconfirmProps['placement'], - trigger: 'click' as PopconfirmProps['trigger'], - okType: 'primary' as PopconfirmProps['okType'], - icon: , - disabled: false, - }; +const Popconfirm = React.forwardRef((props, ref) => { + const [visible, setVisible] = React.useState(props.visible); - static getDerivedStateFromProps(nextProps: PopconfirmProps) { - if ('visible' in nextProps) { - return { visible: nextProps.visible }; - } - if ('defaultVisible' in nextProps) { - return { visible: nextProps.defaultVisible }; + React.useEffect(() => { + if ('visible' in props) { + setVisible(props.visible); } - return null; - } - - private tooltip: any; + }, [props.visible]); - constructor(props: PopconfirmProps) { - super(props); + React.useEffect(() => { + if ('defaultVisible' in props) { + setVisible(props.defaultVisible); + } + }, [props.defaultVisible]); - this.state = { - visible: props.visible, - }; - } + const settingVisible = (value: boolean, e?: React.MouseEvent) => { + if (!('visible' in props)) { + setVisible(value); + } - getPopupDomNode() { - return this.tooltip.getPopupDomNode(); - } + if (props.onVisibleChange) { + props.onVisibleChange(value, e); + } + }; - onConfirm = (e: React.MouseEvent) => { - this.setVisible(false, e); + const onConfirm = (e: React.MouseEvent) => { + settingVisible(false, e); - const { onConfirm } = this.props; - if (onConfirm) { - onConfirm.call(this, e); + if (props.onConfirm) { + props.onConfirm.call(this, e); } }; - onCancel = (e: React.MouseEvent) => { - this.setVisible(false, e); + const onCancel = (e: React.MouseEvent) => { + settingVisible(false, e); - const { onCancel } = this.props; - if (onCancel) { - onCancel.call(this, e); + if (props.onCancel) { + props.onCancel.call(this, e); } }; - onVisibleChange = (visible: boolean) => { - const { disabled } = this.props; + const onVisibleChange = (value: boolean) => { + const { disabled } = props; if (disabled) { return; } - this.setVisible(visible); + settingVisible(value); }; - setVisible(visible: boolean, e?: React.MouseEvent) { - const { props } = this; - if (!('visible' in props)) { - this.setState({ visible }); - } - - const { onVisibleChange } = props; - if (onVisibleChange) { - onVisibleChange(visible, e); - } - } - - saveTooltip = (node: any) => { - this.tooltip = node; - }; - - renderOverlay = (prefixCls: string, popconfirmLocale: PopconfirmLocale) => { - const { - okButtonProps, - cancelButtonProps, - title, - cancelText, - okText, - okType, - icon, - } = this.props; + const renderOverlay = (prefixCls: string, popconfirmLocale: PopconfirmLocale) => { + const { okButtonProps, cancelButtonProps, title, cancelText, okText, okType, icon } = props; return (
@@ -124,10 +89,10 @@ class Popconfirm extends React.Component {
{getRenderPropValue(title)}
- -
@@ -135,32 +100,37 @@ class Popconfirm extends React.Component { ); }; - renderConfirm = ({ getPrefixCls }: ConfigConsumerProps) => { - const { prefixCls: customizePrefixCls, placement, ...restProps } = this.props; - const prefixCls = getPrefixCls('popover', customizePrefixCls); - - const overlay = ( - - {(popconfirmLocale: PopconfirmLocale) => this.renderOverlay(prefixCls, popconfirmLocale)} - - ); - - return ( - - ); - }; - - render() { - return {this.renderConfirm}; - } -} + const { getPrefixCls } = React.useContext(ConfigContext); + + const { prefixCls: customizePrefixCls, placement, ...restProps } = props; + const prefixCls = getPrefixCls('popover', customizePrefixCls); + + const overlay = ( + + {(popconfirmLocale: PopconfirmLocale) => renderOverlay(prefixCls, popconfirmLocale)} + + ); + + return ( + + ); +}); + +Popconfirm.defaultProps = { + transitionName: 'zoom-big', + placement: 'top' as PopconfirmProps['placement'], + trigger: 'click' as PopconfirmProps['trigger'], + okType: 'primary' as PopconfirmProps['okType'], + icon: , + disabled: false, +}; export default Popconfirm;