diff --git a/packages/components/CHANGELOG.md b/packages/components/CHANGELOG.md index 285f861cc3b73..3881fea0860ff 100644 --- a/packages/components/CHANGELOG.md +++ b/packages/components/CHANGELOG.md @@ -13,6 +13,7 @@ ### Bug Fix - `Button`: Fix RTL alignment for buttons containing an icon and text ([#44787](https://github.com/WordPress/gutenberg/pull/44787)). +- `TabPanel`: Call `onSelect()` on every tab selection, regardless of whether it was triggered by user interaction ([#44028](https://github.com/WordPress/gutenberg/pull/44028)). - `FontSizePicker`: Fallback to font size `slug` if `name` is undefined ([#45041](https://github.com/WordPress/gutenberg/pull/45041)). ### Internal diff --git a/packages/components/src/tab-panel/test/index.tsx b/packages/components/src/tab-panel/test/index.tsx index 3b8f7aacc265c..ce096cac6bcb5 100644 --- a/packages/components/src/tab-panel/test/index.tsx +++ b/packages/components/src/tab-panel/test/index.tsx @@ -38,14 +38,22 @@ describe( 'TabPanel', () => { it( 'should render a tabpanel, and clicking should change tabs', async () => { const user = setupUser(); const panelRenderFunction = jest.fn(); + const mockOnSelect = jest.fn(); - render( ); + render( + + ); expect( getSelectedTab() ).toHaveTextContent( 'Alpha' ); expect( screen.getByRole( 'tabpanel', { name: 'Alpha' } ) ).toBeInTheDocument(); expect( panelRenderFunction ).toHaveBeenLastCalledWith( TABS[ 0 ] ); + expect( mockOnSelect ).toHaveBeenLastCalledWith( 'alpha' ); await user.click( screen.getByRole( 'tab', { name: 'Beta' } ) ); @@ -54,6 +62,7 @@ describe( 'TabPanel', () => { screen.getByRole( 'tabpanel', { name: 'Beta' } ) ).toBeInTheDocument(); expect( panelRenderFunction ).toHaveBeenLastCalledWith( TABS[ 1 ] ); + expect( mockOnSelect ).toHaveBeenLastCalledWith( 'beta' ); await user.click( screen.getByRole( 'tab', { name: 'Alpha' } ) ); @@ -62,6 +71,7 @@ describe( 'TabPanel', () => { screen.getByRole( 'tabpanel', { name: 'Alpha' } ) ).toBeInTheDocument(); expect( panelRenderFunction ).toHaveBeenLastCalledWith( TABS[ 0 ] ); + expect( mockOnSelect ).toHaveBeenLastCalledWith( 'alpha' ); } ); it( 'should render with a tab initially selected by prop initialTabIndex', () => { @@ -117,4 +127,71 @@ describe( 'TabPanel', () => { 'gamma-class' ); } ); + + it( 'should select `initialTabname` if defined', () => { + const mockOnSelect = jest.fn(); + + render( + undefined } + onSelect={ mockOnSelect } + /> + ); + expect( getSelectedTab() ).toHaveTextContent( 'Beta' ); + expect( mockOnSelect ).toHaveBeenLastCalledWith( 'beta' ); + } ); + + describe( 'fallbacks when new tab list invalidates current selection', () => { + it( 'should select `initialTabName` if defined', async () => { + const user = setupUser(); + const mockOnSelect = jest.fn(); + + const { rerender } = render( + undefined } + onSelect={ mockOnSelect } + /> + ); + await user.click( screen.getByRole( 'tab', { name: 'Alpha' } ) ); + + rerender( + undefined } + onSelect={ mockOnSelect } + /> + ); + expect( getSelectedTab() ).toHaveTextContent( 'Gamma' ); + expect( mockOnSelect ).toHaveBeenLastCalledWith( 'gamma' ); + } ); + + it( 'should select first tab if `initialTabName` not defined', async () => { + const user = setupUser(); + const mockOnSelect = jest.fn(); + + const { rerender } = render( + undefined } + onSelect={ mockOnSelect } + /> + ); + await user.click( screen.getByRole( 'tab', { name: 'Alpha' } ) ); + + rerender( + undefined } + onSelect={ mockOnSelect } + /> + ); + expect( getSelectedTab() ).toHaveTextContent( 'Beta' ); + expect( mockOnSelect ).toHaveBeenLastCalledWith( 'beta' ); + } ); + } ); } );