diff --git a/packages/components/src/toggle-group-control/test/index.tsx b/packages/components/src/toggle-group-control/test/index.tsx index b6f2d9a5be49dc..e05910245e2dca 100644 --- a/packages/components/src/toggle-group-control/test/index.tsx +++ b/packages/components/src/toggle-group-control/test/index.tsx @@ -2,6 +2,7 @@ * External dependencies */ import { render, fireEvent, screen } from '@testing-library/react'; +import userEvent from '@testing-library/user-event'; /** * WordPress dependencies @@ -126,4 +127,130 @@ describe( 'ToggleGroupControl', () => { screen.queryByText( 'Click for Sumptuous Caponata' ) ).not.toBeInTheDocument(); } ); + + describe( 'isDeselectable', () => { + describe( 'isDeselectable = false', () => { + it( 'should not be deselectable', async () => { + const mockOnChange = jest.fn(); + const user = userEvent.setup( { + advanceTimers: jest.advanceTimersByTime, + } ); + + render( + + { options } + + ); + + const rigas = screen.getByRole( 'radio', { + name: 'R', + checked: true, + } ); + await user.click( rigas ); + expect( mockOnChange ).toHaveBeenCalledTimes( 0 ); + } ); + + it( 'should not tab to next radio option', async () => { + const user = userEvent.setup( { + advanceTimers: jest.advanceTimersByTime, + } ); + + render( + + { options } + + ); + + const rigas = screen.getByRole( 'radio', { + name: 'R', + } ); + + await user.tab(); + expect( rigas ).toHaveFocus(); + + await user.tab(); + expect( rigas.ownerDocument.body ).toHaveFocus(); + } ); + } ); + + describe( 'isDeselectable = true', () => { + it( 'should be deselectable', async () => { + const mockOnChange = jest.fn(); + const user = userEvent.setup( { + advanceTimers: jest.advanceTimersByTime, + } ); + + render( + + { options } + + ); + + await user.click( + await screen.findByRole( 'button', { + name: 'R', + pressed: true, + } ) + ); + expect( mockOnChange ).toHaveBeenCalledTimes( 1 ); + expect( mockOnChange ).toHaveBeenCalledWith( undefined ); + expect( + screen.getByRole( 'button', { + name: 'R', + pressed: false, + } ) + ).toBeInTheDocument(); + } ); + + it( 'should tab to the next option button', async () => { + const user = userEvent.setup( { + advanceTimers: jest.advanceTimersByTime, + } ); + + render( + + { options } + + ); + + await user.tab(); + expect( + screen.getByRole( 'button', { + name: 'R', + pressed: true, + } ) + ).toHaveFocus(); + + await user.tab(); + expect( + screen.getByRole( 'button', { + name: 'J', + pressed: false, + } ) + ).toHaveFocus(); + + // Focus should not move with arrow keys + await user.keyboard( '{ArrowLeft}' ); + expect( + screen.getByRole( 'button', { + name: 'J', + pressed: false, + } ) + ).toHaveFocus(); + } ); + } ); + } ); } ); diff --git a/packages/components/src/toggle-group-control/toggle-group-control-option-base/component.tsx b/packages/components/src/toggle-group-control/toggle-group-control-option-base/component.tsx index ac40cadd7dac69..e1d90fc1085a29 100644 --- a/packages/components/src/toggle-group-control/toggle-group-control-option-base/component.tsx +++ b/packages/components/src/toggle-group-control/toggle-group-control-option-base/component.tsx @@ -97,6 +97,7 @@ function ToggleGroupControlOptionBase( { isDeselectable ? (