Skip to content

Commit

Permalink
Don't steal focus when opening browse all blocks from navigation link…
Browse files Browse the repository at this point in the history
… popover (#61975)

When using the browse all blocks button from adding a new navigation link block, the inserter would steal focus from the popover (correctly) and then the popover would close, stealing focus back. To prevent this bug, we check to see if focus is still within the popover at the time of closing. If focus is no longer within it, we don't move focus back to the selected block and instead let whatever stole focus keep the focus.
  • Loading branch information
jeryj committed May 31, 2024
1 parent fd456db commit 3031559
Show file tree
Hide file tree
Showing 2 changed files with 21 additions and 3 deletions.
18 changes: 16 additions & 2 deletions packages/block-library/src/navigation-link/edit.js
Original file line number Diff line number Diff line change
Expand Up @@ -261,6 +261,7 @@ export default function NavigationLinkEdit( {
const isDraggingWithin = useIsDraggingWithin( listItemRef );
const itemLabelPlaceholder = __( 'Add label…' );
const ref = useRef();
const linkUIref = useRef();
const prevUrl = usePrevious( url );

// Change the label using inspector causes rich text to change focus on firefox.
Expand Down Expand Up @@ -570,14 +571,27 @@ export default function NavigationLinkEdit( {
) }
{ isLinkOpen && (
<LinkUI
ref={ linkUIref }
clientId={ clientId }
link={ attributes }
onClose={ () => {
// If there is no link then remove the auto-inserted block.
// This avoids empty blocks which can provided a poor UX.
if ( ! url ) {
// Select the previous block to keep focus nearby
selectPreviousBlock( clientId, true );
// Fixes https://github.com/WordPress/gutenberg/issues/61361
// There's a chance we're closing due to the user selecting the browse all button.
// Only move focus if the focus is still within the popover ui. If it's not within
// the popover, it's because something has taken the focus from the popover, and
// we don't want to steal it back.
if (
linkUIref.current.contains(
window.document.activeElement
)
) {
// Select the previous block to keep focus nearby
selectPreviousBlock( clientId, true );
}

// Remove the link.
onReplace( [] );
return;
Expand Down
6 changes: 5 additions & 1 deletion packages/block-library/src/navigation-link/link-ui.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import {
useState,
useRef,
useEffect,
forwardRef,
} from '@wordpress/element';
import {
store as coreStore,
Expand Down Expand Up @@ -145,7 +146,7 @@ function LinkUIBlockInserter( { clientId, onBack, onSelectBlock } ) {
);
}

export function LinkUI( props ) {
function UnforwardedLinkUI( props, ref ) {
const [ addingBlock, setAddingBlock ] = useState( false );
const [ focusAddBlockButton, setFocusAddBlockButton ] = useState( false );
const { saveEntityRecord } = useDispatch( coreStore );
Expand Down Expand Up @@ -214,6 +215,7 @@ export function LinkUI( props ) {

return (
<Popover
ref={ ref }
placement="bottom"
onClose={ props.onClose }
anchor={ props.anchor }
Expand Down Expand Up @@ -298,6 +300,8 @@ export function LinkUI( props ) {
);
}

export const LinkUI = forwardRef( UnforwardedLinkUI );

const LinkUITools = ( { setAddingBlock, focusAddBlockButton } ) => {
const blockInserterAriaRole = 'listbox';
const addBlockButtonRef = useRef();
Expand Down

0 comments on commit 3031559

Please sign in to comment.