diff --git a/.github/workflows/release-helper.yml b/.github/workflows/release-helper.yml index 6c5d376bf6..401f67d71e 100644 --- a/.github/workflows/release-helper.yml +++ b/.github/workflows/release-helper.yml @@ -28,7 +28,6 @@ jobs: branch: 'master' dingding-token: ${{ secrets.DINGDING_BOT_TOKEN }} dingding-msg: 'CHANGELOG.zh-CN.md' - dingding-delay-minute: 10 msg-title: '# Ant Design {{v}} 发布日志' msg-poster: 'https://gw.alipayobjects.com/mdn/rms_08e378/afts/img/A*zx7LTI_ECSAAAAAAAAAAAABkARQnAQ' msg-footer: '💬 前往 [**Ant Design Releases**]({{url}}) 查看更新日志' @@ -44,6 +43,7 @@ jobs: dingding-token: ${{ secrets.DINGDING_BOT_BIGFISH_TOKEN }} dingding-msg: 'CHANGELOG.zh-CN.md' dingding-delay-minute: 10 + release: false antd-conch-msg: '🐟 当前 Bigfish 内嵌 antd 版本:' msg-title: '# Ant Design {{v}} 发布日志' msg-poster: 'https://gw.alipayobjects.com/mdn/rms_08e378/afts/img/A*zx7LTI_ECSAAAAAAAAAAAABkARQnAQ' diff --git a/components/collapse/__tests__/__snapshots__/demo.test.js.snap b/components/collapse/__tests__/__snapshots__/demo.test.ts.snap similarity index 100% rename from components/collapse/__tests__/__snapshots__/demo.test.js.snap rename to components/collapse/__tests__/__snapshots__/demo.test.ts.snap diff --git a/components/collapse/__tests__/__snapshots__/index.test.js.snap b/components/collapse/__tests__/__snapshots__/index.test.tsx.snap similarity index 100% rename from components/collapse/__tests__/__snapshots__/index.test.js.snap rename to components/collapse/__tests__/__snapshots__/index.test.tsx.snap diff --git a/components/collapse/__tests__/demo.test.js b/components/collapse/__tests__/demo.test.ts similarity index 100% rename from components/collapse/__tests__/demo.test.js rename to components/collapse/__tests__/demo.test.ts diff --git a/components/collapse/__tests__/index.test.js b/components/collapse/__tests__/index.test.tsx similarity index 66% rename from components/collapse/__tests__/index.test.js rename to components/collapse/__tests__/index.test.tsx index f6eda414df..a054eca1ba 100644 --- a/components/collapse/__tests__/index.test.js +++ b/components/collapse/__tests__/index.test.tsx @@ -1,7 +1,6 @@ -import { mount } from 'enzyme'; import React from 'react'; import { act } from 'react-dom/test-utils'; -import { render, sleep } from '../../../tests/utils'; +import { sleep, render, fireEvent } from '../../../tests/utils'; import { resetWarned } from '../../_util/warning'; describe('Collapse', () => { @@ -10,6 +9,15 @@ describe('Collapse', () => { const errorSpy = jest.spyOn(console, 'error').mockImplementation(() => {}); + // fix React concurrent + function triggerAllTimer() { + for (let i = 0; i < 10; i += 1) { + act(() => { + jest.runAllTimers(); + }); + } + } + beforeEach(() => { resetWarned(); }); @@ -23,16 +31,16 @@ describe('Collapse', () => { }); it('should support remove expandIcon', () => { - const wrapper = mount( + const { asFragment } = render( null}> , ); - expect(wrapper.render()).toMatchSnapshot(); + expect(asFragment().firstChild).toMatchSnapshot(); }); it('should keep the className of the expandIcon', () => { - const wrapper = mount( + const { container } = render( ( } /> action} /> , ); - expect(wrapper.render()).toMatchSnapshot(); + expect(asFragment().firstChild).toMatchSnapshot(); }); it('could be expand and collapse', async () => { - const wrapper = mount( + const { container } = render( content , ); - expect(wrapper.find('.ant-collapse-item').hasClass('ant-collapse-item-active')).toBe(false); - wrapper.find('.ant-collapse-header').at(0).simulate('click'); - wrapper.update(); + expect( + container.querySelector('.ant-collapse-item')?.classList.contains('ant-collapse-item-active'), + ).toBe(false); + fireEvent.click(container.querySelector('.ant-collapse-header')!); await sleep(400); - wrapper.update(); - expect(wrapper.find('.ant-collapse-item').hasClass('ant-collapse-item-active')).toBe(true); + expect( + container.querySelector('.ant-collapse-item')?.classList.contains('ant-collapse-item-active'), + ).toBe(true); }); it('could override default openMotion', () => { - const wrapper = mount( + const { container, asFragment } = render( content , ); - wrapper.find('.ant-collapse-header').at(0).simulate('click'); - expect(wrapper.render()).toMatchSnapshot(); + fireEvent.click(container.querySelector('.ant-collapse-header')!); + expect(asFragment().firstChild).toMatchSnapshot(); }); it('should trigger warning and keep compatibility when using disabled in Panel', () => { - const wrapper = mount( + const { container } = render( content @@ -98,19 +108,19 @@ describe('Collapse', () => { 'Warning: [antd: Collapse.Panel] `disabled` is deprecated. Please use `collapsible="disabled"` instead.', ); - expect(wrapper.find('.ant-collapse-item-disabled').length).toBe(1); + expect(container.querySelectorAll('.ant-collapse-item-disabled').length).toBe(1); - wrapper.find('.ant-collapse-header').simulate('click'); - expect(wrapper.find('.ant-collapse-item-active').length).toBe(0); + fireEvent.click(container.querySelector('.ant-collapse-header')!); + expect(container.querySelectorAll('.ant-collapse-item-active').length).toBe(0); }); it('should end motion when set activeKey while hiding', async () => { jest.useFakeTimers(); - jest.spyOn(window, 'requestAnimationFrame').mockImplementation(cb => { - setTimeout(cb, 16.66); - }); + const spiedRAF = jest + .spyOn(window, 'requestAnimationFrame') + .mockImplementation(cb => setTimeout(cb, 16.66)); - let setActiveKeyOuter; + let setActiveKeyOuter: React.Dispatch>; const Test = () => { const [activeKey, setActiveKey] = React.useState(); setActiveKeyOuter = setActiveKey; @@ -125,17 +135,18 @@ describe('Collapse', () => { ); }; - const wrapper = mount(); + const { container } = render(); await act(async () => { setActiveKeyOuter('1'); await Promise.resolve(); - jest.runAllTimers(); }); - expect(wrapper.render().find('.ant-motion-collapse').length).toBe(0); + triggerAllTimer(); - window.requestAnimationFrame.mockRestore(); + expect(container.querySelectorAll('.ant-motion-collapse').length).toBe(0); + + spiedRAF.mockRestore(); jest.useRealTimers(); }); diff --git a/components/input-number/__tests__/index.test.js b/components/input-number/__tests__/index.test.js index 1cb4be61a2..77129eb17b 100644 --- a/components/input-number/__tests__/index.test.js +++ b/components/input-number/__tests__/index.test.js @@ -1,10 +1,10 @@ -import { ArrowDownOutlined, ArrowUpOutlined } from '@ant-design/icons'; -import { mount } from 'enzyme'; import React from 'react'; +import { ArrowDownOutlined, ArrowUpOutlined } from '@ant-design/icons'; import InputNumber from '..'; import focusTest from '../../../tests/shared/focusTest'; import mountTest from '../../../tests/shared/mountTest'; import rtlTest from '../../../tests/shared/rtlTest'; +import { fireEvent, render } from '../../../tests/utils'; describe('InputNumber', () => { focusTest(InputNumber, { refFocus: true }); @@ -14,32 +14,35 @@ describe('InputNumber', () => { // https://github.com/ant-design/ant-design/issues/13896 it('should return null when blur a empty input number', () => { const onChange = jest.fn(); - const wrapper = mount(); - wrapper.find('input').simulate('change', { target: { value: '' } }); + const { container } = render(); + fireEvent.change(container.querySelector('input'), { target: { value: '' } }); expect(onChange).toHaveBeenLastCalledWith(null); }); it('should call onStep when press up or down button', () => { const onStep = jest.fn(); - const wrapper = mount(); - wrapper.find('.ant-input-number-handler-up').simulate('mousedown'); + const { container } = render(); + fireEvent.mouseDown(container.querySelector('.ant-input-number-handler-up')); expect(onStep).toBeCalledTimes(1); expect(onStep).toHaveBeenLastCalledWith(2, { offset: 1, type: 'up' }); - wrapper.find('.ant-input-number-handler-down').simulate('mousedown'); + + fireEvent.mouseDown(container.querySelector('.ant-input-number-handler-down')); expect(onStep).toBeCalledTimes(2); expect(onStep).toHaveBeenLastCalledWith(1, { offset: 1, type: 'down' }); }); it('renders correctly when controls is boolean', () => { - expect(mount().render()).toMatchSnapshot(); + const { asFragment } = render(); + expect(asFragment().firstChild).toMatchSnapshot(); }); it('renders correctly when controls is {}', () => { - expect(mount().render()).toMatchSnapshot(); + const { asFragment } = render(); + expect(asFragment().firstChild).toMatchSnapshot(); }); it('renders correctly when controls has custom upIcon and downIcon', () => { - const wrapper = mount( + const { asFragment } = render( , @@ -47,11 +50,11 @@ describe('InputNumber', () => { }} />, ); - expect(wrapper.render()).toMatchSnapshot(); + expect(asFragment().firstChild).toMatchSnapshot(); }); it('should support className', () => { - const wrapper = mount( + const { container } = render( , @@ -59,11 +62,11 @@ describe('InputNumber', () => { }} />, ); - expect(wrapper.find('.anticon-arrow-up').getDOMNode().className.includes('my-class-name')).toBe( + expect(container.querySelector('.anticon-arrow-up')?.className.includes('my-class-name')).toBe( true, ); expect( - wrapper.find('.anticon-arrow-down').getDOMNode().className.includes('my-class-name'), + container.querySelector('.anticon-arrow-down')?.className.includes('my-class-name'), ).toBe(true); }); }); diff --git a/components/input-number/__tests__/prefix.test.js b/components/input-number/__tests__/prefix.test.js index 96f1b797aa..1f9bee8eef 100644 --- a/components/input-number/__tests__/prefix.test.js +++ b/components/input-number/__tests__/prefix.test.js @@ -1,25 +1,24 @@ -import { render } from '@testing-library/react'; -import { mount } from 'enzyme'; -import React from 'react'; +import React, { forwardRef } from 'react'; import InputNumber from '..'; import focusTest from '../../../tests/shared/focusTest'; +import { fireEvent, render } from '../../../tests/utils'; describe('prefix', () => { focusTest( - React.forwardRef((props, ref) => ), + forwardRef((props, ref) => ), { refFocus: true }, ); it('should support className when has prefix', () => { const { container } = render(); - expect(container.firstChild.className.includes('my-class-name')).toBe(true); + expect(container.firstChild?.className.includes('my-class-name')).toBe(true); expect(container.querySelector('input')?.className.includes('my-class-name')).toBe(false); }); it('should trigger focus when prefix is clicked', () => { - const wrapper = mount(123} />); + const { container } = render(123} />); - const mockFocus = jest.spyOn(wrapper.find('input').getDOMNode(), 'focus'); - wrapper.find('i').simulate('mouseUp'); + const mockFocus = jest.spyOn(container.querySelector('input'), 'focus'); + fireEvent.mouseUp(container.querySelector('i')); expect(mockFocus).toBeCalled(); }); }); diff --git a/components/input/Input.tsx b/components/input/Input.tsx index 3ffdb198c2..d3e90949eb 100644 --- a/components/input/Input.tsx +++ b/components/input/Input.tsx @@ -39,7 +39,7 @@ export function resolveOnChange; if (e.type === 'click') { // Clone a new target for event. @@ -63,7 +63,7 @@ export function resolveOnChange); + onChange(event); return; } @@ -75,10 +75,10 @@ export function resolveOnChange); + onChange(event); return; } - onChange(event as React.ChangeEvent); + onChange(event); } export function triggerFocus( diff --git a/components/menu/index.en-US.md b/components/menu/index.en-US.md index af44b41bab..b932c59c96 100644 --- a/components/menu/index.en-US.md +++ b/components/menu/index.en-US.md @@ -119,7 +119,7 @@ The legacy demo code for version `<4.20.0` could be found at [https://github.com #### SubMenuType | Param | Description | Type | Default value | Version | -| --- | --- | --- | --- | --- | +| --- | --- | --- | --- | --- | --- | | children | Sub-menus or sub-menu items | [ItemType\[\]](#ItemType) | - | | | disabled | Whether sub-menu is disabled | boolean | false | | | icon | Icon of sub menu | ReactNode | - | | @@ -166,3 +166,14 @@ const dividerItem = { ### Why will Menu's children be rendered twice? Menu collects structure info with [twice-render](https://github.com/react-component/menu/blob/f4684514096d6b7123339cbe72e7b0f68db0bce2/src/Menu.tsx#L543) to support HOC usage. Merging into one render may cause the logic to become much more complex. Contributions to help improve the collection logic are welcomed. + +### Why Menu do not responsive collapse in Flex layout? + +Menu will render fully item in flex layout and then collapse it. You need tell flex not consider Menu width to enable responsive ([online demo](https://codesandbox.io/s/ding-bu-dao-hang-antd-4-21-7-forked-5e3imy?file=/demo.js)): + +```jsx +
+
Some Content
+ +
+``` diff --git a/components/menu/index.zh-CN.md b/components/menu/index.zh-CN.md index 543767f944..f4f102156d 100644 --- a/components/menu/index.zh-CN.md +++ b/components/menu/index.zh-CN.md @@ -120,7 +120,7 @@ return ; #### SubMenuType | 参数 | 说明 | 类型 | 默认值 | 版本 | -| --- | --- | --- | --- | --- | +| --- | --- | --- | --- | --- | --- | | children | 子菜单的菜单项 | [ItemType\[\]](#ItemType) | - | | | disabled | 是否禁用 | boolean | false | | | icon | 菜单图标 | ReactNode | - | | @@ -167,3 +167,14 @@ const dividerItem = { ### 为何 Menu 的子元素会渲染两次? Menu 通过[二次渲染](https://github.com/react-component/menu/blob/f4684514096d6b7123339cbe72e7b0f68db0bce2/src/Menu.tsx#L543)收集嵌套结构信息以支持 HOC 的结构。合并成一个推导结构会使得逻辑变得十分复杂,欢迎 PR 以协助改进该设计。 + +### 在 Flex 布局中,Menu 没有按照预期响应式省略菜单? + +Menu 初始化时会先全部渲染,然后根据宽度裁剪内容。当处于 Flex 布局中,你需要告知其预期宽度为响应式宽度([在线 Demo](https://codesandbox.io/s/ding-bu-dao-hang-antd-4-21-7-forked-5e3imy?file=/demo.js)): + +```jsx +
+
Some Content
+ +
+``` diff --git a/components/modal/__tests__/confirm.test.js b/components/modal/__tests__/confirm.test.js index 32f48ffb79..ab33aa6c7c 100644 --- a/components/modal/__tests__/confirm.test.js +++ b/components/modal/__tests__/confirm.test.js @@ -305,7 +305,7 @@ describe('Modal.confirm triggers callbacks correctly', () => { }); describe('should not close modals when click confirm button when onOk has argument', () => { - ['info', 'success', 'warning', 'error'].forEach(type => { + ['confirm', 'info', 'success', 'warning', 'error'].forEach(type => { it(type, async () => { jest.useFakeTimers(); Modal[type]({ @@ -318,7 +318,7 @@ describe('Modal.confirm triggers callbacks correctly', () => { await sleep(); }); expect($$(`.ant-modal-confirm-${type}`)).toHaveLength(1); - $$('.ant-btn')[0].click(); + $$('.ant-btn-primary')[0].click(); await act(async () => { jest.runAllTimers(); @@ -674,4 +674,149 @@ describe('Modal.confirm triggers callbacks correctly', () => { const { width } = $$('.ant-modal-body')[0].style; expect(width).toBe('500px'); }); + + describe('the callback close should be a method when onCancel has a close parameter', () => { + ['confirm', 'info', 'success', 'warning', 'error'].forEach(type => { + it(`click the close icon to trigger ${type} onCancel`, async () => { + jest.useFakeTimers(); + const mock = jest.fn(); + + Modal[type]({ + closable: true, + onCancel: close => mock(close), + }); + + await act(async () => { + jest.runAllTimers(); + await sleep(); + }); + + expect($$(`.ant-modal-confirm-${type}`)).toHaveLength(1); + $$('.ant-modal-close')[0].click(); + + await act(async () => { + jest.runAllTimers(); + await sleep(); + }); + + expect($$(`.ant-modal-confirm-${type}`)).toHaveLength(0); + expect(mock).toBeCalledWith(expect.any(Function)); + + jest.useRealTimers(); + }); + }); + + ['confirm', 'info', 'success', 'warning', 'error'].forEach(type => { + it(`press ESC to trigger ${type} onCancel`, async () => { + jest.useFakeTimers(); + const mock = jest.fn(); + + Modal[type]({ + keyboard: true, + onCancel: close => mock(close), + }); + + jest.runAllTimers(); + await sleep(); + jest.runAllTimers(); + + expect($$(`.ant-modal-confirm-${type}`)).toHaveLength(1); + TestUtils.Simulate.keyDown($$('.ant-modal')[0], { + keyCode: KeyCode.ESC, + }); + + jest.runAllTimers(); + await sleep(0); + jest.runAllTimers(); + + expect($$(`.ant-modal-confirm-${type}`)).toHaveLength(0); + expect(mock).toBeCalledWith(expect.any(Function)); + + jest.useRealTimers(); + }); + }); + + ['confirm', 'info', 'success', 'warning', 'error'].forEach(type => { + it(`click the mask to trigger ${type} onCancel`, async () => { + jest.useFakeTimers(); + const mock = jest.fn(); + + Modal[type]({ + maskClosable: true, + onCancel: close => mock(close), + }); + + await act(async () => { + jest.runAllTimers(); + await sleep(); + }); + + expect($$('.ant-modal-mask')).toHaveLength(1); + expect($$(`.ant-modal-confirm-${type}`)).toHaveLength(1); + + $$('.ant-modal-wrap')[0].click(); + + await act(async () => { + jest.runAllTimers(); + await sleep(); + }); + + expect($$(`.ant-modal-confirm-${type}`)).toHaveLength(0); + expect(mock).toBeCalledWith(expect.any(Function)); + + jest.useRealTimers(); + }); + }); + }); + + it('confirm modal click Cancel button close callback is a function', async () => { + jest.useFakeTimers(); + const mock = jest.fn(); + + Modal.confirm({ + onCancel: close => mock(close), + }); + + await act(async () => { + jest.runAllTimers(); + await sleep(); + }); + + $$('.ant-modal-confirm-btns > .ant-btn')[0].click(); + + await act(async () => { + jest.runAllTimers(); + await sleep(); + }); + + expect(mock).toBeCalledWith(expect.any(Function)); + + jest.useRealTimers(); + }); + + it('close can close modal when onCancel has a close parameter', async () => { + jest.useFakeTimers(); + + Modal.confirm({ + onCancel: close => close(), + }); + + await act(async () => { + jest.runAllTimers(); + await sleep(); + }); + + expect($$('.ant-modal-confirm-confirm')).toHaveLength(1); + + $$('.ant-modal-confirm-btns > .ant-btn')[0].click(); + + await act(async () => { + jest.runAllTimers(); + await sleep(); + }); + + expect($$('.ant-modal-confirm-confirm')).toHaveLength(0); + + jest.useRealTimers(); + }); }); diff --git a/components/modal/__tests__/hook.test.tsx b/components/modal/__tests__/hook.test.tsx index 8282af809c..2cb7a43c7b 100644 --- a/components/modal/__tests__/hook.test.tsx +++ b/components/modal/__tests__/hook.test.tsx @@ -1,9 +1,11 @@ import CSSMotion from 'rc-motion'; import { genCSSMotion } from 'rc-motion/lib/CSSMotion'; +import KeyCode from 'rc-util/lib/KeyCode'; import React from 'react'; -import { act } from 'react-dom/test-utils'; +import TestUtils, { act } from 'react-dom/test-utils'; + import Modal from '..'; -import { fireEvent, render } from '../../../tests/utils'; +import { fireEvent, render, sleep } from '../../../tests/utils'; import Button from '../../button'; import ConfigProvider from '../../config-provider'; import Input from '../../input'; @@ -193,4 +195,110 @@ describe('Modal.hook', () => { fireEvent.click(container.querySelectorAll('.open-hook-modal-btn')[0]); expect(document.body.classList.contains('ant-modal-confirm-title')).toBeFalsy(); }); + + it('the callback close should be a method when onCancel has a close parameter', async () => { + jest.useFakeTimers(); + + const clear = async function clear() { + await act(async () => { + jest.runAllTimers(); + await sleep(); + }); + }; + + const mockFn = jest.fn(); + const Demo = () => { + const [modal, contextHolder] = Modal.useModal(); + + const openBrokenModal = React.useCallback(() => { + modal.confirm({ + closable: true, + keyboard: true, + maskClosable: true, + onCancel: close => mockFn(close), + }); + }, [modal]); + + return ( +
+ {contextHolder} +
+ Test hook modal +
+
+ ); + }; + + const { container } = render(); + + await clear(); + + expect(document.body.querySelectorAll('.ant-modal-confirm-confirm')).toHaveLength(0); + // First open + fireEvent.click(container.querySelectorAll('.open-hook-modal-btn')[0]); + await clear(); + + expect(document.body.querySelectorAll('.ant-modal-confirm-confirm')).toHaveLength(1); + // Click mask to close + fireEvent.click(document.body.querySelectorAll('.ant-modal-wrap')[0]); + + await clear(); + + expect(document.body.querySelectorAll('.ant-modal-confirm-confirm')).toHaveLength(0); + // Second open + fireEvent.click(container.querySelectorAll('.open-hook-modal-btn')[0]); + + await clear(); + + expect(document.body.querySelectorAll('.ant-modal-confirm-confirm')).toHaveLength(1); + // Press ESC to turn off + TestUtils.Simulate.keyDown(document.body.querySelectorAll('.ant-modal')[0], { + keyCode: KeyCode.ESC, + }); + + await clear(); + + expect(document.body.querySelectorAll('.ant-modal-confirm-confirm')).toHaveLength(0); + // Third open + fireEvent.click(container.querySelectorAll('.open-hook-modal-btn')[0]); + + await clear(); + + expect(document.body.querySelectorAll('.ant-modal-confirm-confirm')).toHaveLength(1); + // Click the close icon to close + fireEvent.click(document.body.querySelectorAll('.ant-modal-close')[0]); + + await clear(); + + expect(document.body.querySelectorAll('.ant-modal-confirm-confirm')).toHaveLength(0); + // Last open + fireEvent.click(container.querySelectorAll('.open-hook-modal-btn')[0]); + + await clear(); + + expect(document.body.querySelectorAll('.ant-modal-confirm-confirm')).toHaveLength(1); + + // Click the Cancel button to close (invalid) + fireEvent.click(document.body.querySelectorAll('.ant-modal-confirm-btns > .ant-btn')[0]); + + await clear(); + + expect(document.body.querySelectorAll('.ant-modal-confirm-confirm')).toHaveLength(1); + + mockFn.mockImplementation(close => close()); + + // Click the Cancel button to close (valid) + fireEvent.click(document.body.querySelectorAll('.ant-modal-confirm-btns > .ant-btn')[0]); + + await clear(); + + expect(document.body.querySelectorAll('.ant-modal-confirm-confirm')).toHaveLength(0); + + // Close called 5 times + expect(mockFn).toHaveBeenCalledTimes(5); + + expect(mockFn.mock.calls).toEqual(Array.from({ length: 5 }, () => [expect.any(Function)])); + + jest.useRealTimers(); + }); }); diff --git a/components/modal/confirm.tsx b/components/modal/confirm.tsx index 4301154dbc..bfa807ff94 100644 --- a/components/modal/confirm.tsx +++ b/components/modal/confirm.tsx @@ -34,7 +34,7 @@ export default function confirm(config: ModalFuncProps) { function destroy(...args: any[]) { const triggerCancel = args.some(param => param && param.triggerCancel); if (config.onCancel && triggerCancel) { - config.onCancel(...args); + config.onCancel(() => {}, ...args.slice(1)); } for (let i = 0; i < destroyFns.length; i++) { const fn = destroyFns[i]; diff --git a/components/modal/useModal/HookModal.tsx b/components/modal/useModal/HookModal.tsx index 6c19c3dcce..e911805ae7 100644 --- a/components/modal/useModal/HookModal.tsx +++ b/components/modal/useModal/HookModal.tsx @@ -36,7 +36,7 @@ const HookModal: React.ForwardRefRenderFunction = setVisible(false); const triggerCancel = args.some(param => param && param.triggerCancel); if (innerConfig.onCancel && triggerCancel) { - innerConfig.onCancel(); + innerConfig.onCancel(() => {}, ...args.slice(1)); } }; diff --git a/components/radio/__tests__/__snapshots__/group.test.js.snap b/components/radio/__tests__/__snapshots__/group.test.js.snap index c61feab1e3..90418e5ce9 100644 --- a/components/radio/__tests__/__snapshots__/group.test.js.snap +++ b/components/radio/__tests__/__snapshots__/group.test.js.snap @@ -25,7 +25,7 @@ exports[`Radio Group passes prefixCls down to radio 1`] = `