From e1b487c3fccc2513b18a6d93681d2871fc10cad0 Mon Sep 17 00:00:00 2001 From: Aki Hamano Date: Sat, 21 Dec 2024 17:20:13 +0900 Subject: [PATCH] Widget Editor: Focus toggle button when the global inserter is closed --- .../secondary-sidebar/inserter-sidebar.js | 26 ++++++++++++++++--- .../e2e/specs/widgets/editing-widgets.spec.js | 19 ++++++++++++++ 2 files changed, 42 insertions(+), 3 deletions(-) diff --git a/packages/edit-widgets/src/components/secondary-sidebar/inserter-sidebar.js b/packages/edit-widgets/src/components/secondary-sidebar/inserter-sidebar.js index 72e04e5f62034c..338a24cd27adb3 100644 --- a/packages/edit-widgets/src/components/secondary-sidebar/inserter-sidebar.js +++ b/packages/edit-widgets/src/components/secondary-sidebar/inserter-sidebar.js @@ -7,27 +7,47 @@ import { __experimentalUseDialog as useDialog, } from '@wordpress/compose'; import { useCallback, useRef } from '@wordpress/element'; -import { useDispatch } from '@wordpress/data'; +import { useSelect, useDispatch } from '@wordpress/data'; +import { ESCAPE } from '@wordpress/keycodes'; /** * Internal dependencies */ import useWidgetLibraryInsertionPoint from '../../hooks/use-widget-library-insertion-point'; import { store as editWidgetsStore } from '../../store'; +import { unlock } from '../../lock-unlock'; export default function InserterSidebar() { const isMobileViewport = useViewportMatch( 'medium', '<' ); const { rootClientId, insertionIndex } = useWidgetLibraryInsertionPoint(); + const inserterSidebarToggleRef = useSelect( ( select ) => { + return unlock( + select( editWidgetsStore ) + ).getInserterSidebarToggleRef(); + }, [] ); + const { setIsInserterOpened } = useDispatch( editWidgetsStore ); const closeInserter = useCallback( () => { - return setIsInserterOpened( false ); - }, [ setIsInserterOpened ] ); + setIsInserterOpened( false ); + inserterSidebarToggleRef.current?.focus(); + }, [ setIsInserterOpened, inserterSidebarToggleRef ] ); + + const closeOnEscape = useCallback( + ( event ) => { + if ( event.keyCode === ESCAPE && ! event.defaultPrevented ) { + event.preventDefault(); + closeInserter(); + } + }, + [ closeInserter ] + ); const [ inserterDialogRef, inserterDialogProps ] = useDialog( { onClose: closeInserter, focusOnMount: true, + onKeyDown: closeOnEscape, } ); const libraryRef = useRef(); diff --git a/test/e2e/specs/widgets/editing-widgets.spec.js b/test/e2e/specs/widgets/editing-widgets.spec.js index 019e07fe87daac..db44961348adf6 100644 --- a/test/e2e/specs/widgets/editing-widgets.spec.js +++ b/test/e2e/specs/widgets/editing-widgets.spec.js @@ -145,6 +145,25 @@ test.describe( 'Widgets screen', () => { } ); } ); + test( 'Should focus the global inserter toggle when the global inserter is closed', async ( { + page, + } ) => { + const blockInserterToggle = page + .getByRole( 'toolbar', { name: 'Document tools' } ) + .getByRole( 'button', { name: 'Block Inserter', exact: true } ); + await blockInserterToggle.click(); + await page + .getByRole( 'button', { name: 'Close Block Inserter' } ) + .click(); + + await expect( blockInserterToggle ).toBeFocused(); + + await blockInserterToggle.click(); + await page.keyboard.press( 'Escape' ); + + await expect( blockInserterToggle ).toBeFocused(); + } ); + test( 'Should insert content using the inline inserter', async ( { page, widgetsScreen,