From 8e110d5a5fa163bb727f2b27a4bcbcfc29e1506b Mon Sep 17 00:00:00 2001 From: Vincenzo Scamporlino Date: Thu, 23 Nov 2023 20:59:37 +0100 Subject: [PATCH 1/3] core-components: invoke onChange only on focus Signed-off-by: Vincenzo Scamporlino --- .../src/layout/HeaderTabs/HeaderTabs.test.tsx | 12 ++++++++++++ .../src/layout/HeaderTabs/HeaderTabs.tsx | 7 +++++-- 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/packages/core-components/src/layout/HeaderTabs/HeaderTabs.test.tsx b/packages/core-components/src/layout/HeaderTabs/HeaderTabs.test.tsx index f656696f8a..5aec83bc2b 100644 --- a/packages/core-components/src/layout/HeaderTabs/HeaderTabs.test.tsx +++ b/packages/core-components/src/layout/HeaderTabs/HeaderTabs.test.tsx @@ -83,4 +83,16 @@ describe('', () => { expect(rendered.getByText('Alarms')).toBeInTheDocument(); expect(rendered.getByText('three new alarms')).toBeInTheDocument(); }); + + it('should trigger onChange only once', async () => { + const mockOnChange = jest.fn(); + const user = userEvent.setup(); + + const rendered = await renderInTestApp( + , + ); + + await user.click(rendered.getByText('Docs')); + expect(mockOnChange).toHaveBeenCalledTimes(1); + }); }); diff --git a/packages/core-components/src/layout/HeaderTabs/HeaderTabs.tsx b/packages/core-components/src/layout/HeaderTabs/HeaderTabs.tsx index 704df67374..59a40001ee 100644 --- a/packages/core-components/src/layout/HeaderTabs/HeaderTabs.tsx +++ b/packages/core-components/src/layout/HeaderTabs/HeaderTabs.tsx @@ -81,11 +81,14 @@ export function HeaderTabs(props: HeaderTabsProps) { const styles = useStyles(); const handleChange = useCallback( - (_: React.ChangeEvent<{}>, index: number) => { + (e: React.ChangeEvent<{}>, index: number) => { if (selectedIndex === undefined) { setSelectedTab(index); } - if (onChange) onChange(index); + + if (e.type === 'focus') { + onChange?.(index); + } }, [selectedIndex, onChange], ); From 175d86b63b7fb1726daa669b39896a15276bc32f Mon Sep 17 00:00:00 2001 From: Vincenzo Scamporlino Date: Thu, 23 Nov 2023 21:02:32 +0100 Subject: [PATCH 2/3] HeaderTabs changeset Signed-off-by: Vincenzo Scamporlino --- .changeset/short-buttons-cover.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/short-buttons-cover.md diff --git a/.changeset/short-buttons-cover.md b/.changeset/short-buttons-cover.md new file mode 100644 index 0000000000..2d98e212f7 --- /dev/null +++ b/.changeset/short-buttons-cover.md @@ -0,0 +1,5 @@ +--- +'@backstage/core-components': patch +--- + +Fixed an issue where the `onChange` prop within `HeaderTabs` was triggering twice upon tab-switching. From 69919a82abf6b6f058740e5483baba3fcddf9856 Mon Sep 17 00:00:00 2001 From: Philipp Hugenroth Date: Wed, 6 Dec 2023 15:27:00 +0100 Subject: [PATCH 3/3] Remove flag from Signed-off-by: Philipp Hugenroth --- .../src/layout/HeaderTabs/HeaderTabs.tsx | 8 ++----- .../src/layout/TabbedCard/TabbedCard.test.tsx | 22 +++++++++++++++++++ .../src/layout/TabbedCard/TabbedCard.tsx | 1 - 3 files changed, 24 insertions(+), 7 deletions(-) diff --git a/packages/core-components/src/layout/HeaderTabs/HeaderTabs.tsx b/packages/core-components/src/layout/HeaderTabs/HeaderTabs.tsx index 59a40001ee..799eab1eb5 100644 --- a/packages/core-components/src/layout/HeaderTabs/HeaderTabs.tsx +++ b/packages/core-components/src/layout/HeaderTabs/HeaderTabs.tsx @@ -81,14 +81,11 @@ export function HeaderTabs(props: HeaderTabsProps) { const styles = useStyles(); const handleChange = useCallback( - (e: React.ChangeEvent<{}>, index: number) => { + (_: React.ChangeEvent<{}>, index: number) => { if (selectedIndex === undefined) { setSelectedTab(index); } - - if (e.type === 'focus') { - onChange?.(index); - } + if (onChange) onChange(index); }, [selectedIndex, onChange], ); @@ -102,7 +99,6 @@ export function HeaderTabs(props: HeaderTabsProps) { return ( ', () => { ); expect(screen.getByText('Test Content 2')).toBeInTheDocument(); }); + + it('should trigger onChange only once', async () => { + const mockOnChange = jest.fn(); + const user = userEvent.setup(); + + const rendered = render( + wrapInTestApp( + + + Test Content 1 + + + Test Content 2 + + , + ), + ); + + await user.click(rendered.getByText('Test 2')); + expect(mockOnChange).toHaveBeenCalledTimes(1); + }); }); diff --git a/packages/core-components/src/layout/TabbedCard/TabbedCard.tsx b/packages/core-components/src/layout/TabbedCard/TabbedCard.tsx index 4e75878a7d..088e54c1f3 100644 --- a/packages/core-components/src/layout/TabbedCard/TabbedCard.tsx +++ b/packages/core-components/src/layout/TabbedCard/TabbedCard.tsx @@ -114,7 +114,6 @@ export function TabbedCard(props: PropsWithChildren) { {title && }