From 4b186714d0491af7c6c9bc53ec046d65cca2f549 Mon Sep 17 00:00:00 2001 From: zyf <81416635+Zyf665@users.noreply.github.com> Date: Mon, 18 Nov 2024 11:31:38 +0800 Subject: [PATCH] fix(Table): preserve custom event handlers in row selection (#51661) --- .../__tests__/Table.rowSelection.test.tsx | 72 +++++++++++++++++++ components/table/hooks/useSelection.tsx | 19 +++-- 2 files changed, 86 insertions(+), 5 deletions(-) diff --git a/components/table/__tests__/Table.rowSelection.test.tsx b/components/table/__tests__/Table.rowSelection.test.tsx index 4f86b15b10..4ba6f2c8b3 100644 --- a/components/table/__tests__/Table.rowSelection.test.tsx +++ b/components/table/__tests__/Table.rowSelection.test.tsx @@ -1905,4 +1905,76 @@ describe('Table.rowSelection', () => { ); }); }); + + it('should trigger both custom and internal checkbox events', () => { + const onClickMock = jest.fn(); + const onChangeMock = jest.fn(); + + const getCheckboxProps = () => ({ + onClick: onClickMock, + onChange: onChangeMock, + }); + + const { container } = render( + , + ); + + const firstRowCheckbox = container.querySelector('tbody tr:first-child input[type="checkbox"]'); + expect(firstRowCheckbox).toBeTruthy(); + + fireEvent.click(firstRowCheckbox!); + + expect(onClickMock).toHaveBeenCalled(); + expect(onClickMock.mock.calls.length).toBe(1); + + expect(onChangeMock).toHaveBeenCalled(); + expect(onChangeMock.mock.calls.length).toBe(1); + + const changeEvent = onChangeMock.mock.calls[0][0]; + expect(changeEvent).toHaveProperty('target'); + expect(changeEvent.target).toHaveProperty('checked'); + }); + + it('should trigger both custom and internal radio events', () => { + const onClickMock = jest.fn(); + const onChangeMock = jest.fn(); + + const getCheckboxProps = () => ({ + onClick: onClickMock, + onChange: onChangeMock, + }); + + const { container } = render( +
, + ); + + const firstRowRadio = container.querySelector('tbody tr:first-child input[type="radio"]'); + expect(firstRowRadio).toBeTruthy(); + + fireEvent.click(firstRowRadio!); + + expect(onClickMock).toHaveBeenCalled(); + expect(onClickMock.mock.calls.length).toBe(1); + + expect(onChangeMock).toHaveBeenCalled(); + expect(onChangeMock.mock.calls.length).toBe(1); + + const changeEvent = onChangeMock.mock.calls[0][0]; + expect(changeEvent).toHaveProperty('target'); + expect(changeEvent.target).toHaveProperty('checked'); + }); }); diff --git a/components/table/hooks/useSelection.tsx b/components/table/hooks/useSelection.tsx index 8cf525fe47..0d7f77285c 100644 --- a/components/table/hooks/useSelection.tsx +++ b/components/table/hooks/useSelection.tsx @@ -496,17 +496,21 @@ const useSelection = ( renderCell = (_, record, index) => { const key = getRowKey(record, index); const checked = keySet.has(key); - + const checkboxProps = checkboxPropsMap.get(key); return { node: ( e.stopPropagation()} + onClick={(e) => { + e.stopPropagation(); + checkboxProps?.onClick?.(e); + }} onChange={(event) => { if (!keySet.has(key)) { triggerSingleSelection(key, true, [key], event.nativeEvent); } + checkboxProps?.onChange?.(event); }} /> ), @@ -538,8 +542,12 @@ const useSelection = ( indeterminate={mergedIndeterminate} checked={checked} skipGroup - onClick={(e) => e.stopPropagation()} - onChange={({ nativeEvent }) => { + onClick={(e) => { + e.stopPropagation(); + checkboxProps?.onClick?.(e); + }} + onChange={(event) => { + const { nativeEvent } = event; const { shiftKey } = nativeEvent; const currentSelectedIndex = recordKeys.findIndex((item) => item === key); const isMultiple = derivedSelectedKeys.some((item) => recordKeys.includes(item)); @@ -595,6 +603,7 @@ const useSelection = ( } else { updatePrevSelectedIndex(currentSelectedIndex); } + checkboxProps?.onChange?.(event); }} /> ),