From 06bd2662c8fafacfbd6832aa6017b91915375445 Mon Sep 17 00:00:00 2001 From: Jerry Jones Date: Fri, 31 Jan 2020 15:03:27 -0800 Subject: [PATCH] Navigation: Change UX to move focus to navigation link label and close the LinkControl (#19686) * When adding a link via the LinkControl, selects/highlights nav link label text if it's url-like. Focuses if not. Automatically adds url-like labels as the label. * Adds @wordpress/dom to package-lock.json * Removed test for awaiting for Link Control focus after pressing Enter, as the focus should now be on the navigation link text with the Link Control closed --- package-lock.json | 2 + packages/block-library/package.json | 2 + .../block-library/src/navigation-link/edit.js | 55 ++++++++++++++++++- .../specs/editor/blocks/navigation.test.js | 28 +++++----- 4 files changed, 69 insertions(+), 18 deletions(-) diff --git a/package-lock.json b/package-lock.json index d4562580e2b47..1d5a493bf8e4e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10115,6 +10115,8 @@ "@wordpress/data": "file:packages/data", "@wordpress/date": "file:packages/date", "@wordpress/deprecated": "file:packages/deprecated", + "@wordpress/dom": "file:packages/dom", + "@wordpress/editor": "file:packages/editor", "@wordpress/element": "file:packages/element", "@wordpress/escape-html": "file:packages/escape-html", "@wordpress/i18n": "file:packages/i18n", diff --git a/packages/block-library/package.json b/packages/block-library/package.json index fe1bb28e1f96e..1a99a38df771f 100644 --- a/packages/block-library/package.json +++ b/packages/block-library/package.json @@ -37,6 +37,8 @@ "@wordpress/data": "file:../data", "@wordpress/date": "file:../date", "@wordpress/deprecated": "file:../deprecated", + "@wordpress/dom": "file:../dom", + "@wordpress/editor": "file:../editor", "@wordpress/element": "file:../element", "@wordpress/escape-html": "file:../escape-html", "@wordpress/i18n": "file:../i18n", diff --git a/packages/block-library/src/navigation-link/edit.js b/packages/block-library/src/navigation-link/edit.js index d953ca8efeada..ff55c5dabfecd 100644 --- a/packages/block-library/src/navigation-link/edit.js +++ b/packages/block-library/src/navigation-link/edit.js @@ -30,8 +30,9 @@ import { RichText, __experimentalLinkControl as LinkControl, } from '@wordpress/block-editor'; -import { Fragment, useState, useEffect } from '@wordpress/element'; - +import { isURL, prependHTTP } from '@wordpress/url'; +import { Fragment, useState, useEffect, useRef } from '@wordpress/element'; +import { placeCaretAtHorizontalEdge } from '@wordpress/dom'; /** * Internal dependencies */ @@ -61,6 +62,7 @@ function NavigationLinkEdit( { }; const [ isLinkOpen, setIsLinkOpen ] = useState( false ); const itemLabelPlaceholder = __( 'Add linkā€¦' ); + const ref = useRef(); // Show the LinkControl on mount if the URL is empty // ( When adding a new menu item) @@ -72,6 +74,49 @@ function NavigationLinkEdit( { } }, [] ); + /** + * The hook shouldn't be necessary but due to a focus loss happening + * when selecting a suggestion in the link popover, we force close on block unselection. + */ + useEffect( () => { + if ( ! isSelected ) { + setIsLinkOpen( false ); + } + }, [ isSelected ] ); + + // If the LinkControl popover is open and the URL has changed, close the LinkControl and focus the label text. + useEffect( () => { + if ( isLinkOpen && url ) { + // Close the link. + setIsLinkOpen( false ); + + // Does this look like a URL and have something TLD-ish? + if ( + isURL( prependHTTP( label ) ) && + /^.+\.[a-z]+/.test( label ) + ) { + // Focus and select the label text. + selectLabelText(); + } else { + // Focus it (but do not select). + placeCaretAtHorizontalEdge( ref.current, true ); + } + } + }, [ url ] ); + + /** + * Focus the navigation link label text and select it. + */ + function selectLabelText() { + ref.current.focus(); + const selection = window.getSelection(); + const range = document.createRange(); + // Get the range of the current ref contents so we can add this range to the selection. + range.selectNodeContents( ref.current ); + selection.removeAllRanges(); + selection.addRange( range ); + } + return ( @@ -155,6 +200,7 @@ function NavigationLinkEdit( { >