Skip to content

Commit

Permalink
Focus Editor Region from Template Footer Click (#62595)
Browse files Browse the repository at this point in the history
  • Loading branch information
jeryj authored Jun 26, 2024
1 parent cea3b8d commit 2139bc2
Show file tree
Hide file tree
Showing 3 changed files with 49 additions and 28 deletions.
17 changes: 16 additions & 1 deletion packages/block-editor/src/components/block-breadcrumb/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ import { chevronRightSmall, Icon } from '@wordpress/icons';
import BlockTitle from '../block-title';
import { store as blockEditorStore } from '../../store';
import { unlock } from '../../lock-unlock';
import { __unstableUseBlockRef as useBlockRef } from '../block-list/use-block-props/use-block-refs';
import getEditorRegion from '../../utils/get-editor-region';

/**
* Block breadcrumb component, displaying the hierarchy of the current block selection as a breadcrumb.
Expand All @@ -37,6 +39,10 @@ function BlockBreadcrumb( { rootLabelText } ) {
}, [] );
const rootLabel = rootLabelText || __( 'Document' );

// We don't care about this specific ref, but this is a way
// to get a ref within the editor canvas so we can focus it later.
const blockRef = useBlockRef( clientId );

/*
* Disable reason: The `list` ARIA role is redundant but
* Safari+VoiceOver won't announce the list otherwise.
Expand All @@ -60,7 +66,16 @@ function BlockBreadcrumb( { rootLabelText } ) {
<Button
className="block-editor-block-breadcrumb__button"
variant="tertiary"
onClick={ clearSelectedBlock }
onClick={ () => {
// Find the block editor wrapper for the selected block
const blockEditor = blockRef.current?.closest(
'.editor-styles-wrapper'
);

clearSelectedBlock();

getEditorRegion( blockEditor ).focus();
} }
>
{ rootLabel }
</Button>
Expand Down
29 changes: 2 additions & 27 deletions packages/block-editor/src/components/block-tools/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import usePopoverScroll from '../block-popover/use-popover-scroll';
import ZoomOutModeInserters from './zoom-out-mode-inserters';
import { useShowBlockTools } from './use-show-block-tools';
import { unlock } from '../../lock-unlock';
import getEditorRegion from '../../utils/get-editor-region';

function selector( select ) {
const {
Expand Down Expand Up @@ -161,33 +162,7 @@ export default function BlockTools( {
) {
event.preventDefault();
clearSelectedBlock();
// If there are multiple editors, we need to find the iframe that contains our contentRef to make sure
// we're focusing the region that contains this editor.
const editorCanvas =
Array.from(
document
.querySelectorAll( 'iframe[name="editor-canvas"]' )
.values()
).find( ( iframe ) => {
// Find the iframe that contains our contentRef
const iframeDocument =
iframe.contentDocument ||
iframe.contentWindow.document;

return (
iframeDocument ===
__unstableContentRef.current.ownerDocument
);
} ) ?? __unstableContentRef.current;

// The region is provivided by the editor, not the block-editor.
// We should send focus to the region if one is available to reuse the
// same interface for navigating landmarks. If no region is available,
// use the canvas instead.
const focusableWrapper =
editorCanvas?.closest( '[role="region"]' ) ?? editorCanvas;

focusableWrapper.focus();
getEditorRegion( __unstableContentRef.current ).focus();
}
} else if ( isMatch( 'core/block-editor/collapse-list-view', event ) ) {
// If focus is currently within a text field, such as a rich text block or other editable field,
Expand Down
31 changes: 31 additions & 0 deletions packages/block-editor/src/utils/get-editor-region.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
/**
* Gets the editor region for a given editor canvas element or
* returns the passed element if no region is found
*
* @param { Object } editor The editor canvas element.
* @return { Object } The editor region or given editor element
*/
export default function getEditorRegion( editor ) {
if ( ! editor ) {
return null;
}

// If there are multiple editors, we need to find the iframe that contains our contentRef to make sure
// we're focusing the region that contains this editor.
const editorCanvas =
Array.from(
document.querySelectorAll( 'iframe[name="editor-canvas"]' ).values()
).find( ( iframe ) => {
// Find the iframe that contains our contentRef
const iframeDocument =
iframe.contentDocument || iframe.contentWindow.document;

return iframeDocument === editor.ownerDocument;
} ) ?? editor;

// The region is provivided by the editor, not the block-editor.
// We should send focus to the region if one is available to reuse the
// same interface for navigating landmarks. If no region is available,
// use the canvas instead.
return editorCanvas?.closest( '[role="region"]' ) ?? editorCanvas;
}

0 comments on commit 2139bc2

Please sign in to comment.